Redis - 설치 및 복제와 HA(Sentinel) 구성 - Cache 와 Redis 설명

Share

Last Updated on 4월 23, 2023 by Jade(정현호)

안녕하세요 
이번 글은 Redis 에 관한 내용 및 설치 와 Replication , HA(Sentinel) 구성에 관해서 확인 해보려고 합니다. 
여기 블로그와 페도라 사용자 모임 사이트에서 사용도 하고 학습 도 하기 위한 용도로 구성한 Redis 를 구성하게 되었습니다. 

Cache 를 사용하는 이유

Redis 를 확인 하기전에 먼저 Cache 를 왜 사용해야하는지 등을 확인해보도록 하겠습니다.

Cache 란 무엇인가로 부터 시작해보는 것이 좋을 것 같습니다.

컴퓨터 과학에서 데이터나 값을 미리 복사해 놓는 임시 장소를 의미합니다. 캐시는 캐시의 접근 시간에 비해 원래 데이터를 접근하는 시간이 오래 걸리는 경우나 값을 다시 계산하는 시간을 절약하고 싶은 경우에 사용하며, 캐시에 데이터를 미리 복사해 놓으면 계산이나 접근 시간 없이 더 빠른 속도로 데이터에 접근할 수 있는 장점이 있습니다.

1 부터 100까지 결과를 더하는 것은 5050 이라고 아주 쉽게 계산할 수 도 있지만 1부터 100까지의 결과인 5050을 외워(기억)둘 수도 있습니다. 그래서 1부터 100까지 더하기가 파스칼인지 가우스 인지를 검색이나 찾는 시간도 줄 일수 있을 것 입니다

[charsyam.wordpress.com]

컴퓨터 아키텍처에서는 CPU의 Register 가 가장 속도가 빠르며, 그다음 L1 ,L2, L3 Cache 그리고 Memory 와 Disk 순으로 접근 속도가 느려지게 됩니다.
Disk 에 가까울 수록 속도는 느려지며, 용량은 커지고 비용은 저렴해지게 됩니다.

웹 서비스의 가장 기본인 접속 후 로그인에 관련 된 서비스를 실행시 유저에 대한 정보 또는 인증 정보 데이터 등을 확인하는 과정이 Disk 에서 가져온다면 가장 느릴 것이며, Memory 에 있다면 훨씬 빠를 것 입니다.

즉 Cache 는 빠른 응답 속도를 위해서 사용됩니다. 다만 의문이 든다면 갈수록 데이터의 사이즈는 증가하지만 메모리 공간은 데이터 저장 공간(Disk 등) 만큼 크지는 않습니다.
그럼 어떻게 요청 되는 많은 데이터를 빠르게 응답해줄 수 있을지가 의문이 생길 수 있습니다.

여기서 파레토법칙(Pareto Law)에 의해서 이러한 부분이 설명을 할 수 있게 됩니다.

80%가 전체 원인의 20%에서 일어나는 현상을 의미하며, 용어를 처음으로 사용한 사람은 주란(J. M. Juran) 이며, 이탈리아 인구의 20%가 이탈리아 전체 부의 80%를 가지고 있다고 주장한 이탈리아의 경제학자 빌프레도 파레토(Vilfredo Federico Damaso Pareto)의 이름에서 가져온 것입니다.

[kapa21.or.kr]

그래서 우리가 사용하는 시스템도 전체의 80%의 요청이나 부하가 상위 20% 유저로 인해서 발생 한다는 의미이며, 다시 그 20%의 80%도 그 안의 20%에 의해서 발생합니다. 그래서, 자주 접근하는 정보만 Cache 하더라도 엄청나게 좋은 효과를 볼 수 있다는 것 입니다.

빈번하게 사용 되는 데이터라도 DB 시스템의 자체 캐시 시스템(Buffer Cache) 에는 크기의 한계가 있으며, 다 목적으로 사용하기 때문에 중간 중간 수행되는 작고 크고 배치나 통계 수행 이나 기타 작업 등에 의해서 또는 여러 이유로 여러 데이터가 DB 시스템의 캐시에 적재와 비워짐을 반복하게 됩니다.

그래서 필연적으로 Disk 에서 읽어서 DB 시스템의 캐시 시스템에 적재 후 조회해야 하는 경우가 발생하게 됩니다.


그래서 사용자 정보, 로그인이나 인증에 관한 정보 등 빈번한 데이터를 서빙하기 위해서 그리고 데이터베이스의 부하를 줄이기 위해서 별도의 Cache 시스템을 사용하게 되며 지금의 시스템 구성에서 보통 Cache 시스템 이제 거의다 사용한다고 생각하고 있습니다.

이러한 Cache 시스템에는 대표적으로 Redis 와 Memcached 등이 있습니다.
           

Redis 란

Redis 는 Remote Dictionary Server 약자로 인 메모리 데이터 저장소로 이며, 분산형 인 메모리의 Key-Value(키 값) 구조의 오픈 소스 기반의 비 관계형 데이터베이스 입니다.

Redis 는 다양한 인 메모리 데이터 구조 집합을 제공 하므로 다양한 사용자 정의 애플리케이션을 손쉽게 사용할 수 있습니다.

