目錄
一? 利用docker搭建環境
板書:
一)準備?作:
板書:
解讀docker配置文件:
1)安裝docker和docker-compose
?2) 停?之前的redis-server
?3) 使?docker獲取redis鏡像
二)編排redis主從節點
板書:?編輯
1) 編寫docker-compose.yml
2) 啟動所有容器
3) 查看運??志
4) 驗證
三)編排 redis-sentinel節點
板書:
1) 編寫 docker-compose.yml
?2) 創建配置?件
?3) 啟動所有容器
?4) 查看運??志
5) 觀察redis-sentinel 的配置rewrite
二? 哨兵自動選舉詳解
自動選舉的全部板書:
1)手動操作觀察重新選舉
2)選舉原理
1) 主觀下線
2) 客觀下線
?3) 選舉出哨兵的leader
?4) leader 挑選出合適的slave成為新的 master
三? 總結
一? 利用docker搭建環境
板書:
一)準備?作:
板書:
解讀docker配置文件:
?
1)安裝docker和docker-compose
關于docker的安裝請點擊鏈接看docker專欄
docker-compose安裝
# ubuntuapt install docker-compose# centosyum install docker-compose
?2) 停?之前的redis-server
# 停?redis-server
service redis-server stop
# 停?redis-sentinel 如果已經有的話
service redis-sentinel stop
?3) 使?docker獲取redis鏡像
docker pull redis:5.0.9
二)編排redis主從節點
復制粘貼的格式可能不對,需要正確格式的私聊我
板書:

