1. 程式人生 > >Redis多機資料庫的實現(叢集、複製、sentinel)

Redis多機資料庫的實現(叢集、複製、sentinel)

1.複製

Redis中,使用者通過執行slaveof命令或者設定slaveof選項,讓一個伺服器去複製另外一個伺服器,被複制的伺服器為主伺服器,對主伺服器進行復制的伺服器稱為從伺服器。
這裡寫圖片描述
舊版本複製功能分為:1)同步:將從伺服器的資料庫狀態更新至主伺服器當前所處的資料庫狀態。2)命令傳播:主伺服器的資料庫狀態被修改,導致主從資料庫的狀態不一致,讓主從伺服器的資料庫從新回到一致狀態。
同步:從伺服器對主伺服器的同步操作需要通過向主伺服器傳送SYNC命令來完成。
這裡寫圖片描述
這裡寫圖片描述
命令傳播:主伺服器會將客戶端對它執行的寫命令,傳送給從伺服器,使主從伺服器狀態保持一致。
缺點:斷線後重新複製,效率低下

新版本複製功能
使用PSYNC代替SYNC命令
PSYNC命令:完整重同步,部分同步。
完整重同步:類似SYNC的初始同步。
部分同步:處理斷線後複製情況,將主從伺服器斷開期間執行的寫命令傳送給從伺服器。通過複製偏移量、複製積壓緩衝區、伺服器執行ID

複製的實現
127.0.0.1:1212>slaveof 127.0.0.1 6379
1)設定主伺服器的地址和埠,首先將主伺服器的IP和埠儲存到伺服器狀態的masterhost和masterport
2)建立套接字連線
3)傳送ping命令
4)身份驗證
5)傳送埠資訊
6)同步

心跳檢測:從伺服器想主伺服器傳送命令來進行心跳檢測,以及命令丟失檢測。
1、檢測主從伺服器的網路連線狀態
從伺服器傳送 INFO replication,若主伺服器超過一秒鐘沒有接收到REPLCONF ACK命令,說明連線有問題。
2、輔助實現min-slaves
作用:防止主伺服器在不安全的情況下執行寫命令
3、檢測命令丟失

2.Sentinel(哨兵)

sentinel:是redis高可用的解決方案,由一個或者多個sentinel例項組成的sentinel系統可以監視任意多個主伺服器,以及這些伺服器屬下的所有從伺服器,並在被監視的主伺服器下線的狀態時,自動將下線主伺服器屬下的某個從伺服器升級為新的主伺服器。
這裡寫圖片描述這裡寫圖片描述

啟動並初始化sentinel
啟動命令:redissentinel/path/t/your/sentinel.conf redis-server /path/t/your/sentinel.conf

當sentinel 啟動時,需要執行以下步驟:
1)初始化伺服器
本質是執行在特殊模式下的redis伺服器,不會載入RDB和AOF檔案
2)將普通redis伺服器使用的程式碼替換成sentinel專用程式碼
普通的redis伺服器使用redis.h/redis_serverport作為埠,而sentinel使用redis_sentinel_port常量的值作為伺服器埠。
兩者的伺服器命令不同。
3)初始化sentinel狀態
4)根據給定的配置檔案,初始化sentinel的監視主伺服器列表
5)建立連向主伺服器的網路連線

獲取主伺服器資訊
sentinel會以預設十秒一次的頻率,傳送命令連線向北監視的主伺服器傳送INFO命令,通過分析INFO命令的回覆來獲取主伺服器的當前狀態。
sentinel發現主伺服器有新的從伺服器,sentinel除了會為新的從伺服器建立相應的例項結構外,sentinel還會建立連線到從伺服器的命令連線和訂閱連線。

3.叢集

Redis叢集是redis提供分散式資料庫方案,叢集通過分片來進行資料共享,並提供複製和故障轉移功能。

節點:一個redis 叢集通常有多個節點(node)組成,開始時每個節點相互獨立,都處於找一個包含自己的叢集中,要組建一個真正工作的叢集,需要將各個獨立的節點連線起來,構成一個多節點的叢集。

cluster meet <ip> <port>
首先連線節點:
$redis -cli -c -p 127.0.0.1:7000
127.0.0.1:7000>cluster Nodes  //檢視節點連線情況
127.0.0.1:7000>cluster meet 127.0.0.1:7001  //連線新的節點

啟動節點
redis啟動時會根據cluster-enabled配置選項是否yes來決定是否開啟伺服器叢集模式。
這裡寫圖片描述
叢集資料結構:clusterNode結構儲存了一個節點當前狀態,比如節點的建立時間、節點的名稱、節點當前的配置紀元、節點的IP地址和埠號。

槽指派:redis叢集通過分片來儲存資料庫的鍵值對,叢集的整個資料庫被分成16384個槽(slot),資料庫中的每個鍵都屬於這16384個槽的其中一個,每個節點都可以處理0個或者最多16384個槽。
當資料庫中的16384個槽都有節點在處理時,叢集處於上線狀態,如果任何一個槽沒有得到處理,則叢集處於下線狀態。

   通過cluster addslots命令可以將一個槽或者多個槽指派給節點節點複製
   127.0.0.17000>cluster addsolts 0 1 2 3 4 .... 5000
   127.0.0.17001>cluster addsolts  5000 5001 .....10000
  127.0.0.17002>cluster addsolts 10000 10001 .... 16383

//計算鍵屬於哪個槽
 127.0.0.17000>cluster keyslot "data"
 2022

重新分片
Redis叢集的重新分片操作可以將任意數量已經指派給某個節點的槽改為指派給另外一個節點,並且相關槽所屬的鍵值對也會從源節點移動到目標節點。

//第一步 新增新節點
//向新節點分配槽

重新分片原理:分片操作由redis叢集管理軟體redis-triib負責執行的。
這裡寫圖片描述

ASK錯誤
屬於被遷移槽的一部分鍵對儲存在源節點裡面,而另一部分鍵值對則儲存在目標節點裡面。
複製轉移
Redis叢集的節點分為主節點和從節點,主節點主要用於處理槽,從節點主要用於複製某個主節點,並在被複制的主節點下線時,代替下線的主節點繼續處理命令請求。
設定從節點:

cluster replicate<node_id>

可以讓接受命令的節點稱為node_id所指定的從節點,並開始對主節點進行復制。
故障檢測
叢集中的每個節點都會定期地向叢集中的其他節點發送PING命令,以此來檢查對方是否線上,如果接收ping訊息的節點沒有在規定的時間內,向傳送ping訊息的節點返回pong訊息,那麼將認為沒有返回訊息的節點標記為疑似下線。
如果半數以上處理槽的節點都將某節點x報告為疑似下線,那麼這個主節點x將被標記為已下線。
故障轉移
當一個節點發現自己真在複製的主節點進入已下線狀態時,從節點將開始對下線主節點進行故障轉移,一下是故障轉移的執行步驟。
1.複製下線主節點的所有從節點將會有一個從節點被選中。
2.被選中的從節點會執行slaveof on one,成為新的主節點。
3.新的主節點會撤銷所有對已下線主節點的槽指派,並將這些槽指派給自己。
4.新的主節點向叢集廣播一條pong訊息,這條pong訊息可以讓叢集中的其他節點立即致電這個節點已經由從節點變為主節點了。
5.新的主節點開始接收和自己負責處理的槽有關的命令請求,故障轉移完成。
叢集中的節點通過傳送和接受訊息進行通訊,節點的訊息包括meet,ping,pong,publish,fail五種。