Redis 주로 데이터베이스, 캐싱, 세션 관리, message broker 서비스로 stream 와 Pub/Sub 및 랭킹 서비스(Ranking Board), 대기열(queue) 등의 기능으로 사용하고 있습니다.

Redis는 현재 가장 인기 있는 인메모리 Key-Value(키 값) 데이터 스토어로서, BSD 라이선스 이며, 최적화된 C 코드로 작성 되었으며, 다양한 개발 언어를 지원합니다

Redis에서는 다양한 데이터 구조(Data Structures/Collection)를 제공합니다.

[Redis Data Structures]

- Strings / Lists / Sets
- Sorted Sets / Hashes
- Bitmaps / Bit filed /HyperLogLogs
- Streams / Geospatial

다양한 데이터 구조를 지원하는 덕에 Redis는 여러가지 용도로 사용 하며, 이런 다양한 데이터 구조를 지원 되는 것이 Memcached 와의 차이점 이기도 합니다.

Redis는 운영 효율화 및 운영 안정성 면에서 Replication 외 추가적으로 고가용성을 위한 Sentinel 과 확장을 위한 Cluster 를 자체적으로 지원하고 있기 때문에 확장성 과 문제 발생시 장애조치 면에서도 장점이라고 할 수 있습니다.

Redis 자체에 대한 더 자세한 내용은 추가 포스팅에서 다루도록 하겠습니다.
             

Redis 설치

Redis 를 설치 하기전에 먼저 OS 환경 설정을 진행하도록 하겠습니다.
        

포스팅 시스템 구성 현황

포스팅 환경
 OS : 우분투 20.04 / Oracle Linux 8.0 Arm
 Redis : 6.2.6 버전

      +----+         +----+
      | M1 |----+----| R1 |
      | S1 |    |    | S2 |
      +----+    |    +----+
                |
         +------+
         |  
         |   
      +----+
      | C1 |
      | S3 |
      +----+ 

Configuration: quorum = 2


위의 박스안의 내용은 아래와 같습니다
Masters are called M1, M2, M3, …, Mn
Replicas are called R1, R2, R3, …, Rn
Sentinels are called S1, S2, S3, …, Sn
Clients are called C1, C2, C3, …, Cn

Sentinel 은 최소 3개 구성이 필요 하기 때문에 위와 같이 3개로 구성 하였습니다.

Master 와 Replica 는 각각의 서버에서 구동중이고, 해당 서버에서 각각 Sentinel 1 ,2 도 같은 서버에 각각 구동되어있습니다.

그리고 Client 로 표기한 Application 이 구동되는 서버에서 Sentinel 3 가 같이 구동 되어 있습니다.
         

OS 설정

1) 메모리 설정

Overcommit : 1
메모리 사용량이 허용량을 초과할 경우, overcommit 을 처리하는 방식 결정합니다.

sudo sysctl -w vm.overcommit_memory=1


swappiness : 1
스왑 사용의 최소화를 의미하며, 스왑의 사용을 결정 짓는 swap_tendency 공식에서 사용 됩니다.
swap_tendency 에 관한 내용은 이곳을 참조 해보시면 될 것 같습니다.

sudo sysctl -w vm.swappiness=1


Redis setup hints 를 참조하면
Linux에 스왑이 없고 Redis 인스턴스가 실수로 너무 많은 메모리를 소비하는 경우 메모리가 부족할 때 Redis가 Crash 도거나 Linux 커널 OOM Killer 의 의해 Redis 프로세스를 예상치 못하게 종료 될 수도 있습니다.

하지만 스왑이 활성화하여 Redis 가 사용중에 스왑이 사용될 경우 Redis 의 처리 지연 시간이 급증하게 되고 그에 따라서 시스템 상황 또는 Redis 의 문제가 있음을 눈치 챌 수 있고 조치를 할 수 있습니다.


2) TCP 설정

tcp_max_syn_backlog : 4096
TCP 요청으로 유입되는 대량의 SYN 패킷 요청을 수용하도록 listen backlog 큐에 대한 설정 입니다.

sudo sysctl -w net.ipv4.tcp_max_syn_backlog=4096


net.core.somaxconn : 4096
somaxconn 는 애플리케이션이 TCP listen()으로 열리는 Accept를 대기하는 큐 크기 설정 입니다
(리스너의 수락 큐에 있을 수 있는 최대 연결 제한)

sudo sysctl -w net.core.somaxconn=4096



3) File Descriptors 설정

fs.file-max : 6815744
fs.file-max 는 이미 값이 충분히 크다면 변경 하지 않아도 되며 현재 설정 값 조회는 아래와 같이 할 수 있습니다

sudo sysctl fs.file-max


조회결과 6815744 보다 작다면 아래와 같이 설정을 진행하고 더 크다면 설정 하지 않으셔도 됩니다.

sudo sysctl -w fs.file-max=6815744


ulimit nofile : 1048576

echo "
redis soft nofile 1048576
redis hard nofile 1048576" |
sudo tee -a /etc/security/limits.conf > /dev/null


위에서 sysctl 명령어로 적용한 내역에 대해서 재부팅시에도 다시 적용 되도록 파일에 기록 하도록 하겠습니다.
파일명: /etc/sysctl.d/10-redis.conf