1) 編寫docker-compose.yml
創建 /root/redis/docker-compose.yml?,同時cd到yml所在?錄中.
注意:docker中可以通過容器名字,作為ip地址,進?相互之間的訪問
version: '3.7'services:master:image: 'redis:5.0.9'container_name: redis-masterrestart: alwayscommand: redis-server --appendonly yesports: - 6379:6379slave1:image: 'redis:5.0.9'container_name: redis-slave1restart: alwayscommand: redis-server --appendonly yes --slaveof redis-master 6379ports:- 6380:6379slave2:image: 'redis:5.0.9'container_name: redis-slave2restart: alwayscommand: redis-server --appendonly yes --slaveof redis-master 6379ports:- 6381:6379
2) 啟動所有容器
docker-compose up -d
如果啟動后發現前?的配置有誤,需要重新操作,使? docker-compose down 即可停?并刪除剛才創建好的容器.
3) 查看運??志
docker-compose logs
上 述操作必須保證?作?錄在yml的同級?錄中,才能?作
4) 驗證
連接主節點??redis-cli -p 6379
127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:2slave0:ip=172.22.0.3,port=6379,state=online,offset=348,lag=1slave1:ip=172.22.0.4,port=6379,state=online,offset=348,lag=1master_replid:a22196b425ab42ddfd222cc5a64d53acffeb3e63master_replid2:0000000000000000000000000000000000000000master_repl_offset:348second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:348
連接從節點??redis-cli -p 6380
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:redis-master
master_port:6379
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_repl_offset:446
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:a22196b425ab42ddfd222cc5a64d53acffeb3e63
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:446
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:446
連接從節點??redis-cli -p 6381
127.0.0.1:6381> info replication# Replicationrole:slavemaster_host:redis-mastermaster_port:6379master_link_status:upmaster_last_io_seconds_ago:7master_sync_in_progress:0slave_repl_offset:516slave_priority:100slave_read_only:1connected_slaves:0master_replid:a22196b425ab42ddfd222cc5a64d53acffeb3e63master_replid2:0000000000000000000000000000000000000000master_repl_offset:516second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:1repl_backlog_histlen:516
三)編排 redis-sentinel節點
復制粘貼的格式可能不對,需要正確格式的私聊我
板書:
也可以把redis-sentinel放到和上?的redis的同?個yml中進?容器編排.此處分成兩組,主要是為
了兩??:
- 觀察?志?便
- 確保redis主從節點啟動之后才啟動redis-sentinel.如果先啟動redis-sentinel的話,可能觸發額 外的選舉過程,混淆視聽.(不是說先啟動哨兵不?,?是觀察的結果可能存在?定隨機性).
1) 編寫 docker-compose.yml
創建 /root/redis-sentinel/docker-compose.yml?,同時cd到yml所在?錄中.
注意:每個?錄中只能存在?個docker-compose.yml?件.
version: '3.7'
services:sentinel1:image: 'redis:5.0.9'container_name: redis-sentinel-1restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel1.conf:/etc/redis/sentinel.confports:- 26379:26379
sentinel2:image: 'redis:5.0.9'container_name: redis-sentinel-2restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel2.conf:/etc/redis/sentinel.confports:- 26380:26379
sentinel3:image: 'redis:5.0.9'container_name: redis-sentinel-3restart: alwayscommand: redis-sentinel /etc/redis/sentinel.confvolumes:- ./sentinel3.conf:/etc/redis/sentinel.confports:- 26381:26379
networks:default:external:name: redis-data_default
?2) 創建配置?件
創建?sentinel1.conf?sentinel2.conf?sentinel3.conf 三份文件的內容是完全相同的,都放到 /root/redis-sentinel/ ?錄中.
bind 0.0.0.0
port 26379
sentinel monitor redis-master redis-master 6379 2
sentinel down-after-milliseconds redis-master 1000
理解 sentinel monitor
sentinel monitor 主節點名 主節點 ip 主節點端? 法定票數
參數解釋:
- 主節點名,這個是哨兵內部??起的名字
- 主節點ip,部署redis-master的設備ip.此處由于是使?docker,可以直接寫docker的容器名,會被?動DNS成對應的容器ip
- 主節點端?,不解釋.
- 法定票數,哨兵需要判定主節點是否掛了.但是有的時候可能因為特殊情況,?如主節點仍然?作正常,但是哨兵節點???絡出問題了,?法訪問到主節點了.此時就可能會使該哨兵節點認為主節點下線,出現誤判.使?投票的?式來確定主節點是否真的掛了是更穩妥的做法.需要多個哨兵都認為主節點掛了,票數>=法定票數之后,才會真的認為主節點是掛了.
理解 sentinel down-after-milliseconds
主節點和哨兵之間通過?跳包來進?溝通.如果?跳包在指定的時間內還沒回來,就視為是節點出現 故障.
既然內容相同,為啥要創建多份配置?件?
redis-sentinel 在運?中可能會對配置進?rewrite,修改?件內容.如果??份?件,就可能出現修改混亂的情況.
?3) 啟動所有容器
docker-compose up -d
如果啟動后發現前?的配置有誤,需要重新操作,使? docker-compose down 剛才創建好的容器.
?4) 查看運??志
docker-compose logs
上述操作必須保證?作?錄在yml的同級?錄中,才能?作.
可以看到,哨兵節點已經通過主節點,認識到了對應的從節點.
5) 觀察redis-sentinel 的配置rewrite
再次打開哨兵的配置?件,發現?件內容已經被?動修改了.
bind 0.0.0.0port 26379sentinel myid 4d2d562860b4cdd478e56494a01e5c787246b6aasentinel deny-scripts-reconfig yes# Generated by CONFIG REWRITEdir "/data"sentinel monitor redis-master 172.22.0.4 6379 2sentinel down-after-milliseconds redis-master 1000sentinel config-epoch redis-master 1sentinel leader-epoch redis-master 1sentinel known-replica redis-master 172.22.0.2 6379sentinel known-replica redis-master 172.22.0.3 6379sentinel known-sentinel redis-master 172.22.0.7 26379 f718caed536d178f5ea6d1316d09407cfae43dd2sentinel known-sentinel redis-master 172.22.0.5 26379 2ab6de82279bb77f8397c309d36238f51273e80asentinel current-epoch 1
# Generated by CONFIG REWRITE 這?的內容就是?動修改的
對?這三份?件,可以看到配置內容是存在差異的
二? 哨兵自動選舉詳解
自動選舉的全部板書:
1)手動操作觀察重新選舉
redis-master 宕機之后
?動把 redis-master??掉
1 docker stop redis-master
觀察哨兵的?志
可以看到哨兵發現了主節點sdown,進?步的由于主節點宕機得票達到 master 被判定為odown.
- 主觀下線(SubjectivelyDown,SDown):哨兵感知到主節點沒?跳了.判定為主觀下線
- 客觀下線(ObjectivelyDown,ODown):多個哨兵達成?致意?,才能認為master確實下線了.
接下來,哨兵們挑選出了?個新的master.在上圖中,是172.22.04:6379?這個節點.
此時,對于Redis來說仍然是可以正常使?的.
redis-master 重啟之后
?動把 redis-master?啟動起來
1 docker start redis-master
觀察哨兵?志可以看到剛才新啟動的redis-master?被當成了slave
使?redis-cli 也可以進?步的驗證這?點
127.0.0.1:6379> info replication# Replicationrole:slavemaster_host:172.22.0.4master_port:6379master_link_status:upmaster_last_io_seconds_ago:0master_sync_in_progress:0slave_repl_offset:324475slave_priority:100slave_read_only:1connected_slaves:0master_replid:ececc285a2892fba157318c77ebe1409f9c2254emaster_replid2:0000000000000000000000000000000000000000master_repl_offset:324475second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:318295repl_backlog_histlen:6181
結論
- ?Redis主節點如果宕機,哨兵會把其中的?個從節點,提拔成主節點.
- 當之前的Redis主節點重啟之后,這個主節點被加?到哨兵的監控中,但是只會被作為從節點使?
2)選舉原理
假定當前環境如上?介紹,三個哨兵(sentenal1,sentenal2,sentenal3),?個主節點(redis-master),兩
個從節點(redis-slave1,redis-slave2).?
當主節點出現故障,就會觸發重新?系列過程.
1) 主觀下線
當redis-master 宕機,此時redis-master和三個哨兵之間的?跳包就沒有了.
此時,站在三個哨兵的?度來看,redis-master出現嚴重故障.因此三個哨兵均會把redis-master判定
為主觀下線(SDown)
2) 客觀下線
此時,哨兵sentenal1,sentenal2,sentenal3均會對主節點故障這件事情進?投票.當故障得票數>=配
置的法定票數之后,
sentinel monitor redis-master 172.22.0.4 6379 2
?3) 選舉出哨兵的leader
接下來需要哨兵把剩余的slave中挑選出?個新的master.這個?作不需要所有的哨兵都參與.只需要選出個代表(稱為leader),由leader負責進?slave升級到master的提拔過程.這個選舉的過程涉及到 Raft?算法
假定一共三個哨兵結點 S1 S2 S3
1. 每個哨兵節點都給其他所有哨兵節點,發起?個"拉票請求".(S1->S2,S1->S3,S2->S1,S2->S3,S3->S1,S3->S2)
2. 收到拉票請求的節點,會回復?個"投票響應".響應的結果有兩種可能,投or不投.
?????????如S1給S2發了個投票請求,S2就會給S1返回投票響應.
????????到底S2是否要投S1呢?取決于S2是否給別?投過票了.(每個哨兵只有?票).
????????如果S2沒有給別?投過票,換??之,S1是第?個向S2拉票的,那么S2就會投S1.否則則不投.3. ?輪投票完成之后,發現得票超過半數的節點,?動成為leader0.
????????如果出現平票的情況(S1投S2,S2投S3,S3投S1,每??票),就重新再投?次即可. 這也是為啥建議哨兵節點設置成奇數個的原因.如果是偶數個,則增?了平票的概率,帶來不必要的開銷.
?4. leader 節點負責挑選?個slave成為新的master.當其他的sentenal發現新的master出現了,就說明選舉結束了.
簡??之,Raft算法的核?就是"先下?為強".誰率先發出了拉票請求,誰就有更?的概率成為leader
這?的決定因素成了"?絡延時".?絡延時本?就帶有?定隨機性
具體選出的哪個節點是leader,這個不重要,重要的是能選出?個節點即可.????????
?4) leader 挑選出合適的slave成為新的 master
挑選規則:
?1. ?較優先級.優先級?(數值?的)的上位.優先級是配置?件中的配置項(slave-priority)或者(replica-priority)
2. ?較 replication offset 誰復制的數據多,?的上位.
3. ?較run id?,誰的id?,誰上位.
當某個slave節點被指定為master之后,
1. leader 指定該節點執?slave no one?,成為master
2. leader 指定剩余的slave節點,都依附于這個新master
三? 總結
上述過程,都是"??值守",Redis?動完成的.這樣做就解決了主節點宕機之后需要???預的問題,
提?了系統的穩定性和可?性.
?些注意事項:
- ?哨兵節點不能只有?個.否則哨兵節點掛了也會影響系統可?性.
- ?哨兵節點最好是奇數個.?便選舉leader,得票更容易超過半數.
- ?哨兵節點不負責存儲數據.仍然是redis主從節點負責存儲.
- ?哨兵+主從復制解決的問題是"提?可?性",不能解決"數據極端情況下寫丟失"的問題
- ?哨兵+主從復制不能提?數據的存儲容量.當我們需要存的數據接近或者超過機器的物理內存,這樣的結構就難以勝任了.
為了能存儲更多的數據,就引?了集群.