叢集版本:
redis-4.0.14
叢集節點:
節點角色 | IP |
---|---|
redis-master | 10.100.8.21 |
redis-slave1 | 10.100.8.22 |
redis-slave2 | 10.100.8.23 |
redis-sentinel01 | 10.100.8.24 |
redis-sentinel02 | 10.100.8.25 |
redis-sentinel03 | 10.100.8.26 |
主從部署
全部節點執行:
useradd -M -s /sbin/nologin redis;
mkdir /srv/{app,data,logs}/redis;
cd /srv/tmp/
wget http://download.redis.io/releases/redis-4.0.14.tar.gz
tar -zxf redis-4.0.14.tar.gz
cd redis-4.0.14
make MALLOC=libc
make PREFIX=/srv/app/redis install
mkdir /srv/app/redis/conf;
chown -Rf redis:redis /srv/{app,data,logs}/redis;
修改redis-master配置檔案/srv/app/redis/conf/redis.conf
,這裡我們開啟了AOF持久化,並啟用了密碼:
bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /srv/logs/redis/redis.log
databases 16
requirepass "d03fatznjxp6wkk6qvfg5tqjc5u5buod7cc8se7yzdyai9x0"
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /srv/data/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
修改master-slave1從節點的配置/srv/app/redis/conf/redis.conf
,配置slaveof
:
bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /srv/logs/redis/redis.log
databases 16
requirepass "d03fatznjxp6wkk6qvfg5tqjc5u5buod7cc8se7yzdyai9x0"
slaveof 10.100.8.21 6379
masterauth "d03fatznjxp6wkk6qvfg5tqjc5u5buod7cc8se7yzdyai9x0"
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /srv/data/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
修改master-slave2從節點的配置/srv/app/redis/conf/redis.conf
,配置slaveof
:
bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /srv/logs/redis/redis.log
databases 16
requirepass "d03fatznjxp6wkk6qvfg5tqjc5u5buod7cc8se7yzdyai9x0"
slaveof 10.100.8.21 6379
masterauth "d03fatznjxp6wkk6qvfg5tqjc5u5buod7cc8se7yzdyai9x0"
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /srv/data/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
新增redis開機自啟/etc/systemd/system/redis.service
,其中/srv/app/redis/bin/redis-shutdown
指令碼需要自行新增(redis所有節點和sentinel節點都需要)
[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/srv/app/redis/bin/redis-server /srv/app/redis/conf/redis.conf --supervised systemd
ExecStop=/srv/app/redis/bin/redis-shutdown
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
新增/srv/app/redis/bin/redis-shutdown
指令碼到所有叢集,並給予執行許可權chmod 755 /srv/app/redis/bin/redis-shutdown
#!/bin/bash
#
# Wrapper to close properly redis and sentinel
test x"$REDIS_DEBUG" != x && set -x
REDIS_CLI=/srv/app/redis/bin/redis-cli
# Retrieve service name
SERVICE_NAME="$1"
if [ -z "$SERVICE_NAME" ]; then
SERVICE_NAME=redis
fi
# Get the proper config file based on service name
CONFIG_FILE="/srv/app/redis/conf/$SERVICE_NAME.conf"
# Use awk to retrieve host, port from config file
HOST=`awk '/^[[:blank:]]*bind/ { print $2 }' $CONFIG_FILE | tail -n1`
PORT=`awk '/^[[:blank:]]*port/ { print $2 }' $CONFIG_FILE | tail -n1`
PASS=`awk '/^[[:blank:]]*requirepass/ { print $2 }' $CONFIG_FILE | tail -n1`
SOCK=`awk '/^[[:blank:]]*unixsocket\s/ { print $2 }' $CONFIG_FILE | tail -n1`
# Just in case, use default host, port
HOST=${HOST:-127.0.0.1}
if [ "$SERVICE_NAME" = redis ]; then
PORT=${PORT:-6379}
else
PORT=${PORT:-26739}
fi
# Setup additional parameters
# e.g password-protected redis instances
[ -z "$PASS" ] || ADDITIONAL_PARAMS="-a $PASS"
# shutdown the service properly
if [ -e "$SOCK" ] ; then
$REDIS_CLI -s $SOCK $ADDITIONAL_PARAMS shutdown
else
$REDIS_CLI -h $HOST -p $PORT $ADDITIONAL_PARAMS shutdown
fi
啟動redis節點:
chown -Rf redis:redis /srv/{app,data,logs}/redis;
systemctl daemon-reload && systemctl enable redis && systemctl restart redis
檢視redis主從資訊``:
[root@localhost ~]# /srv/app/redis/bin/redis-cli -h 127.0.0.1 -p 6379 -a d03fatznjxp6wkk6qvfg5tqjc5u5buod7cc8se7yzdyai9x0
Warning: Using a password with '-a' option on the command line interface may not be safe.
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.100.8.22,port=6379,state=online,offset=548291,lag=0
slave1:ip=10.100.8.23,port=6379,state=online,offset=548291,lag=0
master_replid:0a56572596b7c46792946836cda553a6dda31898
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:548291
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:548291
sentinel叢集部署
注意:以下所有部署步驟只在sentinel角色機器執行!
之前的部署已經編譯安裝了redis,我們只需要在每臺sentinel節點新增配置/srv/app/redis/conf/redis-sentinel.conf
即可:
bind 0.0.0.0
port 26379
dir /tmp
protected-mode yes
daemonize yes
supervised systemd
sentinel monitor mymaster 10.100.8.21 6379 2
sentinel auth-pass mymaster "d03fatznjxp6wkk6qvfg5tqjc5u5buod7cc8se7yzdyai9x0"
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
logfile /srv/logs/redis/redis-sentinel.log
設定開機自啟/etc/systemd/system/redis-sentinel.service
:
[Unit]
Description=Redis Sentinel
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/srv/app/redis/bin/redis-sentinel /srv/app/redis/conf/redis-sentinel.conf --supervised systemd
ExecStop=/srv/app/redis/bin/redis-shutdown redis-sentinel
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
將上面的配置檔案各自複製到三個sentinel節點,注意:複製配置檔案一定要在啟動redis-sentinel服務之前,因為啟動服務後配置檔案中會生成id號,服務個節點的id相同會造成無法選舉新的master節點
啟動sentinel
chown -Rf redis:redis /srv/{app,data,logs}/redis;
systemctl daemon-reload && systemctl enable redis-sentinel && systemctl restart redis-sentinel
我們再次檢視配置:
[root@vm-10-100-8-24 ~]# cat /srv/app/redis/conf/redis-sentinel.conf
bind 0.0.0.0
port 26379
dir "/tmp"
daemonize yes
protected-mode yes
supervised systemd
sentinel myid f040baa9d10e86988c9658dc475735a851215b04
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 10.100.8.21 6379 2
sentinel auth-pass mymaster d03fatznjxp6wkk6qvfg5tqjc5u5buod7cc8se7yzdyai9x0
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
logfile "/srv/logs/redis/redis-sentinel.log"
# Generated by CONFIG REWRITE
maxclients 4064
sentinel known-slave mymaster 10.100.8.23 6379
sentinel known-slave mymaster 10.100.8.22 6379
sentinel known-sentinel mymaster 10.100.8.26 26379 4db3eb7d479d03a3e964f09541e6b2384ccbdbb2
sentinel known-sentinel mymaster 10.100.8.25 26379 cbcf5b81ec4e77ec1fa2f4f3a15f9e3afe041a24
sentinel current-epoch 0
配置redis+sentinel的日誌自動切割(每個節點都需要新增):
[root@localhost ~]# vim /etc/logrotate.d/redis
/srv/logs/redis/*.log {
weekly
rotate 10
copytruncate
delaycompress
compress
notifempty
missingok
}
驗證叢集
至此, redis主從+sentinel叢集已經部署完畢,接下來我們驗證sentinel叢集的資訊:
[root@vm-10-100-8-24 ~]# /srv/app/redis/bin/redis-cli -p #哨兵模式檢視
127.0.0.1:26379> sentinel master mymaster #輸出被監控的主節點的狀態資訊
1) "name"
2) "mymaster"
3) "ip"
4) "10.100.8.21"
5) "port"
6) "6379"
7) "runid"
8) "f35e9a7eea37303e86079cfc8847d37f77c8c66f"
9) "flags"
10) "master"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "841"
19) "last-ping-reply"
20) "841"
21) "down-after-milliseconds"
22) "30000"
23) "info-refresh"
24) "4592"
25) "role-reported"
26) "master"
27) "role-reported-time"
28) "3859508"
29) "config-epoch"
30) "0"
31) "num-slaves"
32) "2"
33) "num-other-sentinels"
34) "2"
35) "quorum"
36) "2"
37) "failover-timeout"
38) "180000"
39) "parallel-syncs"
40) "1"
127.0.0.1:26379> sentinel slaves mymaster #檢視mymaster的從資訊,可以看到有2個從節點
1) 1) "name"
2) "10.100.8.23:6379"
3) "ip"
4) "10.100.8.23"
5) "port"
6) "6379"
7) "runid"
8) "1db40103b8a18e823f30854bdc8b064b7379c7b4"
9) "flags"
10) "slave"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "376"
19) "last-ping-reply"
20) "376"
21) "down-after-milliseconds"
22) "30000"
23) "info-refresh"
24) "3418"
25) "role-reported"
26) "slave"
27) "role-reported-time"
28) "3868335"
29) "master-link-down-time"
30) "0"
31) "master-link-status"
32) "ok"
33) "master-host"
34) "10.100.8.21"
35) "master-port"
36) "6379"
37) "slave-priority"
38) "90"
39) "slave-repl-offset"
40) "729144"
2) 1) "name"
2) "10.100.8.22:6379"
3) "ip"
4) "10.100.8.22"
5) "port"
6) "6379"
7) "runid"
8) "c73bcc5709123194589324feba5e854bd9b921dc"
9) "flags"
10) "slave"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "376"
19) "last-ping-reply"
20) "376"
21) "down-after-milliseconds"
22) "30000"
23) "info-refresh"
24) "3418"
25) "role-reported"
26) "slave"
27) "role-reported-time"
28) "3868342"
29) "master-link-down-time"
30) "0"
31) "master-link-status"
32) "ok"
33) "master-host"
34) "10.100.8.21"
35) "master-port"
36) "6379"
37) "slave-priority"
38) "100"
39) "slave-repl-offset"
40) "729144"
127.0.0.1:26379> sentinel sentinels mymaster #檢視其它sentinel資訊
1) 1) "name"
2) "4db3eb7d479d03a3e964f09541e6b2384ccbdbb2"
3) "ip"
4) "10.100.8.26"
5) "port"
6) "26379"
7) "runid"
8) "4db3eb7d479d03a3e964f09541e6b2384ccbdbb2"
9) "flags"
10) "s_down,sentinel,disconnected"
11) "link-pending-commands"
12) "2"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "3152356"
17) "last-ok-ping-reply"
18) "3152356"
19) "last-ping-reply"
20) "3152356"
21) "s-down-time"
22) "3122313"
23) "down-after-milliseconds"
24) "30000"
25) "last-hello-message"
26) "1656"
27) "voted-leader"
28) "?"
29) "voted-leader-epoch"
30) "0"
2) 1) "name"
2) "cbcf5b81ec4e77ec1fa2f4f3a15f9e3afe041a24"
3) "ip"
4) "10.100.8.25"
5) "port"
6) "26379"
7) "runid"
8) "cbcf5b81ec4e77ec1fa2f4f3a15f9e3afe041a24"
9) "flags"
10) "s_down,sentinel,disconnected"
11) "link-pending-commands"
12) "2"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "3428000"
17) "last-ok-ping-reply"
18) "3428000"
19) "last-ping-reply"
20) "3428000"
21) "s-down-time"
22) "3397980"
23) "down-after-milliseconds"
24) "30000"
25) "last-hello-message"
26) "1259"
27) "voted-leader"
28) "?"
29) "voted-leader-epoch"
30) "0"
- 哨兵模式下的主從測試
[root@vm-10-100-8-21 ~]# service redis start #停掉master
Redirecting to /bin/systemctl start redis.service
[root@vm-10-100-8-22 ~]# tail -f /srv/logs/redis/redis.log #檢視其中一臺slave的日誌
4701:S 20 Jul 23:18:53.716 * MASTER <-> SLAVE sync started
4701:S 20 Jul 23:18:53.717 # Error condition on socket for SYNC: Connection refused
4701:S 20 Jul 23:18:53.853 * SLAVE OF 10.100.8.23:6379 enabled (user request from 'id=33 addr=10.100.8.25:51437 fd=9 name=sentinel-cbcf5b81-cmd age=79 idle=0 flags=x db=0 sub=0 psub=0 multi=3 qbuf=137 qbuf-free=32631 obl=36 oll=0 omem=0 events=r cmd=exec')
4701:S 20 Jul 23:18:53.854 # CONFIG REWRITE executed with success.
4701:S 20 Jul 23:18:54.719 * Connecting to MASTER 10.100.8.23:6379
4701:S 20 Jul 23:18:54.719 * MASTER <-> SLAVE sync started
4701:S 20 Jul 23:18:54.721 * Non blocking connect for SYNC fired the event.
4701:S 20 Jul 23:18:54.722 * Master replied to PING, replication can continue...
4701:S 20 Jul 23:18:54.723 * Trying a partial resynchronization (request bd76cf3afae3bfa4312299fdba0a30cffa57caf1:13534).
4701:S 20 Jul 23:18:54.724 * Successful partial resynchronization with master.
4701:S 20 Jul 23:18:54.724 # Master replication ID changed to 105cf31a94bd9fd0dfb89b0ae230c930d42ee230
4701:S 20 Jul 23:18:54.724 * MASTER <-> SLAVE sync: Master accepted a Partial Resynchronization.
[root@vm-10-100-8-24 ~]# tail -f /srv/logs/redis/redis-sentinel.log #檢視哨兵日誌
31874:X 20 Jul 23:17:06.392 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
31874:X 20 Jul 23:17:06.393 # Redis version=4.0.14, bits=64, commit=00000000, modified=0, pid=31874, just started
31874:X 20 Jul 23:17:06.393 # Configuration loaded
31874:X 20 Jul 23:17:06.393 * supervised by systemd, will signal readiness
31874:X 20 Jul 23:17:06.395 * Increased maximum number of open files to 4096 (it was originally set to 1024).
31874:X 20 Jul 23:17:06.397 * Running mode=sentinel, port=26379.
31874:X 20 Jul 23:17:06.397 # Sentinel ID is f040baa9d10e86988c9658dc475735a851215b04
31874:X 20 Jul 23:17:06.397 # +monitor master mymaster 10.100.8.21 6379 quorum 1
31874:X 20 Jul 23:17:36.418 # +sdown sentinel 4db3eb7d479d03a3e964f09541e6b2384ccbdbb2 10.100.8.26 26379 @ mymaster 10.100.8.21 6379
31874:X 20 Jul 23:17:49.037 # -sdown sentinel 4db3eb7d479d03a3e964f09541e6b2384ccbdbb2 10.100.8.26 26379 @ mymaster 10.100.8.21 6379
31874:X 20 Jul 23:18:52.654 # +new-epoch 5
31874:X 20 Jul 23:18:52.658 # +vote-for-leader cbcf5b81ec4e77ec1fa2f4f3a15f9e3afe041a24 5
31874:X 20 Jul 23:18:52.670 # +sdown master mymaster 10.100.8.21 6379
31874:X 20 Jul 23:18:52.670 # +odown master mymaster 10.100.8.21 6379 #quorum 1/1
31874:X 20 Jul 23:18:52.670 # Next failover delay: I will not start a failover before Mon Jul 20 23:24:52 2020
31874:X 20 Jul 23:18:53.853 # +config-update-from sentinel cbcf5b81ec4e77ec1fa2f4f3a15f9e3afe041a24 10.100.8.25 26379 @ mymaster 10.100.8.21 6379
31874:X 20 Jul 23:18:53.853 # +switch-master mymaster 10.100.8.21 6379 10.100.8.23 6379
31874:X 20 Jul 23:18:53.854 * +slave slave 10.100.8.22:6379 10.100.8.22 6379 @ mymaster 10.100.8.23 6379
31874:X 20 Jul 23:18:53.854 * +slave slave 10.100.8.21:6379 10.100.8.21 6379 @ mymaster 10.100.8.23 6379