echo "vm.overcommit_memory=1
vm.swappiness = 1
net.ipv4.tcp_max_syn_backlog = 4096
net.core.somaxconn=4096
fs.file-max = 6815744" |
sudo tee -a /etc/sysctl.d/10-redis.conf > /dev/null

사용하는 시스템의 상황에 따라서 위의 sysctl 파일에 들어갈 값의 수치나 종류는 다르게 사용하시면 됩니다.


4) THP 비활성화

THP(Transparent Huge Pages) 기능이 Enable 되어 있는 경우 Redis 에서는 이를 Disable 시킬 것을 권장 하고 있습니다.
systemd 서비스를 생성하여 비활성화를 진행하도록 하겠습니다.

Transparent Huge Pages에 대한 내용은 이전 포스팅을 참조하시면 됩니다.


서비스 파일 작성

## disable-transparent-huge-pages.service 이름으로 파일 작성
sudo vi /etc/systemd/system/disable-transparent-huge-pages.service


## 아래 내용으로 작성

[Unit]
Description=Disable Transparent Huge Pages (THP)
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=mongod.service

[Service]
Type=oneshot
ExecStart=/bin/sh -c "echo 'never' >/sys/kernel/mm/transparent_hugepage/enabled && echo 'never' >/sys/kernel/mm/transparent_hugepage/defrag"

[Install]
WantedBy=basic.target


서비스 활성화 및 시작

sudo systemctl daemon-reload
sudo systemctl enable disable-transparent-huge-pages
sudo systemctl start disable-transparent-huge-pages


THP 비활성화 확인

cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never] <--!!

cat /sys/kernel/mm/transparent_hugepage/defrag
always madvise [never] <--!!

조회 결과에서 [never] 로 되어 있는지 확인하시면 됩니다.
      

설치

Redis 는 공식적으로 지원하는 OS는 Linux 와 MacOS 입니다.
윈도우의 경우 Microsoft 에서 직접 빌드 버전을 배포 하기도 하였으나 버전업이 안되고 있는 상태 입니다[Link]

윈도우에서 Redis 를 사용하는 방법은 WSL2 를 이용하여 WLS2 내에서의 리눅스 시스템에서 Redis 를 설치를 하는 것 입니다.

설치에 관련된 추가적인 내용은 아래 Document 를 참고해보시면 됩니다.

Redis 의 공식 설치 방법은 패키지로 설치와 컴파일 설치로 나눌수 있습니다.

패키지는 debian 이나 ubuntu 계열은 레파지토리 추가 후 apt(또는 apt-get) 으로 설치 할 수 있습니다.
CentOS나 Rocky Linux 같은 RPM 계열은 Snapcraft 를 통해서 패키지를 설치 하거나 외부 레파지토리인 REMI repo 를 추가해서 설치 할 수도 있습니다.

또는 Docker 컨테이너를 이용해서 설치하거나 여기서 더해서 쿠버네티스로 관리할 수도 있습니다.

# docker search redis
NAME             DESCRIPTION                              STARS     OFFICIAL   AUTOMATED
redis            Redis is an open source key-value store  10728     [OK]
bitnami/redis    Bitnami Redis Docker Image               212                  [OK]
< ... 중략 ... >

쿠버네티스로 구성 관리 한 내용은 if 카카오 2020에서 카카톡 서비스 캐싱 서비스 관련된 세션에서도 발표된 적이 있습니다.

원본 영상은 지금은 플레이가 안되는 것 같긴 합니다 또는 플레이하는 시점에 따라 영상이 나올수도 있습니다
개인적으로는 해당 세션이 매우 유쾌하고 유용한 내용이 있기 때문에 안보셨다면 한번 쯤 보시는 것을 추천 드립니다.


포스팅에서 사용하는 시스템이 RPM 계열인 Oracle Linux 8.x ARM 시스템 과 Ubuntu 20.04 x86_64 환경이라서 Oracle Linux 에서는 Compile 로 설치를 하고, Ubuntu 에서는 패키지로 설치를 진행하였습니다.
                

Compile 설치

패키지에 관한 내용은 RPM 계열인 CentOS 나 Oracle Linux , Rocky Linux OS 환경에서의 내용입니다.
Ubuntu 에서 APT 를 이용한 패키지 설치는 다음 아래에 내용이 있습니다.


OS 유저 생성

sudo groupadd redis
sudo useradd -M -s /sbin/nologin -g redis redis

-s /bin/false 혹은 /sbin/nologin 옵션을 사용해서 유저의 로그인쉘을 사용할 수 없게 하는 것입니다.
즉 redis 이라는 유저는 Redis 애플리케이션 데몬을 실행하기 위한 유저일 뿐이라는 것입니다.
서버의 보안강화 측면에서 외부에서 redis 유저가 로그인 쉘을 사용할 필요는 없기 때문입니다.

epel 저장소 추가

## Linux version 7
sudo yum install epel-release yum-utils

## Linux version 8
sudo dnf install epel-release yum-utils


필요 패키지 설치

## Linux version 7
sudo yum install gcc gcc-c++ make \
tcl jemalloc-devel lua-devel \
systemd-devel

