설치환경 및 Redis소스버전
OS: Ubuntu 22.04.3 LTS
Redis: 7.2.3
아래와 같이 3개의 VM을 준비한다.
No. |
host name |
IP |
node roles |
#1 |
redis-server1 |
172.25.254.131 |
redis (master), sentinel |
#2 |
redis-server2 |
172.25.254.132 |
redis (slave), sentinel |
#3 |
redis-server3 |
172.25.254.133 |
redis (slave), sentinel |
빌드 패키지 설치
1
2
3
4
5
| sudo apt update
sudo apt install build-essential
# systemd로 서비스관리를 원할 경우libsystemd-dev(Debian/Ubuntu) 혹은 systemd-devel(CentOS) 패키지 설치 필요
sudo apt install libsystemd-dev
# sudo yum -y install systemd-devel
|
redis 소스폴더 README참고:
To build with systemd support, you’ll need systemd development libraries (such
as libsystemd-dev on Debian/Ubuntu or systemd-devel on CentOS) and run:
Redis 소스다운로드 및 컴파일 설치
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # 소스 다운로드
curl -O https://download.redis.io/redis-stable.tar.gz
# or
wget https://download.redis.io/redis-stable.tar.gz
# 압축 해제
tar -xzvf redis-stable.tar.gz
cd redis-stable
# 소스 컴파일 및 설치, systemd 지원옵션은 필요여부에 따라 넣으면 됨
make USE_SYSTEMD=yes
sudo make PREFIX=/usr/local/redis-server install
# redis 및 sentinel의 config template 복사
sudo cp redis.conf sentinel.conf /usr/local/redis-server/
# log 디렉토리 생성
sudo mkdir /usr/local/redis-server/logs
|
Redis 사용자 계정 생성
사용자 계정 생성 및 권한설정
1
2
| sudo adduser --system --group --no-create-home redis
sudo chown -R redis:redis /usr/local/redis-server
|
Replication구성 (Master / Slave)
서버별로 아래와 같이 redis.conf
파일 편집
master서버 #1 (172.25.254.131)
1
| sudo vim /usr/local/redis-server/redis.conf
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| # listening IP, 개발환경 같은 경우 편이성을 위하여 코멘트 처리 하거나 0.0.0.0으로 bind해도 되나
# 인터넷에 노출된 서버이거나 운영환경일 경우 보안을 고려하여 IP를 세팅해주자.
bind 172.25.254.131
# 워킹 디렉토리(working directory), rdb, aof파일이 저장되는 위치, Redis는 해당 경로에 대한 R/W권한이 필히 필요함.
dir /usr/local/redis-server/
# replication을 위하여 slave가 master에 접속시 사용되는 비번
# failover를 고려하여 master, slave 무관하게 masterauth, requirepass 같게 설정할것을 권장
masterauth mypass
# 비번설정, 다른 명령 실행시 "AUTH <PASSWORD>" 명령으로 인증후 실행가능.
requirepass mypass
# log파일 위치
logfile "/usr/local/redis-server/logs/redis.log"
# redis주기적으로 RDB(dump)파일을 떨구지만, 장애 발생시 미치 떨구지 못한 데이터는 유실되게 된다.
# 데이터 유실 최소화를 원한다면 AOF 기능을 사용할것을 권장한다.
appendonly yes
# appendonly가 yes로 설정했을때 적용되며, aof파일에 append(file sync)하는 주기를 뜻한다.
# no, always, everysec 3개의 옵션이 있으며,
# no: 디스크에 쓰는 시점을 운영체제에 맡긴다
# always: 비권장 옵션이다. write명령이 실행될 때 마다 aof파일을 쓰므로 성능에 매우 영향을 준다.
# everysec: 데이터를 모아서 1초 마다 디스크에 쓴다. 성능과 데이터 보존측면에서 적절한 옵션이다. 판단이 어려울때 everysec권장
# If unsure, use "everysec".
appendfsync everysec
|
slave 서버 #2 (172.25.254.132)
1
| sudo vim /usr/local/redis-server/redis.conf
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| # listening IP, 개발환경 같은 경우 편이성을 위하여 코멘트 처리 하거나 0.0.0.0으로 bind해도 되나
# 인터넷에 노출된 서버이거나 운영환경일 경우 보안을 고려하여 IP를 세팅해주자.
bind 172.25.254.132
# 워킹 디렉토리(working directory), rdb, aof파일이 저장되는 위치, Redis는 해당 경로에 대한 R/W권한히 필히 필요함.
dir /usr/local/redis-server/
# replication을 위하여 slave가 master에 접속시 사용되는 비번
# failover를 고려하여 master, slave 무관하게 masterauth, requirepass 같게 설정할것을 권장
masterauth mypass
# 비번설정, 다른 명령 실행시 "AUTH <PASSWORD>" 명령으로 인증후 실행가능.
requirepass mypass
# master의 ip/port ( master만 해당옵션을 코멘트 처리해주자 )
replicaof 172.25.254.131 6379
# log파일 위치
logfile "/usr/local/redis-server/logs/redis.log"
# redis주기적으로 RDB(dump)파일을 떨구지만, 장애 발생시 미치 떨구지 못한 데이터는 유실되게 된다.
# 데이터 유실 최소화를 원한다면 AOF 기능을 사용할것을 권장한다.
appendonly yes
# appendonly가 yes로 설정했을때 적용되며, aof파일에 append(file sync)하는 주기를 뜻한다.
# no, always, everysec 3개의 옵션이 있으며,
# no: 디스크에 쓰는 시점을 운영체제에 맡긴다
# always: 비권장 옵션이다. write명령이 실행될 때 마다 aof파일을 쓰므로 성능에 매우 영향을 준다.
# everysec: 데이터를 모아서 1초 마다 디스크에 쓴다. 성능과 데이터 보존측면에서 적절한 옵션이다. 판단이 어려울때 everysec권장
# If unsure, use "everysec".
appendfsync everysec
|
slave 서버 #3 (172.25.254.133)
1
| sudo vim /usr/local/redis-server/redis.conf
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| # listening IP, 개발환경 같은 경우 편이성을 위하여 코멘트 처리 하거나 0.0.0.0으로 bind해도 되나
# 인터넷에 노출된 서버이거나 운영환경일 경우 보안을 고려하여 IP를 세팅해주자.
bind 172.25.254.133
# 워킹 디렉토리(working directory), rdb, aof파일이 저장되는 위치, Redis는 해당 경로에 대한 R/W권한히 필히 필요함.
dir /usr/local/redis-server/
# master의 ip/port ( master만 해당옵션을 코멘트 처리해주자 )
replicaof 172.25.254.131 6379
# replication을 위하여 slave가 master에 접속시 사용되는 비번
# failover를 고려하여 master, slave 무관하게 masterauth, requirepass 같게 설정할것을 권장
masterauth mypass
# 비번설정, 다른 명령 실행시 "AUTH <PASSWORD>" 명령으로 인증후 실행가능.
requirepass mypass
# log파일 위치
logfile "/usr/local/redis-server/logs/redis.log"
# redis주기적으로 RDB(dump)파일을 떨구지만, 장애 발생시 미치 떨구지 못한 데이터는 유실되게 된다.
# 데이터 유실 최소화를 원한다면 AOF 기능을 사용할것을 권장한다.
appendonly yes
# appendonly가 yes로 설정했을때 적용되며, aof파일에 append(file sync)하는 주기를 뜻한다.
# no, always, everysec 3개의 옵션이 있으며,
# no: 디스크에 쓰는 시점을 운영체제에 맡긴다
# always: 비권장 옵션이다. write명령이 실행될 때 마다 aof파일을 쓰므로 성능에 매우 영향을 준다.
# everysec: 데이터를 모아서 1초 마다 디스크에 쓴다. 성능과 데이터 보존측면에서 적절한 옵션이다. 판단이 어려울때 everysec권장
# If unsure, use "everysec".
appendfsync everysec
|
systemd Unit파일 생성
1
| sudo vim /etc/systemd/system/redis-server.service
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| [Unit]
Description=Redis data structure server
Documentation=https://redis.io/documentation
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/local/redis-server/bin/redis-server /usr/local/redis-server/redis.conf --supervised systemd --daemonize no
LimitNOFILE=10032
NoNewPrivileges=yes
Type=notify
TimeoutStartSec=infinity
TimeoutStopSec=infinity
UMask=0077
User=redis
Group=redis
[Install]
WantedBy=multi-user.target
|
서버별로 redis instance 각각 구동
1
| systemctl start redis-server
|
구동후 서비스 상태 확인:
1
| systemctl status redis-server
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| ● redis-server.service - Redis data structure server
Loaded: loaded (/etc/systemd/system/redis-server.service; disabled; vendor preset: enabled)
Active: active (running) since Fri 2023-12-22 05:19:08 UTC; 6s ago
Docs: https://redis.io/documentation
Main PID: 48121 (redis-server)
Status: "Ready to accept connections"
Tasks: 6 (limit: 2178)
Memory: 2.3M
CPU: 19ms
CGroup: /system.slice/redis-server.service
└─48121 "/usr/local/redis-server/bin/redis-server *:6379" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" >
Dec 22 05:19:08 kafka-server1 systemd[1]: Starting Redis data structure server...
Dec 22 05:19:08 kafka-server1 systemd[1]: Started Redis data structure server.
|
Replication확인
master replication상태 확인
1
2
| cd /usr/local/redis-server/bin
./redis-cli -h 172.25.254.131
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| 172.25.254.131:6379> auth mypass
OK
172.25.254.131:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.25.254.133,port=6379,state=online,offset=95561,lag=0
slave1:ip=172.25.254.132,port=6379,state=online,offset=95561,lag=0
master_failover_state:no-failover
master_replid:e396c5f17b331fc17d89f9c03e27e8a4548214f9
master_replid2:b950d0774916c8901184640d4652864788e2a51e
master_repl_offset:95561
second_repl_offset:94277
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:94277
repl_backlog_histlen:1285
|
slave replication상태 확인
1
2
| # 두대의 slave상태 각각 확인
./redis-cli -h 172.25.254.132
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| 172.25.254.132:6379> auth mypass
OK
172.25.254.132:6379> info replication
# Replication
role:slave
master_host:172.25.254.131
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_read_repl_offset:95603
slave_repl_offset:95603
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:e396c5f17b331fc17d89f9c03e27e8a4548214f9
master_replid2:b950d0774916c8901184640d4652864788e2a51e
master_repl_offset:95603
second_repl_offset:94277
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:93577
repl_backlog_histlen:2027
|
서비스 활성화:
1
| systemctl enable redis-server
|
Sentinel 구성
서버별로 sentinel.conf
편집
1
| sudo vim /usr/local/redis-server/sentinel.conf
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # pid파일 위치
pidfile "/usr/local/redis-server/logs/redis-sentinel.pid"
# log파일 위치
logfile "/usr/local/redis-server/logs/sentinel.log"
# monitoring대상 master정보 및 O_DOWN판정(failover)에 필요한 최저 투표수
# sentinel monitor <master-name> <ip> <port> <quorum>
sentinel monitor mymaster 172.25.254.131 6379 2
# master비번
sentinel auth-pass mymaster mypass
# master S_DOWN판정 시간
sentinel down-after-milliseconds mymaster 6000
sentinel failover-timeout mymaster 180000
|
systemd Unit파일 생성
1
| sudo vim /etc/systemd/system/redis-sentinel.service
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| [Unit]
Description=Redis sentinel
Documentation=https://redis.io/docs/management/sentinel/
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/local/redis-server/bin/redis-sentinel /usr/local/redis-server/sentinel.conf --supervised systemd --daemonize no
LimitNOFILE=10032
NoNewPrivileges=yes
Type=notify
TimeoutStartSec=infinity
TimeoutStopSec=infinity
UMask=0077
User=redis
Group=redis
[Install]
WantedBy=multi-user.target
|
서버별로 sentinel instance 각각 구동
1
| systemctl start redis-sentinel
|
구동후 서비스 상태 확인:
1
| systemctl status redis-sentinel
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| ● redis-sentinel.service - Redis sentinel
Loaded: loaded (/etc/systemd/system/redis-sentinel.service; disabled; vendor preset: enabled)
Active: active (running) since Fri 2023-12-22 07:47:47 UTC; 16min ago
Docs: https://redis.io/docs/management/sentinel/
Main PID: 85260 (redis-sentinel)
Status: "Ready to accept connections"
Tasks: 5 (limit: 2178)
Memory: 2.1M
CPU: 3.497s
CGroup: /system.slice/redis-sentinel.service
└─85260 "/usr/local/redis-server/bin/redis-sentinel *:26379 [sentinel]" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ">
Dec 22 07:47:47 kafka-server3 systemd[1]: Starting Redis sentinel...
Dec 22 07:47:47 kafka-server3 systemd[1]: Started Redis sentinel.
|
Sentinel 상태정보 확인
1
2
| cd /usr/local/redis-server/bin
./redis-cli -p 26379 info sentinel
|
1
2
3
4
5
6
7
8
| # Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.25.254.131:6379,slaves=2,sentinels=3
|
서비스 활성화:
1
| systemctl enable redis-sentinel
|
Failover 테스트
이 단계에서 failover 테스트를 해보자. master process를 kill 혹은 sleep 처리하여 구성정보가 정상적으로 변경되였는지 확인하면 된다.
1
2
3
4
5
6
7
| ./bin/redis-cli
127.0.0.1:6379> auth mypass
OK
# debug명령은 redis.conf의 enable-debug-command옵션을 "local" 혹은 "yes"로 변경후 사용가능하다
127.0.0.1:6379> debug sleep 10
OK
(10.01s)
|
log확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| 122668:X 25 Dec 2023 01:30:57.033 # +sdown master mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:57.088 # +odown master mymaster 172.25.254.131 6379 #quorum 2/2
122668:X 25 Dec 2023 01:30:57.088 # +new-epoch 11
122668:X 25 Dec 2023 01:30:57.088 # +try-failover master mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:57.093 * Sentinel new configuration saved on disk
122668:X 25 Dec 2023 01:30:57.093 # +vote-for-leader 8a8d49f48649f665877ae3821c411d2511f1e084 11
122668:X 25 Dec 2023 01:30:57.100 * 79aafc906bc392865fbb1c6f1c9d4f38d8996332 voted for 8a8d49f48649f665877ae3821c411d2511f1e084 11
122668:X 25 Dec 2023 01:30:57.100 * d5e27cf5588cc89870ba1454872b6eedf8f4cae7 voted for 8a8d49f48649f665877ae3821c411d2511f1e084 11
122668:X 25 Dec 2023 01:30:57.155 # +elected-leader master mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:57.155 # +failover-state-select-slave master mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:57.215 # +selected-slave slave 172.25.254.133:6379 172.25.254.133 6379 @ mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:57.215 * +failover-state-send-slaveof-noone slave 172.25.254.133:6379 172.25.254.133 6379 @ mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:57.272 * +failover-state-wait-promotion slave 172.25.254.133:6379 172.25.254.133 6379 @ mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:58.159 * Sentinel new configuration saved on disk
122668:X 25 Dec 2023 01:30:58.159 # +promoted-slave slave 172.25.254.133:6379 172.25.254.133 6379 @ mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:58.159 # +failover-state-reconf-slaves master mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:58.258 * +slave-reconf-sent slave 172.25.254.132:6379 172.25.254.132 6379 @ mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:59.177 * +slave-reconf-inprog slave 172.25.254.132:6379 172.25.254.132 6379 @ mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:59.177 * +slave-reconf-done slave 172.25.254.132:6379 172.25.254.132 6379 @ mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:59.231 # -odown master mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:59.231 # +failover-end master mymaster 172.25.254.131 6379
122668:X 25 Dec 2023 01:30:59.231 # +switch-master mymaster 172.25.254.131 6379 172.25.254.133 6379
122668:X 25 Dec 2023 01:30:59.231 * +slave slave 172.25.254.132:6379 172.25.254.132 6379 @ mymaster 172.25.254.133 6379
122668:X 25 Dec 2023 01:30:59.231 * +slave slave 172.25.254.131:6379 172.25.254.131 6379 @ mymaster 172.25.254.133 6379
122668:X 25 Dec 2023 01:30:59.233 * Sentinel new configuration saved on disk
122668:X 25 Dec 2023 01:31:10.692 * +convert-to-slave slave 172.25.254.131:6379 172.25.254.131 6379 @ mymaster 172.25.254.133 6379
|
대체적으로 아래와 같은 과정을 거쳐 failover가 완료된다.
- master의 다운상태 감지후 +sdown(주관적 다운)이벤트가 발생
- +sdown(주관적 다운) 상태에 대한 기타 sentine의 동의를 거친후 +odown(객관적 다운)상태로 승격
- sentinel leader 선출
- failover 수행
신규 master정보 조회
1
2
3
| ./redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
1) "172.25.254.133"
2) "6379"
|
master ip가 172.25.254.131에서 172.25.254.133으로 변한것을 확인할수 있다.