1. 程式人生 > 實用技巧 >Docker部署Redis主從和哨兵

Docker部署Redis主從和哨兵

1. 主從複製概述

主從複製,是指將一臺Redis伺服器的資料,複製到其他的Redis伺服器。前者稱為主節點(master),後者稱為從節點(slave);資料的複製是單向的,只能由主節點到從節點。

預設情況下,每臺Redis伺服器都是主節點;且一個主節點可以有多個從節點(或沒有從節點),但一個從節點只能有一個主節點。

主從複製的作用

主從複製的作用主要包括:

  1. 資料冗餘:主從複製實現了資料的熱備份,是持久化之外的一種資料冗餘方式。
  2. 故障恢復:當主節點出現問題時,可以由從節點提供服務,實現快速的故障恢復;實際上是一種服務的冗餘。
  3. 負載均衡:在主從複製的基礎上,配合讀寫分離,可以由主節點提供寫服務,由從節點提供讀服務(即寫Redis資料時應用連線主節點,讀Redis資料時應用連線從節點),分擔伺服器負載;尤其是在寫少讀多的場景下,通過多個從節點分擔讀負載,可以大大提高Redis伺服器的併發量。
  4. 高可用基石:除了上述作用以外,主從複製還是哨兵和叢集能夠實施的基礎,因此說主從複製是Redis高可用的基礎

2. 實驗環境

  本人採用虛擬機器VMware內裝centos7版本的Linux系統,redis部署都採用docker容器技術

主機說明 主機IP 哨兵埠
master 192.168.222.157 6379 26379
slave1 192.168.222.157 6380 26380
slave2 192.168.222.157 6381 26381

3. 架構

典型的哨兵架構圖如下所示:

它由兩部分組成,哨兵節點和資料節點:

  • 哨兵節點:哨兵系統由一個或多個哨兵節點組成,哨兵節點是特殊的redis節點,不儲存資料。
  • 資料節點:主節點和從節點都是資料節點。

4. 部署主從

目的:1個主節點、2個從節點和3個哨兵節點

4.1 準備

所有主從伺服器上操作

1.下載redis映象

# 下載redis
docker pull redis

2.在/root目錄下建立6個redis目錄分別存放6個redis容器的配置

3.每個redis目錄下建立conf資料夾存放redis配置檔案

4.下載redis配置檔案

wget http://download.redis.io/redis-stable/redis.conf

5.配置master redis.conf檔案(只需修改紅色的配置即可)

protected-
mode no port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize no supervised no pidfile /var/run/redis_6379.pid loglevel notice logfile "" databases 16 always-show-logo yes save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb rdb-del-sync-files no dir ./ replica-serve-stale-data yes replica-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-diskless-load disabled repl-disable-tcp-nodelay no replica-priority 100 acllog-max-len 128 lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no replica-lazy-flush no lazyfree-lazy-user-del no oom-score-adj no oom-score-adj-values 0 200 800 appendonly no 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 aof-use-rdb-preamble 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 stream-node-max-bytes 4096 stream-node-max-entries 100 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 dynamic-hz yes aof-rewrite-incremental-fsync yes rdb-save-incremental-fsync yes jemalloc-bg-thread yes

6.配置slave redis.conf檔案(只需修改紅色的配置即可)(兩臺slave配置一樣,只是換一下port 6380和6381)

protected-mode no
port 6380
replicaof 192.168.222.157 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
appendonly no
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
aof-use-rdb-preamble 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
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes

7.將寫好的配置檔案放到redis對應的conf目錄下

redis.conf配置介紹

bind 0.0.0.0
# 指定redis只接收來自於該IP地址的請求,如果不進行設定,那麼將處理所有請求

port 6379
# redis監聽的埠號

daemonize no
# 是否在後臺執行

logfile "6379.log"
# 日誌檔案命名及路徑

dbfilename "dump-6379.rdb"
# 資料檔案命名及路徑