## Linux version 8 
sudo dnf install gcc gcc-c++ make \
tcl jemalloc-devel lua-devel \
systemd-devel


[참고] gcc version 관련
Redis 6.0 버전의 경우 gcc 4.8 버전대에서 컴파일 할때 _Atomic and threaded IO 관련해서 C11 을 지원하는 gcc compiler 가 필요 했습니다.
RPM 계열(CentOS/Oracle/RHEL) 버전 7.x OS 에서는 yum(패키지) 로 설치 가능한 최신의 gcc 버전은 4.8.5 입니다.

# cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)

# gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

그래서 C11 을 지원하는 gcc 4.9 이상 버전이 필요하였기 때문에 gcc 를 컴파일로 버전업을 해서 사용하거나 devtoolset-7-gcc 패키지 설치 후 해당 gcc 컴파일러를 통해 컴파일하는 방법을 사용해야 했습니다.

Redis 6.2 버전 에서 C11 및 _Atomic 지원 컴파일러에 대한 요구 사항 제거됨에 따라서 gcc 4.8 버전으로도 컴파일할 수 있도록 수정되었습니다.
Ref URL
github.com/redis/7509
github.com/redis/7707
redisgate.kr/redis_release6

그래서 CentOS/Oracle Linux 7.x 버전대에서는 Redis 6.2 를 설치시 4.8 버전대 gcc 로 컴파일 하시면 됩니다.


파일 다운로드 및 압축해제

wget https://download.redis.io/redis-stable.tar.gz
tar -xzvf redis-stable.tar.gz

# 압축해제된 디렉토리로 이동
cd redis-stable

# Redis 버전 확인
grep Released 00-RELEASENOTES | head -1
Redis 6.2.6 Released Mon Oct 4 12:00:00 IDT 2021


Dependencies 빌드

# deps 로 디렉토리 이동
cd deps

# 컴파일
make hdr_histogram hiredis jemalloc linenoise lua

# 이전 디렉토리로 이동
cd ..


Redis 컴파일 및 설치

# 환경 변수 설정
export USE_SYSTEMD=yes

# 빌드
make

# 설치 위치를 지정하여 설치를 진행
sudo make install PREFIX=/usr/local/redis-6.2.6

컴파일(빌드) 된 파일을 설치할 위치를 포스팅에서는 "/usr/local/redis-6.2.6" 으로 지정하고 진행하였습니다.

심볼릭 링크 생성 과 환경 변수 설정

# 심볼릭 링크 생성
cd /usr/local
sudo ln -s /usr/local/redis-6.2.6 redis

# 환경 변수 선언
export PATH=$PATH:/usr/local/redis/bin

# 환경변수 정보 파일에 입력
echo "
export PATH=\$PATH:/usr/local/redis/bin" |
tee -a ~/.bash_profile > /dev/null


추가 디렉토리 생성

# 설정파일 경로 생성
sudo mkdir -p /etc/redis
sudo chown -R root:redis /etc/redis
sudo chmod -R 775 /etc/redis

# dump 파일 경로
sudo mkdir -p /var/lib/redis
sudo chown -R redis:redis /var/lib/redis

# log 파일 경로
sudo mkdir -p /var/log/redis/
sudo chown -R redis:redis /var/log/redis


Post Install Task

Post Install Task 단계 입니다. 해당 단계에서는 conf 파일을 생성하는 과정을 진행합니다.

방법은 크게 두가지로 다운로드 받은 Source Code의 디렉토리내 install_server.sh 를 이용하는 것과 Sample 로 제공되는 conf 파일을 통해서 수정하여 conf 파일을 생성 하는 것 입니다.

# 파일 경로
redis-stable/utils/install_server.sh

스크립트 실행시 아래와 같은 내용을 입력 받게 됩니다.

1. 포트 번호 설정
2. redis config 경로 및 파일명
3. redis log 의 경로 및 파일명
4. 데이터 기록 파일 경로
4. Please select the redis executable path [] 를 설정합니다.
5. redis-server 파일 경로 및 파일명


또다른 방법으로 redis.conf 파일 등을 직접 만들어서 사용하는 방법 입니다.
샘플 conf 파일은 다운로드 받은 Source Code 디렉토리에 있으며 내용을 수정/추가 해서 사용하면 됩니다.

## 샘플 conf 파일 경로
redis-stable/redis.conf
redis-stable/sentinel.conf

redis.conf 는 redis-server의 conf 파일이며 sentinel.conf 는 고가용 구성시 필요한 Sentinel 에서 사용하는 conf 파일 입니다.

redis.conf 파일에 대해서는 환경에 따라서 수정해서 사용하면 되며 포스팅에서는 환경에 맞게 아래 처럼 수정 하도록 하겠습니다.
logdir 경로 지정
pid 파일 경로 및 파일명 변경 : redis_6379.pid -> redis-server.pid
기타 추가 변경

# 파일 복사
cp ./redis-stable/redis.conf /etc/redis/

