作業(yè) 1024
1、RDB和AOF的優(yōu)缺點
# RDB 模式優(yōu)點
1.RDB快照保存了某個時間點的數(shù)據(jù),可以通過腳本執(zhí)行redis指令'bgsave(非阻塞,后臺執(zhí)行)'或者'save(會阻塞寫操作,不推薦)命令自定義時間點'進行備份,可以保留多個備份。
當(dāng)出現(xiàn)問題'可以恢復(fù)到不同時間點的版本',很適合備份,并且此'文件格式支持許多第三方工具',可以進行后續(xù)的數(shù)據(jù)分析
2.RDB可以'最大化Redis的性能',父進程在保存 RDB文件時唯一要做的就是fork出一個子進程,然后這個子進程就會處理接下來的所有保存工作,父進程無須執(zhí)行任何磁盤 I/O 操作。
3.RDB在大量數(shù)據(jù),比如幾個G的數(shù)據(jù),'恢復(fù)的速度比AOF的快
# RDB 模式缺點
1.'不能實時保存數(shù)據(jù)',可能會丟失自上一次執(zhí)行RDB備份到當(dāng)前的內(nèi)存數(shù)據(jù)
2.當(dāng)數(shù)據(jù)量非常大的時候,從父進程fork子進程進行保存至RDB文件時需要一點時間,取決于磁盤IO性能
'在數(shù)據(jù)集比較龐大時,fork()生成子進程可能會非常耗時,造成服務(wù)器在一定時間內(nèi)停止處理客戶端﹔如果數(shù)據(jù)集非常巨大,并且CPU時間非常緊張的話,那么這種停止時間甚至可能會長達整整一秒或更久。'
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
# AOF模式優(yōu)點
1.'數(shù)據(jù)安全性相對較高',根據(jù)所使用的fsync策略(fsync是同步內(nèi)存中redis所有已經(jīng)修改的文件到存儲設(shè)備),默認是appendfsync everysec,即每秒執(zhí)行一次 fsync,在這種配置下,Redis 仍然可以保持良好的性能,并且就算發(fā)生故障停機,也'最多只會丟失一秒鐘的數(shù)據(jù)( fsync會在后臺線程執(zhí)行,所以主線程可以繼續(xù)努力地處理命令請求)
2.由于該機制對日志文件的寫入操作采用的是append模式,因此在寫入過程中不需要seek, '即使出現(xiàn)宕機現(xiàn)象,也不會破壞日志文件中已經(jīng)存在的內(nèi)容'。然而如果本次操作只是寫入了一半數(shù)據(jù)就出現(xiàn)了系統(tǒng)崩潰問題,不用擔(dān)心,在Redis下一次啟動之前,可以通過 redis-check-aof 工具來解決數(shù)據(jù)一致性的問題
3.Redis可以'在 AOF文件體積變得過大時,自動地在后臺對AOF進行重寫',重寫后的新AOF文件包含了恢復(fù)當(dāng)前數(shù)據(jù)集所需的最小命令集合。 整個重寫操作是絕對安全的,因為Redis在創(chuàng)建新 AOF文件的過程中,append模式不斷的將修改數(shù)據(jù)追加到現(xiàn)有的 AOF文件里面,即使重寫過程中發(fā)生停機,現(xiàn)有的 AOF文件也不會丟失。 而一旦新AOF文件創(chuàng)建完畢,Redis就會從舊AOF文件切換到新AOF文件,并開始對新AOF文件進行追加操作。
4.AOF包含一個'格式清晰、易于理解的日志文件'用于記錄所有的修改操作。事實上,也可以通過該文件完成數(shù)據(jù)的重建
AOF文件有序地保存了對數(shù)據(jù)庫執(zhí)行的所有寫入操作,這些寫入操作以Redis協(xié)議的格式保存,因此 'AOF文件的內(nèi)容非常容易被人讀懂,對文件進行分析(parse)也很輕松'。
'導(dǎo)出(export)AOF文件也非常簡單':舉個例子,如果你不小心執(zhí)行了FLUSHALL.命令,但只要AOF文件未被重寫,那么只要停止服務(wù)器,移除 AOF文件末尾的FLUSHAL命令,并重啟Redis ,就可以將數(shù)據(jù)集恢復(fù)到FLUSHALL執(zhí)行之前的狀態(tài)。
# AOF模式缺點
1.即使有些操作是重復(fù)的也會全部記錄,AOF 的文件大小要大于 RDB 格式的文件
2.AOF 在恢復(fù)大數(shù)據(jù)集時的速度比 RDB 的恢復(fù)速度要慢
3.根據(jù)fsync策略不同,AOF速度可能會慢于RDB
4.bug 出現(xiàn)的可能性更多
2、master和slave同步過程
1)從服務(wù)器連接主服務(wù)器,發(fā)送PSYNC命令
2)主服務(wù)器接收到PSYNC命令后,開始執(zhí)行BGSAVE命令生成RDB快照文件,并使用緩沖區(qū)記錄此后執(zhí)行的所有寫命令
3)主服務(wù)器BGSAVE執(zhí)行完后,向所有從服務(wù)器發(fā)送RDB快照文件,并在發(fā)送期間繼續(xù)記錄被執(zhí)行的寫命令
4)從服務(wù)器收到快照文件后丟棄所有舊數(shù)據(jù),載入收到的快照至內(nèi)存
5)主服務(wù)器快照發(fā)送完畢后,開始向從服務(wù)器發(fā)送緩沖區(qū)中的寫命令
6)從服務(wù)器完成對快照的載入,開始接收命令請求,并執(zhí)行來自主服務(wù)器緩沖區(qū)的寫命令
7)后期同步,從服務(wù)器會先發(fā)送自己的slave_repl_offset位置,只同步新增加的數(shù)據(jù),不再全量同步
3、哨兵的使用和實現(xiàn)機制?
1 哨兵的準備:先實現(xiàn)主從復(fù)制架構(gòu)
在已實現(xiàn)主從架構(gòu)的情況下,實現(xiàn)一個一主兩從、基于哨兵的高可用redis架構(gòu)
# 注意: master 的配置文件中masterauth 和slave 都必須相同!??!
==========================================================
# 實現(xiàn)一主二從:
1.所有節(jié)點執(zhí)行:
yum -y install redis
sed -i -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth.*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/' /etc/redis.conf
2.在兩臺從節(jié)點執(zhí)行:
echo "replicaof 10.0.0.8 6379" >> /etc/redis.conf
3.所有節(jié)點執(zhí)行:
systemctl enable --now redis
# 檢查主節(jié)點狀態(tài)
[root@CentOS8 ~]#redis-cli -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:2
slave0:ip=10.0.0.58,port=6379,state=online,offset=112,lag=1
slave1:ip=10.0.0.68,port=6379,state=online,offset=112,lag=1
master_replid:3293d562bd15ecac07eecae47100ca67d0c0353c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:112
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:112
# 配置從節(jié)點(兩臺相同操作):
[root@centos8 ~]#redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> REPLICAOF 10.0.0.8 6379
OK Already connected to specified master
127.0.0.1:6379> config set masterauth "123456"
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.8
master_port:6379
master_link_status:up
......
==========================================================
2 編輯哨兵的配置文件
Sentinel實際上是一個特殊的redis服務(wù)器,默認監(jiān)聽在26379/tcp端口
哨兵可以不和Redis服務(wù)器部署在一起,但一般部署在一起,所有redis節(jié)點使用相同的配置文件
# 如果是編譯安裝,在源碼目錄有sentinel.conf,復(fù)制到安裝目錄即可
如:/apps/redis/etc/sentinel.conf
==========================================================
# 配置文件:
[root@CentOS8 ~]#grep '^[^#]' /etc/redis-sentinel.conf
port 26379
daemonize no
pidfile /var/run/redis-sentinel.pid
logfile "" # 自定義日志目錄,若指定,需要修改權(quán)限屬性(保持原狀,不影響下面生效)
dir /tmp
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
logfile /var/log/redis/sentinel.log # 默認日志位置?。?!
==========================================================
'必要設(shè)置項1'
sentinel monitor mymaster 10.0.0.8 6379 2
# 指定當(dāng)前mymaster集群中master服務(wù)器的地址和端口
# 2 為法定人數(shù)限制(quorum),即有幾個sentinel認為master down了就進行故障轉(zhuǎn)移,一般此值是所有sentinel節(jié)點數(shù)量(一般總數(shù)是3以上的奇數(shù))的一半以上的整數(shù)值。。。比如,此例中總數(shù)是3,即3/2=1.5,取整為2。是master的ODOWN客觀下線的依據(jù)
'必要設(shè)置項2'
sentinel auth-pass mymaster 123456
# mymaster集群中master的密碼。。。注意此行要緊接在上面行的下面?。?!
sentinel down-after-milliseconds mymaster 30000
# (SDOWN)判斷mymaster集群中所有節(jié)點的主觀下線的時間,單位:毫秒,建議3000
sentinel parallel-syncs mymaster 1
# 發(fā)生故障轉(zhuǎn)移后,同時向新master同步數(shù)據(jù)的slave數(shù)量,數(shù)字越小總同步時間越長,但可以減輕新master的負載壓力
sentinel failover-timeout mymaster 180000
# 所有slaves指向新的master所需的超時時間,單位:毫秒
# 日志
logfile /var/log/redis/sentinel.log
========================================================================
## 三個哨兵服務(wù)器的配置都如下(只有3行需要變動):
========================================================================
sentinel monitor mymaster 10.0.0.8 6379 2 # 修改此行
sed -ri 's/^(sentinel monitor mymaster).*/\1 10.0.0.8 6379 2/' /etc/redis-sentinel.conf
sentinel auth-pass mymaster 123456 # 增加此行(緊跟著上一行)
sed -ri '/sentinel monitor mymaster/a\sentinel auth-pass mymaster 123456' /etc/redis-sentinel.conf
sentinel down-after-milliseconds mymaster 3000 # 修改此行
sed -ri 's/^(sentinel down-after-milliseconds).*/\1 mymaster 3000/' /etc/redis-sentinel.conf
# 最終結(jié)果:
[root@centos8 ~]#grep '^[^#]' /etc/redis-sentinel.conf
port 26379
daemonize no
pidfile /var/run/redis-sentinel.pid
logfile ""
dir /tmp
sentinel monitor mymaster 10.0.0.8 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 3000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
logfile /var/log/redis/sentinel.log
3 啟動哨兵
# 啟動哨兵,在其配置文件中會生成 'sentinel myid'
注:'sentinel myid'是自動生成的,且必須唯一
若發(fā)生雷同需要手動修改,隨便改,修改后需重啟redis和sentinel服務(wù)
==============================================================
# 啟動
systemctl enable --now redis-sentinel
# 檢查 myid(確保每個哨兵主機myid不同)
[root@CentOS8 ~]#grep 'myid' /etc/redis-sentinel.conf
sentinel myid 482ea8aa1764314909473803ae4e15c93fd9f174
[root@centos8 ~]#grep 'myid' /etc/redis-sentinel.conf
sentinel myid 757ac9a40542a060b12e4f570e9f19c016b0762f
[root@centos8 ~]#grep 'myid' /etc/redis-sentinel.conf
sentinel myid b8f9d69a8b849fa09ede20a45fb8d91c55d72c52
注:如果是編譯安裝,在所有哨兵服務(wù)器執(zhí)行下面操作啟動哨兵
`/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf
4 驗證哨兵端口
[root@CentOS8 ~]#ss -ntl | grep 26379
LISTEN 0 128 0.0.0.0:26379 0.0.0.0:*
LISTEN 0 128 [::]:26379 [::]:*
5 查看哨兵日志
# master的哨兵日志
[root@CentOS8 ~]#tail -f /var/log/redis/sentinel.log
19131:X 23 Oct 2020 20:36:12.035 # Configuration loaded
19131:X 23 Oct 2020 20:36:12.035 * supervised by systemd, will signal readiness
19131:X 23 Oct 2020 20:36:12.036 * Running mode=sentinel, port=26379.
19131:X 23 Oct 2020 20:36:12.036 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
19131:X 23 Oct 2020 20:36:12.036 # Sentinel ID is 482ea8aa1764314909473803ae4e15c93fd9f174
19131:X 23 Oct 2020 20:36:12.036 # +monitor master mymaster 10.0.0.8 6379 quorum 2
19131:X 23 Oct 2020 20:36:12.040 * +slave slave 10.0.0.68:6379 10.0.0.68 6379 @ mymaster 10.0.0.8 6379
19131:X 23 Oct 2020 20:36:12.040 * +slave slave 10.0.0.58:6379 10.0.0.58 6379 @ mymaster 10.0.0.8 6379
19131:X 23 Oct 2020 20:36:14.104 * +sentinel sentinel 757ac9a40542a060b12e4f570e9f19c016b0762f 10.0.0.58 26379 @ mymaster 10.0.0.8 6379
19131:X 23 Oct 2020 20:36:14.119 * +sentinel sentinel b8f9d69a8b849fa09ede20a45fb8d91c55d72c52 10.0.0.68 26379 @ mymaster 10.0.0.8 6379
# slave的哨兵日志
[root@centos8 ~]#tail -f /var/log/redis/sentinel.log
18272:X 23 Oct 2020 20:36:12.063 # Configuration loaded
18272:X 23 Oct 2020 20:36:12.063 * supervised by systemd, will signal readiness
18272:X 23 Oct 2020 20:36:12.064 * Running mode=sentinel, port=26379.
18272:X 23 Oct 2020 20:36:12.064 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
18272:X 23 Oct 2020 20:36:12.065 # Sentinel ID is b8f9d69a8b849fa09ede20a45fb8d91c55d72c52
18272:X 23 Oct 2020 20:36:12.065 # +monitor master mymaster 10.0.0.8 6379 quorum 2
18272:X 23 Oct 2020 20:36:12.066 * +slave slave 10.0.0.68:6379 10.0.0.68 6379 @ mymaster 10.0.0.8 6379
18272:X 23 Oct 2020 20:36:12.067 * +slave slave 10.0.0.58:6379 10.0.0.58 6379 @ mymaster 10.0.0.8 6379
18272:X 23 Oct 2020 20:36:14.068 * +sentinel sentinel 482ea8aa1764314909473803ae4e15c93fd9f174 10.0.0.8 26379 @ mymaster 10.0.0.8 6379
18272:X 23 Oct 2020 20:36:14.107 * +sentinel sentinel 757ac9a40542a060b12e4f570e9f19c016b0762f 10.0.0.58 26379 @ mymaster 10.0.0.8 6379
6 當(dāng)前sentinel狀態(tài)
# 關(guān)注sentinel狀態(tài)最后一行,涉及到masterIP是多少,有幾個slave,有幾個sentinels,必須是符合全部服務(wù)器數(shù)量
# 注意:
'redis-cli -p 26379' 表示連接哨兵服務(wù)器?。。。。。。?==========================================================================
# 主節(jié)點:
[root@CentOS8 ~]#redis-cli -p 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=10.0.0.8:6379,slaves=2,sentinels=3
# 任選從節(jié)點:
[root@centos8 ~]#redis-cli -p 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=10.0.0.8:6379,slaves=2,sentinels=3
'兩個slave、三個sentinel服務(wù)器。。如果sentinels值不符合,檢查myid,很可能是因為myid沖突
7 停止Redis Master,測試故障轉(zhuǎn)移
# 殺掉主節(jié)點的 redis
killall redis-server
# 查看從節(jié)點哨兵信息
[root@centos8 ~]#redis-cli -p 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=10.0.0.68:6379,slaves=2,sentinels=3
'雖然數(shù)量無變化。。因為舊master已經(jīng)被哨兵修改為一個新的slave!?。?'注意:此處數(shù)目并不表示在線!?。?!只能表示當(dāng)前架構(gòu)各個主機數(shù)量?。。。ㄅfmaster的redis已經(jīng)切斷)
# 查看日志 ,發(fā)現(xiàn)新主為 10.0.0.68
18272:X 23 Oct 2020 20:48:21.878 # -odown master mymaster 10.0.0.8 6379 【客觀宕機】
18272:X 23 Oct 2020 20:48:21.878 # +failover-end master mymaster 10.0.0.8 6379
18272:X 23 Oct 2020 20:48:21.878 # +switch-master mymaster 10.0.0.8 6379 10.0.0.68 6379【切換新主】
18272:X 23 Oct 2020 20:48:21.878 * +slave slave 10.0.0.58:6379 10.0.0.58 6379 @ mymaster 10.0.0.68 6379
18272:X 23 Oct 2020 20:48:21.879 * +slave slave 10.0.0.8:6379 10.0.0.8 6379 @ mymaster 10.0.0.68 6379
18272:X 23 Oct 2020 20:48:24.911 # +sdown slave 10.0.0.8:6379 10.0.0.8 6379 @ mymaster 10.0.0.68 6379
# 檢查主從關(guān)系
# 在slave-58查看:
[root@centos8 ~]#redis-cli -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:10.0.0.68
master_port:6379
master_link_status:up
.....
# 在slave-68查看:(已成為新主,且只有一個slave在線)
[root@centos8 ~]#redis-cli -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.58,port=6379,state=online,offset=270422,lag=1
master_replid:70c2be922ed56af27eedbd848b2a66c7f7e9a414
.....
============================================================================
# 恢復(fù)故障的原master重新加入redis集群
# 重啟舊主的 redis
systemctl start redis
# 在新主查看主從關(guān)系(等待幾秒)
[root@centos8 ~]#redis-cli -a 123456 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:2 # 已有兩個slave(哨兵起作用)
slave0:ip=10.0.0.58,port=6379,state=online,offset=286079,lag=0
slave1:ip=10.0.0.8,port=6379,state=online,offset=285946,lag=0
.........
8 故障轉(zhuǎn)移后的redis配置文件會被自動修改
# 故障轉(zhuǎn)移后,redis.conf中的replicaof行的master IP會被修改
# 哨兵配置文件的sentinel monitor IP 同樣也會被修改
# 在slave-58查看:
[root@centos8 ~]#grep ^replicaof /etc/redis.conf
replicaof 10.0.0.68 6379
# 在所有節(jié)點查看:
[root@centos8 ~]#grep "^sentinel monitor" /etc/redis-sentinel.conf
sentinel monitor mymaster 10.0.0.68 6379 2
'當(dāng)前監(jiān)控都為 10.0.0.68 (因為哨兵監(jiān)控主節(jié)點,此時68為新主)
4、redis cluster集群創(chuàng)建和使用
基于Redis 5的redis cluster 部署:
1 創(chuàng)建redis cluster集群的環(huán)境準備
1. 每個redis 節(jié)點采用相同的'硬件配置'、相同的密碼、相同的redis版本
2. 所有redis服務(wù)器必須沒有任何數(shù)據(jù)
3. 準備六臺主機,地址如下
10.0.0.8
10.0.0.18
10.0.0.28
10.0.0.38
10.0.0.48
10.0.0.58
2 啟用redis cluster配置
# 安裝
dnf -y install redis
# 每個節(jié)點修改redis配置,必須開啟cluster功能的參數(shù)
sed -i.bak -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e '/masterauth/a masterauth 123456' -e '/# requirepass/a requirepass 123456' -e '/# cluster-enabled yes/a cluster-enabled yes' -e '/# cluster-config-file nodes-6379.conf/a cluster-config-file nodes-6379.conf' -e '/cluster-require-full-coverage yes/c cluster-require-full-coverage no' /etc/redis.conf
systemctl enable --now redis
# 驗證當(dāng)前Redis服務(wù)狀態(tài):
[root@CentOS8 ~]#ss -ntl | grep 6379
LISTEN 0 128 0.0.0.0:16379 0.0.0.0:*
LISTEN 0 128 0.0.0.0:6379 0.0.0.0:*
注:cluster的端口號是在 redis服務(wù)設(shè)置的端口號上 +10000 (若修改redis—port=6666,則cluster-port=16666)
3 創(chuàng)建集群
# 注:選項 --cluster-replicas 1 表示每個master對應(yīng)一個slave節(jié)點
===============================================================
# 執(zhí)行(--cluster create)
[root@CentOS8 ~]#redis-cli -a 123456 --cluster create 10.0.0.8:6379 10.0.0.18:6379 10.0.0.28:6379 10.0.0.38:6379 10.0.0.48:6379 10.0.0.58:6379 --cluster-replicas 1
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 10.0.0.38:6379 to 10.0.0.8:6379
Adding replica 10.0.0.48:6379 to 10.0.0.18:6379
Adding replica 10.0.0.58:6379 to 10.0.0.28:6379
'注: M 表示 master、 S 表示 slave
M: bfbbb2390cffddbdb6cad159658a4b8770702cd8 10.0.0.8:6379
slots:[0-5460] (5461 slots) master # 當(dāng)前master的槽位范圍
M: 4457771149df7949b7d94cec318f4e783b5e5a18 10.0.0.18:6379
slots:[5461-10922] (5462 slots) master
M: 6061cf2702a7c07bb64debbdc9bc7897a672d152 10.0.0.28:6379
slots:[10923-16383] (5461 slots) master
S: bb1c85f4a072be2d8645a40ecef76c358da29f3b 10.0.0.38:6379
replicates bfbbb2390cffddbdb6cad159658a4b8770702cd8
S: 5a469424de6187f662ff825b40b3766fca893325 10.0.0.48:6379
replicates 4457771149df7949b7d94cec318f4e783b5e5a18
S: 7a19f3c4082136d3d7c11f6a5c7665e461b2b565 10.0.0.58:6379
replicates 6061cf2702a7c07bb64debbdc9bc7897a672d152
Can I set the above configuration? (type 'yes' to accept): # 輸入 yes 自動創(chuàng)建集群
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 10.0.0.8:6379)
M: bfbbb2390cffddbdb6cad159658a4b8770702cd8 10.0.0.8:6379
slots:[0-5460] (5461 slots) master # 已經(jīng)分配的槽位
1 additional replica(s) # 分配了一個slave
M: 4457771149df7949b7d94cec318f4e783b5e5a18 10.0.0.18:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: bb1c85f4a072be2d8645a40ecef76c358da29f3b 10.0.0.38:6379
slots: (0 slots) slave # slave沒有分配槽位
replicates bfbbb2390cffddbdb6cad159658a4b8770702cd8 # 38對應(yīng)的master=8,此即為8的id
S: 5a469424de6187f662ff825b40b3766fca893325 10.0.0.48:6379
slots: (0 slots) slave
replicates 4457771149df7949b7d94cec318f4e783b5e5a18 # 48對應(yīng)的master=18,此即為18的id
M: 6061cf2702a7c07bb64debbdc9bc7897a672d152 10.0.0.28:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 7a19f3c4082136d3d7c11f6a5c7665e461b2b565 10.0.0.58:6379
slots: (0 slots) slave
replicates 6061cf2702a7c07bb64debbdc9bc7897a672d152 # 58對應(yīng)的master=28,此即為28的id
[OK] All nodes agree about slots configuration.
>>> Check for open slots... # 檢查打開的槽位
>>> Check slots coverage... # 檢查插槽覆蓋范圍
[OK] All 16384 slots covered. # 所有槽位(16384個)分配完成
# 分析以上結(jié)果,可以看到3組master/slave
master:10.0.0.8---slave:10.0.0.38
master:10.0.0.18---slave:10.0.0.48
master:10.0.0.28---slave:10.0.0.58
4 查看主從狀態(tài)
# master=8
[root@CentOS8 ~]#redis-cli -a 123456 -c info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.38,port=6379,state=online,offset=2282,lag=1
master_replid:284b5af60073a1569904dad89cab418d636d918d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2282
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2282
# master=18
[root@centos8 ~]#redis-cli -a 123456 -c info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.48,port=6379,state=online,offset=2338,lag=0
master_replid:d12f0146815127bb80a434cd4a48269cc166dbf1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2338
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2338
# master=28
[root@centos8 ~]#redis-cli -a 123456 -c info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.58,port=6379,state=online,offset=2380,lag=0
master_replid:fb09a9c75fe74e4e98e43333ce61b9dcee8f56e4
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2380
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2380
===============================================================
# slave=48(任取一個)
[root@centos8 ~]#redis-cli -a 123456 -c info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:10.0.0.18
master_port:6379
master_link_status:up
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_repl_offset:2464
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:d12f0146815127bb80a434cd4a48269cc166dbf1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2464
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2464
===============================================================
===============================================================
# 所有[節(jié)點id] 以及node對應(yīng)關(guān)系
[root@centos8 ~]#redis-cli -a 123456 cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
4457771149df7949b7d94cec318f4e783b5e5a18 10.0.0.18:6379@16379 master - 0 1603532399481 2 connected 5461-10922
6061cf2702a7c07bb64debbdc9bc7897a672d152 10.0.0.28:6379@16379 master - 0 1603532398460 3 connected 10923-16383
7a19f3c4082136d3d7c11f6a5c7665e461b2b565 10.0.0.58:6379@16379 slave 6061cf2702a7c07bb64debbdc9bc7897a672d152 0 1603532398000 6 connected
5a469424de6187f662ff825b40b3766fca893325 10.0.0.48:6379@16379 myself,slave 4457771149df7949b7d94cec318f4e783b5e5a18 0 1603532393000 5 connected
bb1c85f4a072be2d8645a40ecef76c358da29f3b 10.0.0.38:6379@16379 slave bfbbb2390cffddbdb6cad159658a4b8770702cd8 0 1603532400500 4 connected
bfbbb2390cffddbdb6cad159658a4b8770702cd8 10.0.0.8:6379@16379 master - 0 1603532400000 1 connected 0-5460
# 查看指定master節(jié)點的slave節(jié)點信息
redis-cli cluster slaves <master-id>
# 使用maste18的id查詢其從節(jié)點48
[root@centos8 ~]#redis-cli -a 123456 cluster slaves 4457771149df7949b7d94cec318f4e783b5e5a18
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
1) "5a469424de6187f662ff825b40b3766fca893325 10.0.0.48:6379@16379 myself,slave 4457771149df7949b7d94cec318f4e783b5e5a18 0 1603532508000 5 connected"
5 驗證集群狀態(tài)
# 集群狀態(tài)總覽
[root@CentOS8 ~]#redis-cli -a 123456 --no-auth-warning CLUSTER INFO
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6 # 總結(jié)點數(shù)
cluster_size:3 # 集群數(shù)(一個主從架構(gòu)就是一個集群)
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:2082
cluster_stats_messages_pong_sent:2042
cluster_stats_messages_sent:4124
cluster_stats_messages_ping_received:2037
cluster_stats_messages_pong_received:2082
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:4124
# 查看指定節(jié)點的集群狀態(tài)
'使用選項 --cluster ,必須小寫
[root@CentOS8 ~]#redis-cli -a 123456 --no-auth-warning --cluster info 10.0.0.58:6379
10.0.0.18:6379 (44577711...) -> 0 keys | 5462 slots | 1 slaves.
10.0.0.28:6379 (6061cf27...) -> 0 keys | 5461 slots | 1 slaves.
10.0.0.8:6379 (bfbbb239...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
6 查看集群node對應(yīng)關(guān)系
# 總覽
redis-cli -a 123456 --no-auth-warning CLUSTER NODES
# 指定任意節(jié)點進行全面檢查
redis-cli -a 123456 --no-auth-warning --cluster check 10.0.0.48:6379
7 驗證集群寫入key
# 寫入key的邏輯原理
1.客戶端發(fā)送命令到任意節(jié)點
2.收到命令的節(jié)點進行定位:計算出槽位得到對應(yīng)節(jié)點,判斷是否指向自身
2.1 指向自身:執(zhí)行
2.2 指向別處:回復(fù)moved。。。然后客戶端重新對正確節(jié)點發(fā)送命令
7.1 redis cluster 寫入key
# 指定節(jié)點8寫入
[root@CentOS8 ~]#redis-cli -a 123456 --no-auth-warning -h 10.0.0.8 SET key1 values1
(error) MOVED 9189 10.0.0.18:6379
'算法根據(jù)key內(nèi)容算出應(yīng)放在 9189 槽位,此槽位不在當(dāng)前節(jié)點,因此失敗
# 指定正確節(jié)點寫入
[root@CentOS8 ~]#redis-cli -a 123456 --no-auth-warning -h 10.0.0.18 SET key1 values1
OK
# 可查看值
[root@CentOS8 ~]#redis-cli -a 123456 --no-auth-warning -h 10.0.0.18 get key1
"values1"
# 與之對應(yīng)的從節(jié)點為48
從節(jié)點只能`keys *`不能`get key`
[root@centos8 ~]#redis-cli -a 123456 --no-auth-warning -h 10.0.0.48 get key1
(error) MOVED 9189 10.0.0.18:6379 '會提示正確位置'
[root@centos8 ~]#redis-cli -a 123456 --no-auth-warning -h 10.0.0.48 keys *
1) "key1"
7.2 redis cluster計算key所有slot
# 計算 xxx 對應(yīng)的slot
redis-cli -h 10.0.0.8 -a 123456 --no-auth-warning cluster keyslot xxx
'注:cluster nodes可查看:3個master分別管轄 0-5461、5462-10922、10923-16383
[root@CentOS8 ~]#redis-cli -h 10.0.0.8 -a 123456 --no-auth-warning cluster keyslot hello
(integer) 866 '若set此key,應(yīng)根據(jù)槽位選擇正確的master節(jié)點,如866在0-5461:選擇8'
[root@CentOS8 ~]#redis-cli -h 10.0.0.8 -a 123456 --no-auth-warning cluster keyslot caokunzi
(integer) 1481
[root@CentOS8 ~]#redis-cli -h 10.0.0.8 -a 123456 --no-auth-warning cluster keyslot zhubazi
(integer) 6488
# 使用選項 -c 以集群模式連接
# 集群模式使用(cluster keyslot xxx)查詢指定key的槽位。。并且可直接set,自動保存在正確節(jié)點?。?!
[root@CentOS8 ~]#redis-cli -c -h 10.0.0.8 -a 123456 --no-auth-warning
10.0.0.8:6379> cluster keyslot linux
(integer) 12299
10.0.0.8:6379> set linux caokunzi
-> Redirected to slot [12299] located at 10.0.0.28:6379
OK
10.0.0.28:6379> get linux
"caokunzi"
# 由12299可知儲存節(jié)點為 master-28
# 使用普通模式查看,必須要在28
[root@CentOS8 ~]#redis-cli -h 10.0.0.28 -a 123456 --no-auth-warning get linux
"caokunzi"
# 反例:
[root@CentOS8 ~]#redis-cli -h 10.0.0.18 -a 123456 --no-auth-warning get linux
(error) MOVED 12299 10.0.0.28:6379
[root@CentOS8 ~]#redis-cli -h 10.0.0.58 -a 123456 --no-auth-warning get linux
(error) MOVED 12299 10.0.0.28:6379
8 python腳本實現(xiàn)RedisCluster集群寫入
# 環(huán)境準備(centos8)
dnf -y install python3
pip3 install redis-py-cluster
# 腳本: vim redis_cluster_test.py
#!/usr/bin/env python3
from rediscluster import RedisCluster
startup_nodes = [
{"host":"10.0.0.8", "port":6379},
{"host":"10.0.0.18", "port":6379},
{"host":"10.0.0.28", "port":6379},
{"host":"10.0.0.38", "port":6379},
{"host":"10.0.0.48", "port":6379},
{"host":"10.0.0.58", "port":6379}
]
redis_conn= RedisCluster(startup_nodes=startup_nodes,password='123456',decode_responses=True)
for i in range(0, 10000):
redis_conn.set('key'+str(i),'value'+str(i))
print('key'+str(i)+':',redis_conn.get('key'+str(i)))
# 權(quán)限
chmod +x redis_cluster_test.py
# 執(zhí)行
./redis_cluster_test.py # 注意: bash 命令用來執(zhí)行shell腳本!這是python腳本
============================================================================
# 檢查數(shù)據(jù)
[root@CentOS8 ~]#redis-cli -a 123456 -h 10.0.0.8 --no-auth-warning
10.0.0.8:6379> DBSIZE
(integer) 3331 # 什么指標????
10.0.0.8:6379> get key1
(error) MOVED 9189 10.0.0.18:6379
10.0.0.8:6379> get key145
"value145"
10.0.0.8:6379> get key777
"value777"
10.0.0.8:6379> get key2828
(error) MOVED 10495 10.0.0.18:6379
[root@centos8 ~]#redis-cli -a 123456 -h 10.0.0.18 --no-auth-warning
10.0.0.18:6379> DBSIZE
(integer) 3340
10.0.0.18:6379> get key1
"value1"
10.0.0.18:6379> get key2828
"value2828"
10.0.0.18:6379> get key9999
(error) MOVED 3339 10.0.0.8:6379
10.0.0.18:6379>
==========================================================================
# 主從一致
[root@centos8 ~]#redis-cli -a 123456 -h 10.0.0.8 --no-auth-warning dbsize
(integer) 3331
[root@centos8 ~]#redis-cli -a 123456 -h 10.0.0.18 --no-auth-warning dbsize
(integer) 3340
[root@centos8 ~]#redis-cli -a 123456 -h 10.0.0.28 --no-auth-warning dbsize
(integer) 3330
[root@centos8 ~]#redis-cli -a 123456 -h 10.0.0.38 --no-auth-warning dbsize
(integer) 3331
[root@centos8 ~]#redis-cli -a 123456 -h 10.0.0.48 --no-auth-warning dbsize
(integer) 3340
[root@centos8 ~]#redis-cli -a 123456 -h 10.0.0.58 --no-auth-warning dbsize
(integer) 3330
9 模擬master故障,對應(yīng)的slave節(jié)點自動提升為新master
# 模擬node2節(jié)點(10.0.0.18)出故障,需要數(shù)秒故障轉(zhuǎn)移時間
===================================================
# 首先在節(jié)點2開啟日志
tail -f /var/log/redis/redis.log
# 登錄node2節(jié)點關(guān)機
[root@centos8 ~]#redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> shutdown
not connected> exit
[root@centos8 ~]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 100 127.0.0.1:25 0.0.0.0:*
LISTEN 0 128 0.0.0.0:111 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 100 [::1]:25 [::]:*
LISTEN 0 128 [::]:111 [::]:*
# 查看集群的主從關(guān)系
[root@CentOS8 ~]#redis-cli -a 123456 --cluster info 10.0.0.8:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Could not connect to Redis at 10.0.0.18:6379: Connection refused
10.0.0.8:6379 (bfbbb239...) -> 3331 keys | 5461 slots | 1 slaves.
10.0.0.48:6379 (5a469424...) -> 3340 keys | 5462 slots | 0 slaves. # 48成為新主
10.0.0.28:6379 (6061cf27...) -> 3330 keys | 5461 slots | 1 slaves.
[OK] 10001 keys in 3 masters.
0.61 keys per slot on average.
# 主從詳細信息
[root@CentOS8 ~]#redis-cli -a 123456 --cluster check 10.0.0.8:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Could not connect to Redis at 10.0.0.18:6379: Connection refused
10.0.0.8:6379 (bfbbb239...) -> 3331 keys | 5461 slots | 1 slaves.
10.0.0.48:6379 (5a469424...) -> 3340 keys | 5462 slots | 0 slaves.
10.0.0.28:6379 (6061cf27...) -> 3330 keys | 5461 slots | 1 slaves.
[OK] 10001 keys in 3 masters.
0.61 keys per slot on average.
>>> Performing Cluster Check (using node 10.0.0.8:6379)
M: bfbbb2390cffddbdb6cad159658a4b8770702cd8 10.0.0.8:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: bb1c85f4a072be2d8645a40ecef76c358da29f3b 10.0.0.38:6379
slots: (0 slots) slave
replicates bfbbb2390cffddbdb6cad159658a4b8770702cd8
M: 5a469424de6187f662ff825b40b3766fca893325 10.0.0.48:6379
slots:[5461-10922] (5462 slots) master
M: 6061cf2702a7c07bb64debbdc9bc7897a672d152 10.0.0.28:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 7a19f3c4082136d3d7c11f6a5c7665e461b2b565 10.0.0.58:6379
slots: (0 slots) slave
replicates 6061cf2702a7c07bb64debbdc9bc7897a672d152
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
# 指定查看 48 的主從關(guān)系
[root@CentOS8 ~]#redis-cli -a 123456 -h 10.0.0.48 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:0
master_replid:230a53c5beda83e2de9550acdc67cddee48c3842
master_replid2:d12f0146815127bb80a434cd4a48269cc166dbf1
master_repl_offset:144009
second_repl_offset:144010
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:144009
==================================
# 恢復(fù)故障節(jié)點node2
systemctl start redis
# 查看日志
18247:S 24 Oct 2020 18:47:18.743 # Cluster state changed: ok
18247:S 24 Oct 2020 18:47:19.761 * Connecting to MASTER 10.0.0.48:6379
18247:S 24 Oct 2020 18:47:19.762 * MASTER <-> REPLICA sync started
18247:S 24 Oct 2020 18:47:19.762 * Non blocking connect for SYNC fired the event.
18247:S 24 Oct 2020 18:47:19.762 * Master replied to PING, replication can continue...
18247:S 24 Oct 2020 18:47:19.763 * Trying a partial resynchronization (request 06e7c1999b779c409e9fce434f5d4a212041a070:1).
18247:S 24 Oct 2020 18:47:19.763 * Full resync from master: 230a53c5beda83e2de9550acdc67cddee48c3842:144009
18247:S 24 Oct 2020 18:47:19.763 * Discarding previously cached master state.
18247:S 24 Oct 2020 18:47:19.857 * MASTER <-> REPLICA sync: receiving 62898 bytes from master
18247:S 24 Oct 2020 18:47:19.857 * MASTER <-> REPLICA sync: Flushing old data
18247:S 24 Oct 2020 18:47:19.858 * MASTER <-> REPLICA sync: Loading DB in memory
18247:S 24 Oct 2020 18:47:19.860 * MASTER <-> REPLICA sync: Finished with success
# 指定查看 48 的主從關(guān)系
[root@CentOS8 ~]#redis-cli -a 123456 -h 10.0.0.48 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.0.18,port=6379,state=online,offset=144093,lag=1 # 18已經(jīng)成為48的從
master_replid:230a53c5beda83e2de9550acdc67cddee48c3842
master_replid2:d12f0146815127bb80a434cd4a48269cc166dbf1
master_repl_offset:144093
second_repl_offset:144010
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:144093