slaveof 192.168.12.222 6379  #新的redis版本支援 replicaof              
# 複製選項,slave複製對應的master

appendonly yes
# AOF資料持久化

appendfilename aof-6379.aof
# AOF資料檔案命名

appendfsync everysec
# 寫入策略,預設值everysec,每秒寫一次(呼叫flush)。另外兩個值,always | no,分別表示每次redis寫命令之外就寫檔案,和由作業系統保證。always對硬碟壓力大,everysec是一個平衡值,no對硬碟壓力最小,但排程由系統控制,丟失資料風險最大.

no-appendfsync-on-rewrite yes
# 是否在後臺寫時同步單寫,預設值no(表示需要同步).這裡的後臺寫,表示後臺正在重寫檔案(包括bgsave和bgrewriteaof.bgrewriteaof網上很多資料都沒有涉及到。其實關掉bgsave之後,主要的即是aof重寫檔案了).no表示新的主程序的set操作會被阻塞掉,而yes表示新的主程序的set不會被阻塞,待整個後臺寫完成之後再將這部分set操作同步到aof檔案中。但這可能會存在資料丟失的風險(機率很小),如果對效能有要求,可以設定為yes,僅在後臺寫時會非同步處理命令.

auto-aof-rewrite-percentage 100
aof檔案增長比例,指當前aof檔案比上次重寫的增長比例大小。aof重寫即在aof檔案在一定大小之後,重新將整個記憶體寫到aof檔案當中,以反映最新的狀態(相當於bgsave)。這樣就避免了,aof檔案過大而實際記憶體資料小的問題(頻繁修改資料問題).

auto-aof-rewrite-min-size 64mb
aof檔案重寫最小的檔案大小,即最開始aof檔案必須要達到這個檔案時才觸發,後面的每次重寫就不會根據這個變量了(根據上一次重寫完成之後的大小).此變數僅初始化啟動redis有效.如果是redis恢復時,則lastSize等於初始aof檔案大小.

4.2 啟動容器

啟動master、slave容器

docker run  --name myredis1 -d -v /root/redis1/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /root/redis1/data:/data -p 6379:6379  redis redis-server /usr/local/etc/redis/redis.conf

docker run  --name myredis2 -d -v /root/redis2/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /root/redis2/data:/data -p 6380:6380  redis redis-server /usr/local/etc/redis/redis.conf

docker run  --name myredis3 -d -v /root/redis3/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /root/redis3/data:/data -p 6381:6381  redis redis-server /usr/local/etc/redis/redis.conf

4.3 測試主從複製

在master上建立key value

在slave上檢視

至此,主從複製成功,另外一臺slave就不看了,自信。

5. 部署哨兵

5.1 下載sentinel.conf檔案

wget http://download.redis.io/redis-stable/sentinel.conf

5.2 配置sentinel.conf檔案

(哨兵配置都一樣,只修改port 26380 26381)

port 26379
daemonize no
pidfile /var/run/redis-sentinel.pid
logfile ""
dir /tmp
sentinel monitor mymaster 192.168.222.157 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

sentinel.conf配置介紹

daemonize yes
# 後臺執行

protected-mode no
# 關閉保護模式,即不使用密碼就可以訪問

dir "/data"
# 資料寫入目錄 logfile "26379.log" # 日誌檔案命名及路徑 sentinel monitor mymaster 192.168.222.157 6379 2 # 該哨兵節點監控192.168.222.157 6379名稱為mymaster的主節點,2代表需要2個哨兵節點同意才能判定主節點故障及開始故障轉移 sentinel down-after-milliseconds mymaster 30000 # 指定30000毫秒後mymaster主節點被sentinel判定為不可用。預設30毫秒。 sentinel parallel-syncs mymaster 1 # 這個配置項指定了在發生failover主備切換時最多可以有多少個slave同時對新的master進行同步 # 這個數字越小,完成failover所需的時間就越長,但是如果這個數字越大,就意味著越多的slave因為replication而不可用。 # 可以通過將這個值設為 1 來保證每次只有一個slave 處於不能處理命令請求的狀態。 sentinel failover-timeout mymaster 15000 #1.同一個sentinel對同一個master兩次failover之間的間隔時間。 #2.當一個slave從一個錯誤的master那裡同步資料開始計算時間。直到slave被糾正為向正確的master那裡同步資料時。 #3.當想要取消一個正在進行的failover所需要的時間。 #4.當進行failover時,配置所有slaves指向新的master所需的最大時間。不過,即使過了這個超時,slaves依然會被正確配置為指向master,但是就不按parallel-syncs所配置的規則來了。

