一、高並發機制
我們知道redis是基於單一執行緒的,在單機模式下能承載的也就幾萬左右吧,所以怎麼提高其在大數據下幾十萬的高並發請求,透過redis的主從架構和讀寫分離。
影片課程推薦→:《千萬資料並發解決方案(理論實戰)》
1.主從複製
redis主從複製的配置就不強調,主要看主從複製的原理及過程:在進行redis的主從複製的過程中,需要一台master主機作為管理員,去搭建多台slave從機。當slave從機試圖啟動時會向master主機發送一個命令PSYNC,如果這個時候slave從機是重新連接的,那麼會從master主機上把slave從機沒有的資料複製過去,如果是第一次連接那麼會觸發full resynchronization。觸發以後master主機會在後台開啟一個進程去產生一個RDB快照文件,同時將這個時間段的寫入操作存入緩存,當這個RDB文件生成完畢之後會向slave從機發送RDB文件,從機拿到文件之後先寫入磁碟然後載入進入記憶體最後master主機會將快取在記憶體裡面的資料也同時傳送給從機。如果在發生主從的網路故障的情況下,有多個slave從機重新連接那麼master只會重啟一份RDB去服務全部slave。 【相關推薦:Redis影片教學】
斷點續傳:在master和slave裡面都有一個replica offset裡面還有一個master id ,其中offset就是保持在backlog,當主從機發生網路故障重連時,會去找到對應的上次replica offset的地方進行複製,如果沒有找到對應的offset那麼觸發full resynchronization。
①複製的完整流程
(1)slave node啟動,只儲存master node的信息,包括master node的host和ip,但複製流程沒開始
# master host和ip是從哪裡來的,redis.conf裡面的slaveof配置的
(2)slave node內部有個定時任務,每秒檢查是否有新的master node要連接和復制,如果發現,就跟master node建立socket網路連線
(3)slave node發送ping指令給master node
(4)口令認證,如果master設定了requirepass,那麼salve node必須傳送masterauth的口令過去進行認證
(5)master node第一次執行全量複製,將所有資料發給slave node
(6)master node後續持續將寫入指令,非同步複製給slave node
②資料同步相關的核心機制
指的就是第一次slave連接msater的時候,執行的全量複製,那個過程裡面你的一些細節的機制
(1)master和slave都會維護一個offset
master會在自身不斷累加offset,slave也會在自身不斷累加offset
slave每秒都會上報自己的offset給master,同時master也會保存每個slave的offset
這個倒不是說特定就用在全量複製的,主要是master和slave都要知道各自的數據的offset,才能知道互相之間的數據不一致的情況
(2)backlog
master node有一個backlog,預設是1MB大小
master node給slave node複製資料時,也會將資料在backlog中同步寫一份
backlog主要是用來做全量複製中斷候的增量複製的
(3)master run id
info server,可以看到master run id
如果根據host ip定位master node,是不靠譜的,如果master node重啟或資料出現了變化,那麼slave node應該根據不同的run id區分,run id不同就做全量複製
如果需要不更改run id重啟redis,可以使用redis-cli debug reload指令
(4)psync
從節點使用psync從master node複製,psync runid offset
master node會根據自身的情況回傳回應訊息,可能是FULLRESYNC runid offset觸發全量複製,可能是CONTINUE觸發增量複製
③全量複製
(1)master執行bgsave,在本地產生一份rdb快照檔案
(2)master node將rdb快照檔案傳送給salve node,如果rdb複製時間超過60秒(repl-timeout),那麼slave node會認為複製失敗,可以適當調節大這個參數
(3)對於千兆網卡的機器,一般每秒傳輸100MB,6G文件,很可能超過60s
(4)master node在生成rdb時,會將所有新的寫入指令快取在記憶體中,在salve node儲存了rdb之後,再將新的寫入指令複製給salve node
(5)client-output-buffer-limit slave 256MB 64MB 60,如果在複製期間,記憶體緩衝區持續消耗超過64MB,或一次性超過256MB,那麼停止複製,複製失敗
(6)slave node接收到rdb之後,清空自己的舊數據,然後重新載入rdb到自己的記憶體中,同時基於舊的資料版本對外提供服務
(7)如果slave node開啟了AOF,那麼會立即執行BGREWRITEAOF,重寫AOF
rdb產生、rdb透過網路拷貝、slave舊資料的清理、slave aof rewrite,很耗費時間
如果複製的資料量在4G~6G之間,那麼很可能全量複製時間消耗到1分半到2分鐘
# ④增量複製
(1)如果全量複製過程中,master-slave網路連接斷掉,那麼salve重新連接master時,會觸發增量複製
(2)master直接從自己的backlog中取得部分遺失的數據,發送給slave node,預設backlog就是1MB
(3)msater就是根據slave發送的psync中的offset來從backlog中取得資料的
⑤heartbeat
主從節點互相都會發送heartbeat訊息
master預設每隔10秒發送一次heartbeat,salve node每隔1秒發送一個heartbeat
⑥異步複製
master每次接收到寫入指令之後,現在內部寫入數據,然後非同步傳送給slave node
2.讀寫分離:master負責寫入操作,slave負責幫master減輕存取查詢量
二、高可用機制
在高並發的情況下,配備多集群一主多備,雖然可以解決高並發問題,但是主機只有一個,master宕機那麼整個無法進行寫入操作,從機無法同步資料整個系統會處於癱瘓狀態,整就一個不可用。 redis的高可用機制哨兵機制,哨兵是redis集群裡面的重要的組件,他負責集群監控,信息通知,故障轉移,配置中心。
(1)群集監控,負責監控redis master和slave程序是否正常工作
(2)訊息通知,如果某個redis實例有故障,那麼哨兵負責發送訊息作為警報通知管理員
(3)故障轉移,如果master node掛掉了,會自動轉移到slave node上
(4)設定中心,如果故障轉移發生了,通知client客戶端新的master位址
哨兵本身是分散式的,是作為一個集群去工作的,需要互相協同工作。
當發現master node 宕機,會需要大部分的哨兵同意才可以,這個涉及到分散式的選舉。
哨兵機制需要保證最少3個節點才能保證其健全性,如果我們在測試時只給出兩個節點,一個master node一個為slave node 那麼這兩個節點裡面都有一個哨兵負責監控,當其中的master主機發生宕機,那麼需要哨兵來進行選舉,那麼master node裡面那個s1的哨兵已經沒辦法工作,只能由slave node裡面的s2哨兵進行選舉,那麼進行選舉之後要進行故障轉移需要一個哨兵進行工作,其majority參數規定了需要哨兵的個數進行故障轉移,這時只有一個S2哨兵沒有majority可以進行故障轉移。所以最少需要3個節點來保證其健壯。
三、高可用與高並發出現的資料遺失問題
(1)非同步複製導致的資料遺失
因為master -> slave的複製是異步的,所以可能有部分資料還沒複製到slave,master就宕機了,此時這些部分資料就遺失了。
(2)腦裂導致的資料遺失
腦裂,也就是說,某個master所在機器突然脫離了正常的網絡,跟其他slave機器不能連接,但是實際上master還在運行著,
此時哨兵可能會認為master宕機了,然後開啟選舉,將其他slave切換成了master,
這個時候,集群裡就會有兩個master,也就是所謂的腦裂,
此時雖然某個slave被切換成了master,但是可能client還沒來得及切換到新的master,還繼續寫向舊master的數據可能也遺失了,
因此舊master再次恢復的時候,會被當作一個slave掛到新的master去,自己的資料會清空,重新從新的master複製資料。
解決非同步複製和腦裂導致的資料遺失
min-slaves-to-write 1 min-slaves-max-lag 10
要求至少有1個slave,資料複製和同步的延遲不能超過10秒
如果說一旦所有的slave,資料複製和同步的延遲都超過了10秒鐘,那麼這個時候,master就不會再接收任何請求了
上面兩個配置可以減少非同步複製和腦裂導致的資料遺失
(1)減少非同步複製的資料遺失
有了min-slaves-max-lag這個配置,就可以確保說,一旦slave複製資料和ack延時太長,就認為可能master宕機後損失的資料太多了,那麼就拒絕寫請求,這樣可以把master宕機時由於部分資料未同步到slave導致的資料遺失降低的可控範圍內
(2)減少腦裂的資料遺失
如果一個master出現了腦裂,跟其他slave丟了連接,那麼上面兩個配置可以確保說,如果不能繼續給指定數量的slave發送數據,而且slave超過10秒沒有給自己ack訊息,那麼就直接拒絕客戶端的寫請求
這樣腦裂後的舊master就不會接受client的新數據,也就避免了數據丟失
上面的配置就確保了,如果跟任何一個slave丟了連接,在10秒後發現沒有slave給自己ack,那麼就拒絕新的寫入請求
因此在腦裂場景下,最多就遺失10秒的資料
更多程式相關知識,請造訪:程式設計入門 ! !
以上是詳解Redis的高可用和高並發機制的詳細內容。更多資訊請關注PHP中文網其他相關文章!