오늘은 실무에서 NoSQL, Memory DB로 많이 사용되는 Redis에 대해서 알아보는 시리즈를 포스팅해보려 한다.
Linux 서버 기준으로 설치부터 실무 적용, 나아가 Replication 구성을 위한 Sentinel 구성까지 알아보려 한다.
(예전에 실무에 적용한 적이 있는데, 까먹기 전에 정리해야겠다 ^^*)
먼저 이번 글에서는 Redis 설치 및 구성에 대한 내용을 정리한다.
그전에 Redis 란 무엇인지 간략하게 알아보고 가자!
#1. Redis 란?
레디스(Redis)는 "Remote Dictionary Server"의 약자로, Key-Value 구조의 비정형 데이터를 저장하고 관리하기 위한 오픈소스 기반의 비 관계형 데이터베이스 관리 시스템(DBMS)이다. 2009년 살바토르 산필리포(Salvatore Sanfilippo)가 처음 개발 후, 2015년부터 Redis Labs가 지원하고 있다. 모든 데이터를 메모리에 로드해 처리하는 메모리 기반 DBMS이다.db-engines.com 기준 가장 인기있는 Key-Value Stores이다.
Cassandra, HBase 와 같이 NoSQL로 분류되기도 하고, memcached와 같이 In Memory 설루션으로 분류되기도 한다. 성능이 memcached에 버금가면서 다양한 데이터 구조(String, List, Set, Sorted Set, Hashes)를 지원한다는 장점이 있다.
Message Queue, Shared Memory, Remote Dictionary 용도로 사용될 수 있다. 다양한 회사 서비스(라인, 네이버, 삼성전자, Stackoverflow, 인스타그램 등)에서 널리 사용되고 있어 나름의 안정성 및 성능이 검증된 솔루션으로 인정받고 있다.
- 장점
- 다양한 데이터 구조를 지원한다. (String, List, Set, Sorted Set, Hashes)
- 메모리 + 디스크 활용을 통한 영속적인 데이터 보존 가능.
- 서버 측 복제 및 샤딩 지원.
- 다양한 API를 지원. - 단점
- 메모리 사용량이 많다.
기본적으로 memcached 대비 데이터 용량을 지원하기 때문이기도 하지만, 동작 방식에서 오는 메모리 사용량이 많다.
- 대규모 트래픽에 대한 응답속도 불안정.
대규모의 트래픽 발생에 따라 많은양의 데이터가 Update 되면 메모리 할당 방식 차이에 따른 메모리 파편화 및 응답속도 저하가 발생된다 (memcached 대비), 다만 응답속도 저하는 극단적인 환경에서 발생한다고 하며 대규모 서비스에서도 Redis를 많이 도입하는 것을 보면 일반적인 상황에서는 문제가 없을 것으로 판단된다.
#2. 사전 작업
- 패키지 설치 (gcc-c++)
yum 을 통해 Redis 컴파일 설치 시 필요한 "gcc-c++" 패키지를 설치한다.
$ sudo yum -y install gcc-c++
- Memory 설정
메모리 사용량이 허용량을 초과할 경우, overcommit을 처리하는 방식 결정하는 값을 "항상"으로 변경한다. 기본 값은 "0"이다.
0 : 커널 기본값, Heuristic 하게 Overcommit을 허용
(Page Cache + Swap Memory + Slab Reclaimable 값이 요청한 메모리 수 보다 클 경우 허용)
1 : 항상 Overcommit을 허용
2 : 제한적 Overcommit 허용
$ sudo sysctl vm.overcommit_memory=1
$ sudo echo "vm.overcommit_memory=1" >> /etc/sysctl.conf
적용이 잘 됐는지 확인해 보자.
$ sudo sysctl -a | grep vm.overcommit
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.enp2s0.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
vm.overcommit_kbytes = 0
vm.overcommit_memory = 1
vm.overcommit_ratio = 50
설정하지 않으면 Redis 실행 시 아래와 같은 경고가 표시된다.
WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
- TCP Backlog 설정
서버 소켓에 Accept를 대기하는 소켓 개수 파라미터를 변경해 준다. 기본 Accept limit은 128이다. 1024로 변경해 준다. (최대 65535)
$ sudo sysctl -w net.core.somaxconn=1024
$ sudo echo "net.core.somaxconn=1024" >> /etc/sysctl.conf
잘 적용됐는지 확인
$ sudo sysctl -a | grep somaxconn
net.core.somaxconn = 1024
이 역시 변경하지 않으면 Redis 실행 시 경고가 표시된다.
WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
- THP 설정
THP(Transparent Huge Pages) 기능이 Enable 되어 있는 경우 Redis에서는 이를 Disable 시킬 것을 권장한다. 재부팅 시 설정을 변경하기 위해 /etc/rc.local 에도 명령어를 추가해 준다.
# echo never > /sys/kernel/mm/transparent_hugepage/enabled
# vi /etc/rc.local
echo never > /sys/kernel/mm/transparent_hugepage/enabled # <- rc.local 파일에 추가
적용 확인은 아래 명령어를 실행해서, AnonHugePages : 0 이면 정상이다.
$ cat /proc/meminfo | grep AnonHugePages
AnonHugePages: 0 kB
이 역시도 Disable 처리하지 않으면 아래와 같은 경고가 발생된다.
WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.
#3. 다운로드 및 설치
공식 사이트에 접속해서 redis.io/download 안정된(stable) 버전을 다운로드하면 된다. (2020.12 기준 : 6.0.9 버전)
# 설치 경로는 /usr/local/src 로 (내맘)
$ cd /usr/local/src
$ wget https://download.redis.io/releases/redis-6.0.9.tar.gz
압축해제 go go
$ tar -xvf redis-6.0.9.tar.gz
압축을 푼 후 디렉터리명을 변경해 준다. (선택)
$ mv redis-6.0.9 redis ## 이부분은 설치 폴더를 redis 로 지정하기 위함. 필수 아님!!
"make" 명령으로 컴파일을 진행한다.
$ cd redis
$ pwd
/usr/local/src/redis
$ sudo make
cd src && make all
make[1]: Entering directory `/usr/local/src/redis/src'
CC Makefile.dep
...
...
에러 없이 완료되면 "make install"을 입력해서 설치를 진행한다.
$ sudo make install
#4. 구성
여기까지 완료되었으면, "utils" 디렉터리로 이동해서 "install_server.sh"를 실행해 redis 구성을 진행하면 된다.
$ cd utils
$ ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379] #Redis 실행 포트설정
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf] /usr/local/src/redis/conf/6379.conf # 설정파일 위치 지정
Please select the redis log file name [/var/log/redis_6379.log] /usr/local/src/redis/logs/6379.log # 로그저장 위치 지정
Please select the data directory for this instance [/var/lib/redis/6379] /usr/local/src/redis/6379 # 데이터 디렉터리 위치 지정
Please select the redis executable path [/usr/local/bin/redis-server] # 실행 위치는 디폴트값 사용
# 설정된 값을 한번 표시해 준다.
Selected config:
Port : 6379
Config file : /usr/local/src/redis/conf/6379.conf
Log file : /usr/local/src/redis/logs/6379.log
Data dir : /usr/local/src/redis/6379
Executable : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
위와 같이 대화형으로 구성이 진행된다. "[]"안에 기본값이 정해져 있어서 변경하지 않을 경우 "Enter"만 입력하면 끝이 난다.
- 실행 권한 변경
실무에서는 사용하는 Application 담당자 계정에는 대부분 루트/관리자 권한이 없다. (ISMS 보안심사 단골 결함사항) 그렇다 보니 일반 root 외 사용자 계정으로 Redis를 구동해야 하는 경우 redis 관련 디렉터리의 권한 변경만 해주면 가능하다.
chown -R 사용자:그룹 redis # redis 하위폴더 포함 owner를 사용자계정으로 변경
- 서비스 실행/중지
# Redis 서버 실행 기본 127.0.0.1:6379로 실행
$ redis_server start
# shell script 를 작성하여 사용하고 있음
# 서비스 실행
$ ./redis_6379.sh start
# 서비스 중지
$ ./redis_6379.sh stop
# 서비스 상태확인
$ ./redis_6379.sh status
# 서비스 재시작
$ ./redis_6379.sh restart
- shell script (redis_6379.sh)
#!/bin/sh
#Configurations injected by install_server below....
EXEC=/usr/local/bin/redis-server
CLIEXEC=/usr/local/bin/redis-cli
PIDFILE=/usr/local/src/redis/redis_6379.pid
CONF=/usr/local/src/redis/conf/6379.conf
REDISPORT=6379
REDISIP=127.0.0.1 #Redis 서버 IP 입력
REDISPW=패스워드 #Redis 서버 패스워드 입력
###############
# SysV Init Information
# chkconfig: - 58 74
# description: redis_6379 is the redis daemon.
### BEGIN INIT INFO
# Provides: redis_6379
# Required-Start: $network $local_fs $remote_fs
# Required-Stop: $network $local_fs $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Should-Start: $syslog $named
# Should-Stop: $syslog $named
# Short-Description: start and stop redis_6379
# Description: Redis daemon
### END INIT INFO
case "$1" in
start)
if [ -f $PIDFILE ]
then
echo "$PIDFILE exists, process is already running or crashed"
else
echo "Starting Redis Server..."
$EXEC $CONF
fi
;;
stop)
if [ ! -f $PIDFILE ]
then
echo "$PIDFILE does not exist, process is not running"
else
PID=$(cat $PIDFILE)
echo "Stopping ..."
$CLIEXEC -h $REDISIP -p $REDISPORT -a $REDISPW shutdown
while [ -x /proc/${PID} ]
do
echo "Waiting for Redis to shutdown ..."
sleep 1
done
echo "Redis stopped"
fi
;;
status)
PID=$(cat $PIDFILE)
if [ ! -x /proc/${PID} ]
then
echo 'Redis is not running'
else
echo "Redis is running ($PID)"
fi
;;
restart)
$0 stop
$0 start
;;
*)
echo "Please use start, stop, restart or status as first argument"
;;
esac
ShellScript를 이용하면 Redis 인스턴스가 여러 개일 때 보다 편리하게 Redis 서버를 관리할 수 있다.
#5. TEST
아래 프로세스 확인(ps 명령)및 Redis Client(redis-cli)를 통해 서버의 상태를 확인할 수 있다.
# 서버 실행 여부 확인
$ ps -ef | grep redis
$ redis-cli #기본 값으로 Redis 서버에 접속
$ redis-cli -p 6379 #서버 포트를 지정하여 접속
redis 127.0.0.1:6379> ping #서버 정상여부 확인
PONG
redis 127.0.0.1:6379> info #Redis 서버정보 확인
redis 127.0.0.1:6379> set key1 value1 #간단한 key-value 셋팅
### OK
redis 127.0.0.1:6379> get key1 #key1 조회
### value1
로그의 경우, 서버 구성시 지정한 로그파일 경로에서 확인 가능하다.
# 서버 구성시 지정한 로그파일 확인
$ tail -500f /usr/local/src/redis/logs/6379.log
자 이렇게 오늘은 Redis에 대해 간략히 알아보고, 설치-구성해서 간단한 TEST까지 진행해 보았다.
다음에는 Replication, Sentinel 구성 방법에 대해 포스팅해 보겠다.
오늘도 즐거운 하루 보내시길 바란다. ^ㅡ^
댓글