5.2 啟動redis哨兵容器

docker run --name mysentinel1 -d -v /root/redis4/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf -v /root/redis4/data:/data -p 26379:26379 redis redis-sentinel /usr/local/etc/redis/sentinel.conf

docker run --name mysentinel2 -d -v /root/redis5/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf -v /root/redis5/data:/data -p 26380:26380 redis redis-sentinel /usr/local/etc/redis/sentinel.conf

docker run --name mysentinel3 -d -v /root/redis6/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf -v /root/redis6/data:/data -p 26381:26381 redis redis-sentinel /usr/local/etc/redis/sentinel.conf

5.3 測試

現在停止當前redis master主節點,檢視哨兵是否判定故障並遷移

docker stop myredis1

docker logs mysentinel1

1:X 16 Sep 2020 05:20:20.031 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:X 16 Sep 2020 05:20:20.031 # Redis version=6.0.7, bits=64, commit=00000000, modified=0, pid=1, just started
1:X 16 Sep 2020 05:20:20.031 # Configuration loaded
1:X 16 Sep 2020 05:20:20.032 * Running mode=sentinel, port=26379.
1:X 16 Sep 2020 05:20:20.032 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:X 16 Sep 2020 05:20:20.033 # Sentinel ID is 6d2cde4e8b3648a5299424e2fd1e628991d71ff3
1:X 16 Sep 2020 05:20:20.034 # +monitor master mymaster 192.168.222.157 6379 quorum 2
1:X 16 Sep 2020 05:20:20.034 * +slave slave 172.17.0.1:6380 172.17.0.1 6380 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 05:20:20.035 * +slave slave 172.17.0.1:6381 172.17.0.1 6381 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 05:22:42.815 * +sentinel sentinel cec9dd73202a580cf4703163037692584ed2e9ff 172.17.0.10 26380 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 05:22:52.591 * +sentinel sentinel 1e8fd10c768640f7ee83d8de6e775285fad6ca94 172.17.0.11 26381 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.308 # +sdown master mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.409 # +new-epoch 1
1:X 16 Sep 2020 06:03:59.410 # +vote-for-leader 1e8fd10c768640f7ee83d8de6e775285fad6ca94 1
1:X 16 Sep 2020 06:03:59.840 # +config-update-from sentinel 1e8fd10c768640f7ee83d8de6e775285fad6ca94 172.17.0.11 26381 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.840 # +switch-master mymaster 192.168.222.157 6379 172.17.0.1 6381
1:X 16 Sep 2020 06:03:59.840 * +slave slave 172.17.0.1:6380 172.17.0.1 6380 @ mymaster 172.17.0.1 6381
1:X 16 Sep 2020 06:03:59.840 * +slave slave 192.168.222.157:6379 192.168.222.157 6379 @ mymaster 172.17.0.1 6381

我們發現,哨兵已將 192.168.222.157:6381 升級為master主節點,成功。

現在恢復192.168.222.157:6379的redis看看日誌會列印什麼?

[root@k8s-master docker]# docker start myredis1
myredis1