# conf 파일 수정
sed -i "s/dir .\//dir \/var\/lib\/redis/g" /etc/redis/redis.conf
sed -i "s/logfile \"\"/logfile \/var\/log\/redis\/redis-server.log/g" /etc/redis/redis.conf
sed -i "s/redis_6379.pid/redis\/redis-server.pid/g" /etc/redis/redis.conf
sed -i "s/daemonize no/daemonize yes/g" /etc/redis/redis.conf
sed -i "s/# supervised auto/supervised auto/g" /etc/redis/redis.conf

           

패키지로 설치

우분투/데비안 계열의 패키지 시스템으로 설치는 아래와 같이 진행합니다.


필요 패키지 설치

## local package list update
sudo apt update


### Ubuntu - 20.04
sudo apt install dpkg-dev libhiredis-dev libjemalloc-dev \
liblua5.3-dev lua5.3 gcc \
lua-bitop-dev lua-cjson-dev procps tcl \
build-essential libsystemd-dev


### Ubuntu - 22.04
sudo apt install dpkg-dev libhiredis-dev libjemalloc-dev \
liblua5.4-dev lua5.4 gcc \
lua-bitop-dev lua-cjson-dev procps tcl \
build-essential libsystemd-dev



Ubuntu 22.04 환경에서 libssl 1.1 추가 설치
우분투 22.04 버전에서 Redis 6.0 버전대 설치시 libssl 1.1 은 아래와 같이 별도로 설치가 필요 합니다.

-- ARM
wget http://launchpadlibrarian.net/475575244/libssl1.1_1.1.1f-1ubuntu2_arm64.deb
sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2_arm64.deb

-- x86-64
wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb
sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb



레파지토리 구성

curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list

sudo apt-get update


Redis 설치

sudo apt install redis redis-server redis-sentinel

[참고] 패키지 시스템으로 설치를 하게 되면 일반 유저는 바로 생성 됩니다.

설치 후 바로 서비스가 시작됩니다. conf 파일 변경을 하고 재시작 하기 위해 먼저 종료 하도록 하겠습니다.
(Master / Replica 인스턴스 모두)

# 서비스 종료
sudo systemctl stop redis-server
sudo systemctl stop redis-sentinel

# 프로세스 체크
ps -ef| grep redis

          

복제 conf 파일 구성

먼저 Master 노드에서 conf 파일을 수정하도록 하겠습니다.

sudo vi /etc/redis/redis.conf

포트 바인딩 주소의 기본 값은 127.0.0.1 ::1 으로 로컬에서만 접속이 가능하기 때문에 외부에서 접속을 해야하는 Replication 과 Sentinel 구성에서는 bind 파라미터 변경 해야 합니다.
bind 0.0.0.0

포트는 포스팅에서는 기본 값 6379 로 설정 하였고, 포트는 환경에 따라서 변경 해서 사용 하시면 됩니다.
port 6379



masterauth 는 Master 노드가 비밀번호로 보호되어 있는 경우("requirepass" 지시문 사용시) Replica 노드에서 복제 동기화 프로세스를 시작 과정에서 Master 노드로의 접속 과정에서 인증시 사용하는 비밀번호 입니다.
masterauth "1234!@#$"

requirepass 는 Master 노드의 비밀번호로 이 옵션은 기본 사용자(default user)의 암호를 설정하는 것입니다.
requirepass "1234!@#$"


Memory 관련 해서 OS가 64비트 기준으로 Redis 에서 사용하는 메모리의 제한은 없습니다.
그리고 모든 메모리가 다 사용하였을 때 maxmemory-policy 설정에 따라 처리됩니다.

noeviction : 어떤 key도 제거하지 않으며 쓰기 동작에 대해서 error 를 반환합니다.(Default)
volatile-lru : expire 가 설정된 key 들중에서 LRU algorithm 에 의해서 선택된 key를 제거합니다.
allkeys-lru : 모든 key 들 중 LRU algorithm에 의해서 선택된 key를 제거 합니다.
volatile-random : expire 가 설정된 key 들 중 임의의 key를 제거 합니다.
allkeys-random : 모든 key 들 중 인의의 key를 제거 합니다.
volatile-ttl : expire time이 가장 적게 남은 key를 제거합니다.(minor TTL)

기본값은 noeviction 으로 물리 메모리 + 가상 메모리(swap) 까지 모두 사용시 Redis 에서 에러가 발생 됩니다.

용량은 바이트나 kb 나 mb 등으로 설정할 수 있습니다.
maxmemory 1kb 1mb 1gb 1tb 등등..
maxmemory-policy allkeys-lru


Replica 서버에서 Replica 용 conf 파일을 수정 하도록 하겠습니다.

sudo vi /etc/redis/redis.conf

포트 바인딩 주소와 포트는 Master 와 동일하게  bind 0.0.0.0 , port 6379 으로 설정 하였습니다.

Master 에서 입력한 인증 정보를 추가 합니다.
masterauth 1234!@#$
requirepass 1234!@#$

replicaof 절에는 Replica 에서 바라보는 Redis Master 정보를 입력 하면 됩니다. 아래에서 IP 123.123.123.123 는 예시 입니다
replicaof 123.123.123.123 6379

사용하는 환경이나 정책에 따라서 maxmemory 와 maxmemory-policy 설정을 고려 할 수 있습니다.

Redis 샘플 conf 파일에서 또는 기본값이 대부분이 바로 사용할수 있는 값으로 되어 있어서 Replication 의 경우 일부 파라미터 변경으로 바로 사용할 수 있습니다.

