Redis集群介紹
集群里有三大模式:
Redis主從模式:一主一從或一主多從,自帶讀寫分離,負載均衡;
Redis哨兵模式:高可用,主服務器宕機,從服務器變為主服務器;
Redis集群模式(分片):將數據拆分存儲到多個Redis主從集群中。訪問任何一臺服務器都可以查到所有數據。
Redis主從模式
原理:第一次同步時,使用RDB(快照),在同步時,主服務器產生的數據,會記錄偏移量,在同步完成后,進行偏移量的同步。
之后的同步的數據是通過AOF日志方式同步的。
工作機制(了解)
- 當slave啟動后,主動向master發送SYNC命令;
- master接受到SYNC命令后在后臺保存快照(RDB持久化)和緩存保存快照這段時間的命令;
- 然后將保存的快照文件和緩存的命令發送給slave;
- slave收到快照文件和命令后加載快照文件和緩存的執行命令;
- 復制初始化后,master每次收到的寫命令都會同步發送給slave,保證主從數據一致性。
缺點:只有主服務器能寫入數據,從服務器只能讀,主服務器一旦宕機,導致無法寫入數據。
哨兵模式
功能:
- 監控所有Redis服務器,重點監控主服務器,1秒ping一次主,10秒ping一次從;
- 主服務器宕機主觀下線,10秒后未恢復,客觀下線,選舉新的主服務器,根據條件(數據完整性、服務器性能);
- 通知其他從服務器,主從變更,讓其他從服務器鏈接新的主服務器。
多哨兵模式:
·哨兵監控主從的同時,也監控其他哨兵。
·當主宕機,哨兵中選出一個哨兵,這個哨兵再從其他從服務器中選出新的主。
工作機制(了解)
- 每個sentinel以每秒鐘一次的頻率向它所知的master,slave以及其他sentinel實例發送一個 PING 命令
- 如果一個實例距離最后一次有效回復 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個實例會被sentinel標記為主觀下線。
- 如果一個master被標記為主觀下線,則正在監視這個master的所有sentinel要以每秒一次的頻率確認master的確進入了主觀下線狀態
- 當有足夠數量的sentinel(大于等于配置文件指定的值)在指定的時間范圍內確認master的確進入了主觀下線狀態, 則master會被標記為客觀下線
- 在一般情況下, 每個sentinel會以每 10 秒一次的頻率向它已知的所有master,slave發送 INFO 命令
- 當master被sentinel標記為客觀下線時,sentinel向下線的master的所有slave發送 INFO 命令的頻率會從 10 秒一次改為 1 秒一次
- 若沒有足夠數量的sentinel同意master已經下線,master的客觀下線狀態就會被移除;
- 若master重新向sentinel的 PING 命令返回有效回復,master的主觀下線狀態就會被移除
Redis集群模式
集群=哨兵+主從+分片,實現高擴展性
集群模式特點
多個redis節點網絡互聯,數據共享
支持在線增加、刪除節點
客戶端可以連接任何一個主節點進行讀寫
優點:
- 多個redis節點網絡互聯,數據共享;
- 所有的節點都是一主一從(也可以是一主多從),其中從不提供服務,僅作為備用;
- 支持在線增加、刪除節點;
- 客戶端可以連接任何一個主節點進行讀寫;
缺點:
- 不支持同時處理多個key(如MSET/MGET),因為redis需要把key均勻分布在各個節點上;
- 并發量很高的情況下同時創建key-value會降低性能并導致不可預測的行為。
集群工作方式
哈希槽:默認Redis官方在Redis集群模式中內置了16384個槽
插槽的取值范圍是:0-16383。cluster,可以理解為是一個集群管理的插件。
當我們的存取 Key的時候,Redis 會根據算法得出一個結果,然后把結果對 16384 求余數,這樣每個 key 都會對應一個編號在 0-16383 之間的哈希槽,通過這個值,去找到對應的插槽所對應的節點,然后直接自動跳轉到這個對應的節點上進行存取操作。
1 % 16384 = 1
Redis重定向:在Redis集群任意節點查詢或存儲修改數據時,通過哈希槽運算,未命中節點,則會重新計算查找節點。
集群模式的搭建???(單機多實例)
- 第一步:創建一個文件夾redis-cluster,然后在其下面分別創建6個文件夾如下:
[root@localhost ~]# cd /usr/local/redis
[root@localhost redis]# ls
bin ?data ?etc ?logs ?redis.pid
[root@localhost redis]# mkdir redis-cluster
[root@localhost redis]# cd redis-cluster/
[root@localhost redis-cluster]# mkdir 700{1..6}
[root@localhost redis-cluster]# ls
7001 ?7002 ?7003 ?7004 ?7005 ?7006
- 第二步:把之前的redis.conf配置文件分別copy到700*下
# 返回redis目錄里
cd ../
[root@localhost redis]# cp ./etc/redis.conf ./redis-cluster/7001/redis.conf
[root@localhost redis]# cp ./etc/redis.conf ./redis-cluster/7002/redis.conf
[root@localhost redis]# cp ./etc/redis.conf ./redis-cluster/7003/redis.conf
[root@localhost redis]# cp ./etc/redis.conf ./redis-cluster/7004/redis.conf
[root@localhost redis]# cp ./etc/redis.conf ./redis-cluster/7005/redis.conf
[root@localhost redis-cluster]# cp ../etc/redis.conf 7006
[root@localhost redis-cluster]# tree
- 第三步:修改集群配置
[root@zuolaoshi redis]# vim ./redis-cluster/7001/redis.conf
以下是全部修改內容:
bind 192.168.221.129
port 7001
pidfile /usr/local/redis/redis-cluster/7001/redis.pid
logfile "/usr/local/redis/logs/redis-7001.log"
dir /usr/local/redis/redis-cluster/7001/
appendonly yes
cluster-enabled yes
cluster-config-file nodes7001.conf
cluster-node-timeout 5000
# 切換到cluster比較方便
[root@localhost redis]# cd redis-cluster/
# 刷新一下7001的配置文件
[root@localhost redis-cluster]# redis-server 7001/redis.conf?
# 查看是否開啟
[root@localhost redis-cluster]# netstat -lnutp | grep 7001
#會出現
tcp ???????0 ?????0 192.168.221.129:17001????0.0.0.0:* ??????????????LISTEN ?????66164/redis-server ?
tcp ???????0 ?????0 192.168.221.129:7001?????0.0.0.0:* ??????????????LISTEN ?????66164/redis-server ?
tcp6 ??????0 ?????0 ::1:17001???????????????:::* ???????????????????LISTEN ?????66164/redis-server ?
tcp6 ??????0 ?????0 ::1:7001????????????????:::* ???????????????????LISTEN ?????66164/redis-server
# 把修改好的配置文件覆蓋到7002到7006的配置文件上
[root@localhost redis-cluster]# cp 7001/redis.conf 7002/redis.conf
cp:是否覆蓋"7002/redis.conf"? y
# 修改每一個配置文件(五個文件都重復這個步驟)
[root@localhost redis-cluster]# vim 7002/redis.conf
:%s/7001/7002/g
[root@localhost redis-cluster]# redis-server 7002/redis.conf?
[root@localhost redis-cluster]# netstat -lnutp | grep 7002
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
中途換成Ubuntu,安裝了Redis,互傳了redis-cluster目錄,改了IP,別的都沒有變,建議下次直接使用Ubuntu:
scp -r root@192.168.221.10:/usr/local/redis/redis-cluster /usr/local/redis/
先進入/usr/local/redis目錄里
cd /usr/local/redis/
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# 安裝ruby
apt install ruby??????????????????Y
gem install redis
# 創建集群
root@cqh-virtual-machine:/usr/local/redis# ./bin/redis-cli --cluster create 192.168.221.129:7001 192.168.221.129:7002 192.168.221.129:7003 192.168.221.129:7004 192.168.221.129:7005 192.168.221.129:7006 --cluster-replicas 1
出現
最后出現綠色OK就成功了
# 查看Redis服務狀態
ps -ef?|?grep redis
# 進入7001端口
root@cqh-virtual-machine:/usr/local/redis# ./bin/redis-cli -c -h 192.168.221.129 -p 7001
192.168.221.129:7001> info cluster
# Cluster
cluster_enabled:1 ??????#節點是否為cluster模式,1是0否
# 測試操作
192.168.221.129:7001> exit
root@cqh-virtual-machine:/usr/local/redis# ./bin/redis-cli -c -h 192.168.221.129 -p 7005
192.168.221.129:7005> set b fdfsfsd
-> Redirected to slot [3300] located at 192.168.221.129:7001
OK
192.168.221.129:7001> get b
"fdfsfsd"
192.168.221.129:7001> set c fdsfdfdsfds
-> Redirected to slot [7365] located at 192.168.221.129:7002
OK
192.168.221.129:7002> get c
"fdsfdfdsfds"
192.168.221.129:7002> set x fdsfdsfsdf
-> Redirected to slot [16287] located at 192.168.221.129:7003
OK
192.168.221.129:7003> keys *
1) "x"
192.168.221.129:7003> get b
-> Redirected to slot [3300] located at 192.168.221.129:7001
"fdfsfsd"
192.168.221.129:7001> keys *
1) "b"
192.168.221.129:7001> set d fdsfdsfsd
-> Redirected to slot [11298] located at 192.168.221.129:7003
OK
192.168.221.129:7003> get d
"fdsfdsfsd"
192.168.221.129:7003> set x zhangsan
OK
192.168.221.129:7003> get x
"zhangsan"
192.168.221.129:7003> exit
實驗:一主兩從三哨兵???
一、安裝好Redis
192.168.221.20 Redis(主)
192.168.221.30 Redis(從)
192.168.221.40 Redis(從)
安裝Redis
二、多機主從配置一主二從
2.1、準備工作
開啟三臺虛擬主機20、30、40,分別安裝redis
檢查防火墻、掛載光盤
systemctl status firewalld
mount /dev/cdrom /media
2.2、配置主機和從機
# 修改配置文件redis.conf
vim /usr/local/redis/etc/redis.conf
主機配置
bind 0.0.0.0??????#將bind127.0.0.1注釋掉 或者改成?bind 0.0.0.0
port 6379????????#改變其服務端口為6379
daemonize yes ??#修改服務為后臺運行
#指定不同的pid文件,注意三份配置文件不同。
pidfile /usr/local/redis/redis.pid
#指定log日志路徑,自己配,要求不同。
logfile "/usr/local/redis/logs/redis.log" ?
#這個指定rdb文件和aof文件的路徑配置,要求改成不同。
dir /usr/local/redis/data
# 密碼設置
masterauth 123??#從服務到主服務的認證密碼(三臺都配置)
requirepass 123 ?#客戶端訪問需要密碼驗證(三臺都配置)
從機配置
#主服務這句話注釋,從服務配置的兩臺需要開啟。配置主服務的ip的port。
replicaof 192.168.221.20 6379
2.3、啟動服務
分別啟動三臺主機的redis服務器端服務
./bin/redis-server ./etc/redis.conf
ps -ef|grep redis
分別啟動三臺主機客戶端服務
./bin/redis-cli
# 查看主從的從屬信息
127.0.0.1:6379> info replication
# 如果從服務器沒有變成從服務,就手動設置從屬
127.0.0.1:6379> slaveof 192.168.221.20 6379
# 關閉從屬功能
127.0.0.1:6379> slaveof no one
# 轉而對新服務器進行同步
127.0.0.1:6379> slaveof host port(比如:slaveof 192.168.221.30 6379)
三、設置單哨兵(在主服務器上)
# 備份配置文件
[root@localhost /]#cp /usr/local/src/redis-6.2.14/sentinel.conf?/usr/local/redis/etc/sentinel.conf
# 進入etc目錄
[root@localhost /]#cd /usr/local/redis/etc/
# 排除哨兵配置文件里的注釋信息(如果沒注釋大約在第84行)
[root@localhost etc]#grep -Ev "^$|^#" /usr/local/src/redis-6.2.14/sentinel.conf > /etc/redis/sentinel.conf
# 編輯哨兵配置文件
[root@localhost etc#vim sentinel.conf
++++++++++++++++++++++++++++++++
pidfile "/var/run/redis-sentinel.pid"
logfile "/usr/local/redis/logs/sentinel.log"
dir "/usr/local/redis/data"
sentinel monitor mymaster 192.168.221.20 6379 1????# mymaster是監控主數據的名稱,命名時可以使用大小寫字母和“.-_”符號;后面是主機IP、端口號和哨兵的數量,少數服從多數的命令
sentinel down-after-milliseconds mymaster 10000
sentinel failover-timeout mymaster 15000
++++++++++++++++++++++++++++++++
# 返回到redis目錄里
[root@localhost etc]# cd ../
# 啟動哨兵實時查看情況
[root@localhost redis]# ./bin/redis-sentinel ./etc/sentinel.conf??或者 ?./bin/redis-server ./etc/sentinel.conf --sentinel
從機宕機
[[root@localhost bin]#?cd
[root@localhost ~]# /etc/init.d/redis stop
Stopping Redis...
Redis stopped.
# 哨兵認為主觀宕機
[root@localhost ~]#?/etc/init.d/redis start
Starting Redis...
Redis started.
# 哨兵取消主觀宕機,檢測到192.168.221.30重啟/恢復上線
# 192.168.221.30重新同步為從節點
主機宕機
[root@localhost redis]# cd
[root@localhost ~]# /etc/init.d/redis stop
Stopping Redis...
Redis stopped.
# 哨兵主觀+客觀宕機
(達到法定票數,這里quorum 1/1表示1個哨兵同意即可)
# 進入新的 “紀元”(類似選舉輪次),保障故障轉移流程有序
# 嘗試執行故障轉移,選主從節點重新掛載
# 哨兵集群選舉出“主導哨兵”,由它主導后續故障轉移操作
# 把一個從節點選為新的主節點
# 其他從節點重新掛載新的主節點
# 測試哨兵連接
redis-cli -p 26379 sentinel masters
# 通過哨兵獲取當前主節點的IP和端口
redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
四、多哨兵連接(一主兩從都配置)
# 接單哨兵結尾的192.168.221.40變為主節點開始:
# 修改主節點配置文件:
vim /etc/redis/redis.conf
++++++++++++++++++++++++++++++++++++++++++++++++++
bind 0.0.0.0
protected no ????????# 關閉加密保護 否則從節點無法連接
daemonize yes ???????# 開啟后臺模式將no改為yes
timeout 300 # 連接超時時間
port 6379 ???????????# 端口號
logfile "/usr/local/redis/logs/redis.log" ????# 存放日志
pidfile /usr/local/redis/redis.pid ??????????# 定義pid文件
dbfilename dump.rdb
dir /usr/local/redis/data ?????????????????# 用于存放數據(目錄需提前創建)
save 3600 1
save 300 100
save 60 10000 ?????????????????????????# snapshot觸發的時機
stop-writes-on-bgsave-error yes ?????????# 當snapshot時出現錯誤無法繼續時,阻塞客戶端“變更操作”,“錯誤”可能因為磁盤已滿/磁盤故障/OS級別異常等
rdbcompression yes ????????????????????# 啟用rdb文件壓縮,默認為“yes”,壓縮往往意味著“額外的cpu消耗”,同時也意味這較小的文件尺寸以及較短的網絡傳輸時間
appendonly yes ????????????????????????# 開啟aof功能,只有在“yes”下,aof重寫/文件同步等特性才會生效
++++++++++++++++++++++++++++++++++++++++++++++++++
# 修改從節點配置文件:
vim /etc/redis/redis.conf
+++++++++++++++++++++++++++++++++
replicaof 192.168.221.40?6379 ????##添加 master IP和端口(注意:老版本的redis是搜索 slaveof 有些許區別)
+++++++++++++++++++++++++++++++++
啟動測試
測試
##-->master節點操作
/etc/init.d/redis restart
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set name jack
OK
127.0.0.1:6379> get name
"jack"
##查看連接狀態
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2 ?##兩個從節點
slave0:ip=192.168.8.12,port=6379,state=online,offset=6535,lag=0
slave1:ip=192.168.8.13,port=6379,state=online,offset=6535,lag=0
##-->從節點操作
/etc/init.d/redis restart
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> get name
"jack"
##查看連接狀態
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.221.40
master_port:6379
master_link_status:up
# 排除哨兵配置文件里的注釋信息并把它生成一個新文件(如果不注釋,大約在第84行,需要提前備份一個新的配置文件cp /usr/local/src/redis-6.2.14/sentinel.conf?/usr/local/redis/sentinel.conf)
[root@localhost ~]#grep -Ev "^$|^#" /usr/local/src/redis-6.2.14/sentinel.conf > /usr/local/redis/sentinel.conf
# 編輯哨兵配置文件
[root@localhost ~]#vim /usr/local/redis/sentinel.conf
++++++++++++++++++++++++++++++++++++++++++++++++++
port 26379
protected-mode no
daemonize yes
pidfile /var/run/redis-sentinel.pid
logfile "/usr/local/redis/logs/sentinel.log"
dir /tmp
sentinel monitor mymaster 192.168.221.40 6379 2
sentinel down-after-milliseconds mymaster 30000
acllog-max-len 128
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
SENTINEL resolve-hostnames no
SENTINEL announce-hostnames no
++++++++++++++++++++++++++++++++++++++++++++++++++
保存退出
# 將配置文件發送到另外兩臺服務器
scp /usr/local/redis/sentinel.conf 192.168.221.20:/usr/local/redis/
yes
輸入20的密碼
scp /usr/local/redis/sentinel.conf 192.168.221.30:/usr/local/redis/
yes
輸入30的密碼
# 如需查看是否一致,可以在另外兩臺輸入
cat /usr/local/redis/sentinel.conf???一致則說明發送成功
# 啟動測試(三臺機器均啟動)
##?啟動哨兵
cd /usr/local/redis/
redis-sentinel sentinel.conf
##?動態查看
tail -f /usr/local/redis/logs/sentinel.log
Ctrl+C退出
##主節點
[root@localhost redis]#?redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.221.20,port=6379,state=online,offset=547559,lag=0
slave1:ip=192.168.221.30,port=6379,state=online,offset=547559,lag=0
##?停止主節點redis(后面要有耐心,多等待一會兒)
127.0.0.1:6379> exit
[root@redis-master redis]# netstat -tnlp
# 會出現
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address ??????????Foreign Address ????????State ??????PID/Program name ???
tcp ???????0 ?????0 0.0.0.0:26379 ??????????0.0.0.0:* ??????????????LISTEN ?????15630/redis-sentine
tcp ???????0 ?????0 0.0.0.0:6379 ???????????0.0.0.0:* ??????????????LISTEN ?????14351/redis-server ?
tcp ???????0 ?????0 0.0.0.0:111 ????????????0.0.0.0:* ??????????????LISTEN ?????743/rpcbind ????????
tcp ???????0 ?????0 0.0.0.0:6032 ???????????0.0.0.0:* ??????????????LISTEN ?????1562/proxysql ??????
tcp ???????0 ?????0 0.0.0.0:6033 ???????????0.0.0.0:* ??????????????LISTEN ?????1562/proxysql ??????
tcp ???????0 ?????0 192.168.122.1:53 ???????0.0.0.0:* ??????????????LISTEN ?????1698/dnsmasq ???????
tcp ???????0 ?????0 0.0.0.0:22 ?????????????0.0.0.0:* ??????????????LISTEN ?????1116/sshd ??????????
tcp ???????0 ?????0 127.0.0.1:631 ??????????0.0.0.0:* ??????????????LISTEN ?????1119/cupsd ?????????
tcp ???????0 ?????0 127.0.0.1:25 ???????????0.0.0.0:* ??????????????LISTEN ?????1622/master ????????
tcp ???????0 ?????0 127.0.0.1:6010 ?????????0.0.0.0:* ??????????????LISTEN ?????13696/sshd: root@pt
tcp ???????0 ?????0 127.0.0.1:6011 ?????????0.0.0.0:* ??????????????LISTEN ?????15015/sshd: root@pt
tcp6 ??????0 ?????0 :::26379 ???????????????:::* ???????????????????LISTEN ?????15630/redis-sentine
tcp6 ??????0 ?????0 ::1:6379 ???????????????:::* ???????????????????LISTEN ?????14351/redis-server ?
tcp6 ??????0 ?????0 :::111 ?????????????????:::* ???????????????????LISTEN ?????743/rpcbind ????????
tcp6 ??????0 ?????0 :::22 ??????????????????:::* ???????????????????LISTEN ?????1116/sshd ??????????
tcp6 ??????0 ?????0 ::1:631 ????????????????:::* ???????????????????LISTEN ?????1119/cupsd ?????????
tcp6 ??????0 ?????0 ::1:25 ?????????????????:::* ???????????????????LISTEN ?????1622/master ????????
tcp6 ??????0 ?????0 ::1:6010 ???????????????:::* ???????????????????LISTEN ?????13696/sshd: root@pt
tcp6 ??????0 ?????0 ::1:6011 ???????????????:::* ???????????????????LISTEN ?????15015/sshd: root@pt
tcp6 ??????0 ?????0 :::33060 ???????????????:::* ???????????????????LISTEN ?????1595/mysqld ????????
tcp6 ??????0 ?????0 :::3306 ????????????????:::* ???????????????????LISTEN ?????1595/mysqld ????????
[root@localhost redis]# kill 14351
##--新的主節點機器192.168.221.30(到時候兩臺都登陸)
127.0.0.1:6379>?redis-cli
127.0.0.1:6379> info replication
# 出現下面這個說明正在轉換身份
Error: Server closed the connection
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.221.20,port=6379,state=online,offset=738791,lag=1
##已實現故障轉移
##--啟動故障機器192.168.221.40
[root@localhost redis]# /etc/init.d/redis start
[root@localhost redis]# redis-cli
127.0.0.1:6379>?info replication
# Replication
role:slave
master_host:192.168.221.30
master_port:6379
master_link_status:up?????#恢復的機器會自動加入集群降為從節點