[root@localhost mnt]# docker logs mysentinel3
1:X 16 Sep 2020 05:22:50.523 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:X 16 Sep 2020 05:22:50.523 # Redis version=6.0.7, bits=64, commit=00000000, modified=0, pid=1, just started
1:X 16 Sep 2020 05:22:50.523 # Configuration loaded
1:X 16 Sep 2020 05:22:50.524 * Running mode=sentinel, port=26381.
1:X 16 Sep 2020 05:22:50.524 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:X 16 Sep 2020 05:22:50.528 # Sentinel ID is 1e8fd10c768640f7ee83d8de6e775285fad6ca94
1:X 16 Sep 2020 05:22:50.528 # +monitor master mymaster 192.168.222.157 6379 quorum 2
1:X 16 Sep 2020 05:22:50.530 * +slave slave 172.17.0.1:6380 172.17.0.1 6380 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 05:22:50.533 * +slave slave 172.17.0.1:6381 172.17.0.1 6381 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 05:22:50.930 * +sentinel sentinel cec9dd73202a580cf4703163037692584ed2e9ff 172.17.0.10 26380 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 05:22:51.246 * +sentinel sentinel 6d2cde4e8b3648a5299424e2fd1e628991d71ff3 172.17.0.8 26379 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.334 # +sdown master mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.405 # +odown master mymaster 192.168.222.157 6379 #quorum 2/2
1:X 16 Sep 2020 06:03:59.406 # +new-epoch 1
1:X 16 Sep 2020 06:03:59.406 # +try-failover master mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.408 # +vote-for-leader 1e8fd10c768640f7ee83d8de6e775285fad6ca94 1
1:X 16 Sep 2020 06:03:59.410 # cec9dd73202a580cf4703163037692584ed2e9ff voted for 1e8fd10c768640f7ee83d8de6e775285fad6ca94 1
1:X 16 Sep 2020 06:03:59.410 # 6d2cde4e8b3648a5299424e2fd1e628991d71ff3 voted for 1e8fd10c768640f7ee83d8de6e775285fad6ca94 1
1:X 16 Sep 2020 06:03:59.460 # +elected-leader master mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.460 # +failover-state-select-slave master mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.532 # +selected-slave slave 172.17.0.1:6381 172.17.0.1 6381 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.532 * +failover-state-send-slaveof-noone slave 172.17.0.1:6381 172.17.0.1 6381 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.595 * +failover-state-wait-promotion slave 172.17.0.1:6381 172.17.0.1 6381 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.789 # +promoted-slave slave 172.17.0.1:6381 172.17.0.1 6381 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.789 # +failover-state-reconf-slaves master mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:03:59.839 * +slave-reconf-sent slave 172.17.0.1:6380 172.17.0.1 6380 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:04:00.481 # -odown master mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:04:00.856 * +slave-reconf-inprog slave 172.17.0.1:6380 172.17.0.1 6380 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:04:00.856 * +slave-reconf-done slave 172.17.0.1:6380 172.17.0.1 6380 @ mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:04:00.915 # +failover-end master mymaster 192.168.222.157 6379
1:X 16 Sep 2020 06:04:00.915 # +switch-master mymaster 192.168.222.157 6379 172.17.0.1 6381
1:X 16 Sep 2020 06:04:00.915 * +slave slave 172.17.0.1:6380 172.17.0.1 6380 @ mymaster 172.17.0.1 6381
1:X 16 Sep 2020 06:04:00.915 * +slave slave 192.168.222.157:6379 192.168.222.157 6379 @ mymaster 172.17.0.1 6381
1:X 16 Sep 2020 06:04:30.979 # +sdown slave 192.168.222.157:6379 192.168.222.157 6379 @ mymaster 172.17.0.1 6381
1:X 16 Sep 2020 06:11:08.621 # -sdown slave 192.168.222.157:6379 192.168.222.157 6379 @ mymaster 172.17.0.1 6381
1:X 16 Sep 2020 06:11:22.954 * +slave slave 172.17.0.1:6379 172.17.0.1 6379 @ mymaster 172.17.0.1 6381

192.168.222.157:6379已經成為192.168.222.157:6381的從節點。那麼本次部署結束。