Note

Redis 5.0 버전 부터 slaveof 에서 replicaof 로 변경 되었습니다.

        

OS 방화벽 포트 오픈

사용하는 환경에 따라서 OS 방화벽이 설정되어 있을 경우 포트 오픈을 해야 합니다.

RHEL/CentOS 계열 과 Debian/Ubuntu 계열 별로 OS 방화벽 명령어가 다릅니다. 각각 아래와 같이 포트를 오픈 합니다.

Debian/Ubuntu

# 패키지 설치
sudo apt-get install iptables-persistent netfilter-persistent

데비안/우분투에서 사용하는 iptables 에서 추가된 방화벽 정책을 영구 저장하기 위해서 추가적으로 패키지가 필요 할 수 있습니다(이미 설치가 되어 있을수도 있음)
그래서 먼저 위와 같이 패키지 설치를 진행 합니다.

iptables 에서 포트오픈은 아래와 같이 진행 하도록 하겠습니다.

# 포트오픈
sudo iptables -I INPUT -p tcp -m tcp --dport 6379 -j ACCEPT
sudo iptables -I INPUT -p tcp -m tcp --dport 26379 -j ACCEPT

# 정책 영구 저장
sudo netfilter-persistent save

# 정책 확인
sudo iptables -L

Replication 구성 후 Sentinel 구성을 할 예정이라서 방화벽 오픈은 Sentinel 에서 사용하는 포트(26379)도 지금 같이 오픈 하도록 하겠습니다.

RHEL/CentOS/Rocky Linux

# 포트오픈
firewall-cmd --permanent --add-port=6379/tcp
firewall-cmd --permanent --add-port=26379/tcp

# 정책 반영
firewall-cmd --reload

# 방화벽 룰 조회
firewall-cmd --list-all

firewalld 에서는 위와 같이 포트 오픈을 합니다.
          

Redis 시작

설정을 모두 완료 하였다면 Master 인스턴스와 Replica 인스턴스 모두를 기동 합니다.

컴파일로 설치한 환경에서의 systemd service 파일을 sample 파일을 참조해서 내용을 수정 및 추가 하여 사용할 수 있습니다.

파일 경로
redis-stable/utils/systemd-redis_server.service

포스팅에서는 직접 수정 대신에 패키지에서 배포하는 service 파일을 사용하였습니다.

다운로드
- redis-server.service
- redis-sentinel.service

파일의 위치와 파일명은 아래와 같이 위치 하면 됩니다.
/lib/systemd/system/redis-server.service
/lib/systemd/system/redis-sentinel.service


서비스 활성화 및 시작

sudo systemctl daemon-reload

sudo systemctl enable redis-server.service

sudo systemctl start redis-server.service

     

복제 설정 확인

Master , Replica 인스턴스 기동 후 로그를 확인 해 보겠습니다.

로그 확인

## Master Redis Log
* Replica ...:6379 asks for synchronization
* Full resync requested by replica ...:6379
* Replication backlog created, my new replication IDs are ...
* Starting BGSAVE for SYNC with target: disk
* Background saving started by pid 6544


## Replica Redis Log
* Connecting to MASTER ...:6379
* MASTER <-> REPLICA sync started
* Non blocking connect for SYNC fired the event.
* Master replied to PING, replication can continue...
* Partial resynchronization not possible (no cached master)
* Full resync from master: ...
* MASTER <-> REPLICA sync: receiving 175 bytes from master to disk
* MASTER <-> REPLICA sync: Flushing old data
* MASTER <-> REPLICA sync: Loading DB in memory



복제 정상 유무 확인

간단하게 Master 인스턴스 에서 데이터를 추가하고 Replica 인스턴스에서도 조회가 되는지 확인해 보겠습니다.

• Master

# Master 접속
$ redis-cli -p 6379

replica-1:6379> auth 1234!@#$
OK

# 저장
127.0.0.1:6379> set 1 "key1234"
OK

# 조회
127.0.0.1:6379> get 1
"key1234"


• Replica

# Replica 로 접속
$ redis-cli -h replica-1 -p 6379

replica-1:6379> auth 1234!@#$
OK

#조회 
replica-1:6379> get 1
"key1234"

         

Sentinel

Master - Replica 의 Replication 구성이 완료 되었고, 이제는 HA(고가용성) 기능을 위해서 Sentinel 을 구성하도록 하겠습니다.

구성은 아래와 같이 Master 와 Replica 서버에 Sentinel 1, 2 를 구동하고 Application 구동 되는 서버에 Sentinel 3 를 구동 하도록 하겠습니다.

+----+         +----+
| M1 |----+----| R1 |
| S1 |    |    | S2 |
+----+    |    +----+
          |
   +------+
   |  
   |   
+----+
| C1 |
| S3 |
+----+ 

Sentinel 을 구성하기 위해서는 최소 3개의 Sentinel 노드가 필요 합니다.

Sentinel 배포 구성의 예시는 아래에서 추가로 확인 할 수 있습니다.

        

sentinel.conf 파일 설정

sentinel.conf 파일은 pkg 로 설치했을 경우 자동 생성 되며, 컴파일의 경우 다운로드 받은 Compile Source 파일내에 있습니다.
- 파일 경로
redis-stable/sentinel.conf

컴파일 설치의 경우 sentinel.conf 파일을 복사 후 일부 내용 수정을 먼저 하겠습니다(pkg 기준으로 경로 등을 변경)

# 파일 복사
cp ./redis-stable/sentinel.conf /etc/redis/

# 내용 치환 
sed -i "s/dir \/tmp/dir \/var\/lib\/redis/g" /etc/redis/sentinel.conf
sed -i "s/logfile \"\"/logfile \/var\/log\/redis\/redis-sentinel.log/g" /etc/redis/sentinel.conf
sed -i "s/pidfile \/var\/run/pidfile \/run\/sentinel/g" /etc/redis/sentinel.conf
sed -i "s/daemonize no/daemonize yes/g" /etc/redis/sentinel.conf

# 내용 추가
echo "
supervised systemd
protected-mode no
" |
sudo tee -a /etc/redis/sentinel.conf > /dev/null


추가로 변경할 내용이 몇 가지가 있으며 정책이나 시스템 상황에 따라서 변경하시면 됩니다.

# 센티널이 실행될 포트를 설정 합니다 기본값 26379 입니다.
port 26379

# 센티널이 감시할 레디스 Master 인스턴스 정보를 입력 합니다.
# mymaster 는 MASTER-NAME 정보이며, MASTER-NAME은 센티널이 모니터할 레디스 서버 이름으로 임으로 지정하는 것 입니다.
# 지정한 MASTER-NAME 으로 모니터를 중지(remove)하거나 레디스 서버에 대한 자세한 정보를 조회할 때 사용하고, INFO sentinel 명령의 결과에서 name 항목에 표시됩니다
# 123.123.123.123 는 예시이며 Redis의 마스터 인스턴스 IP 주소를 입력 하면 됩니다.
# 6379 은 Redis 마스터의 포트 번호이며, 2 는 최소 quorum 수를 의미 합니다.
sentinel monitor mymaster 123.123.123.123 6379 2

# 센티널이 Master 인스턴스에 접속하기 위한 패스워드를 입력합니다.
sentinel auth-pass mymaster 1234!@#$

# 다운 되었다고 인지하는 시간으로 마스터 서버에 정기적으로 PING을 보내는데, 이 시간 동안 응답이 없으면 다운된 것으로 판단하고 장애조치(failover) 작업을 시작합니다(기본 30초=30000ms)
sentinel down-after-milliseconds mymaster 3000
  <-- 포스팅에서는 3초(3000ms) 으로 설정 하였습니다.

# Replica 들이 새 마스터에서 데이터를 받도록 replicaof 명령 수행을 동시에 몇개를 수행할지 정하는 파라이터로 디폴트는 1 입니다.
# 1 이면 한 번에 하나의 Replica 에 명령을 실행하고 완료되면 다음 Replica에 명령을 수행하게 됩니다.
# 센티널은 자신이 블로킹(blocking)되지 않게 하려고 명령을 비동기(async)로 실행한다. 만약 이 기능이 없다면 여러 슬레이브가 동시에 새 마스터에 데이터 전체 동기(Full resync)를 요청할 것이다.
sentinel parallel-syncs mymaster 1

# 페일오버 작업 시간의 threshold 를 의미 합니다. 장애조치가 지정된 시간이 지나도 완료 되지 않았으면 취소(abort)하는 시간 으로 기본값은 3분=180초(180000ms) 입니다
sentinel failover-timeout mymaster 180000
      

Sentinel 시작

포스팅에서는 systemd 를 통해서 Redis-server 와 Redis-Sentinel 을 구동 하고 있습니다.

컴파일로 설치한 경우 sentinel.service 파일을 아래 링크에서 다운 로드 받으시면 됩니다.
redis-sentinel.service

파일에서 ExecStart 및 기타 디렉토리가 맞는지는 확인 해야 합니다.

서비스 파일의 위치와 파일명은 아래와 같습니다.

/lib/systemd/system/redis-sentinel.service


RPM 계열에서 SELinux 가 활성화 되었을 경우 아래와 같이 redis-sentinel.service 파일의 속성을 변경 합니다.

sudo chcon -R -u system_u -t systemd_unit_file_t /lib/systemd/system/redis-sentinel.service


설정 완료 하였다면 이제 Sentinel 을 기동 합니다.

sudo systemctl daemon-reload
sudo systemctl enable redis-sentinel.service
sudo systemctl start redis-sentinel.service


3개의 Sentinel 기동 후 Sentinel 로그를 확인하여 3개가 모두 통신이 되는 지를 확인 합니다.

# +monitor master mymaster x.x.x.x 6379 quorum 2
* +slave slave replica-1:6379 replica-1 6379 @ mymaster x.x.x.x 6379
* +sentinel sentinel ............................ replica-1 26379 @ hoing x.x.x.x 6379
* +sentinel sentinel ............................ replica-2 26379 @ hoing x.x.x.x 6379


그리고 Sentinel 에 접속하여 info 를 통해서도 확인을 합니다(포스팅에서는 sentinel 포트를 26379 로 사용하였습니다)

$ redis-cli -p 26379

127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=123.123.123.1:6379,slaves=1,sentinels=3

Master Redis 인스턴스의 IP 정보와 replica의 수(slaves) 그리고 sentinel의 수를 확인 할 수 있습니다
(* Master 인스턴스의 IP 는 123.123.123.1 로 Replica 인스턴스 IP 는 123.123.123.2 로 임의 치환 하였습니다.)
                

장애조치 테스트

Sentinel 구성이 완료 되었기 때문에 Master Redis 인스턴스의 장애가 발생시 장애 조치가 실행 되는지 확인 해보도록 하겠습니다.

먼저 현재 상태를 다시 한번 확인 해보겠습니다.

## Sentinel 에 접속
$ redis-cli -p 26379

127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=123.123.123.1:6379,slaves=1,sentinels=3

# Replica 인스턴스 정보
127.0.0.1:26379> SENTINEL SLAVES mymaster
1)  1) "name"
    2) "123.123.123.2:6379"
    3) "ip"
    4) "123.123.123.2"
    5) "port"
    6) "6379"

Master 와 Replica 인스턴스 정보를 확인 할 수 있으며, 위의 IP 는 임의 치환한 IP 입니다.

이제 Master Redis 를 종료 하도록 하겠습니다.

sudo systemctl stop reedis-server


종료시 Replica 의 server 로그

Connection with master lost.
Caching the disconnected master state.
Reconnecting to MASTER 123.123.123.1:6379
MASTER <-> REPLICA sync started
Error condition on socket for SYNC: Connection refused
Connecting to MASTER 123.123.123.1:6379
MASTER <-> REPLICA sync started
Error condition on socket for SYNC: Connection refused
Connecting to MASTER 123.123.123.1:6379
MASTER <-> REPLICA sync started
Error condition on socket for SYNC: Connection refused
Connecting to MASTER 123.123.123.1:6379
MASTER <-> REPLICA sync started
Error condition on socket for SYNC: Connection refused
Discarding previously cached master state.
Setting secondary replication ID to ...., valid up to offset: 711746. New replication ID is .......
MASTER MODE enabled (user request from 'id=63 addr=123.123.123.1:42139 laddr=123.123.123.2:6379 fd=11 
name=sentinel-.....-cmd age=83 idle=0 flags=x db=0 sub=0 psub=0 multi=4 qbuf=188 
qbuf-free=40766 argv-mem=4 obl=45 oll=0 omem=0 tot-mem=61468 events=r cmd=exec user=default redir=-1')
CONFIG REWRITE executed with success.

* Master 인스턴스의 IP 는 123.123.123.1 로 Replica 인스턴스 IP 는 123.123.123.2 로 임의 치환 하였습니다.


Sentinel 로그

+sdown master mymaster 123.123.123.1 6379
+new-epoch 5
+vote-for-leader ..... 5
+config-update-from sentinel .... 123.123.123.1 26379 @ mymaster 123.123.123.1 6379
+switch-master mymaster 123.123.123.1 6379 123.123.123.2 6379
+slave slave 123.123.123.1:6379 123.123.123.1 6379 @ mymaster 123.123.123.2 6379
+sdown slave 123.123.123.1:6379 123.123.123.1 6379 @ mymaster 123.123.123.2 6379

* Master 인스턴스의 IP 는 123.123.123.1 로 Replica 인스턴스 IP 는 123.123.123.2 로 임의 치환 하였습니다.

종료된 (이전) 마스터 인스턴스가 다시 기동되면 Fail-back 은 자동으로 수행되지 않으며 Replica 인스턴스로 복제가 수행되게 됩니다.

Sentinel 에 접속하여 정보를 조회하면 Master 인스턴스의 정보와 Replica 인스턴스의 IP 정보가 이전과 반대로(Failover에 의한) 된 것을 확인 할 수 있습니다.

$ redis-cli -p 26379

127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=123.123.123.2:6379,slaves=1,sentinels=3

127.0.0.1:26379> SENTINEL SLAVES mymaster
1)  1) "name"
    2) "123.123.123.1:6379"
    3) "ip"
    4) "123.123.123.2"
    5) "port"
    6) "6379"

* Master 인스턴스의 IP 는 123.123.123.1 로 Replica 인스턴스 IP 는 123.123.123.2 로 임의 치환 하였습니다.

다시 Failback 을 하거나 또는 작업 등의 이유로 사용자가 임의로 장애조치를 실행하려고 할때는 Sentinel 에서 아래와 같이 명령어를 수행하면 됩니다.

SENTINEL FAILOVER [마스터서버명]



여기까지 해서 Redis에 대한 간략한 내용과 설치 및 Sentinel 구성까지 확인하였습니다.
Redis 에 대한 추가적인 여러 내용은 다음 포스팅에서 계속 다루도록 하겠습니다.
       

Reference

Reference URL
redis.io/replication
redis.io/sentinel
redis.io/install-redis-from-source
redis.io/auth
redis.io/memory-optimization
dbwriter.io/installation-redis6
redisgate.kr/redis_release6
charsyam.wordpress.com
kapa21.or.kr
    

0
글에 대한 당신의 생각을 기다립니다. 댓글 의견 주세요!x