1. 程式人生 > >redis3.0 cluster功能介紹

redis3.0 cluster功能介紹

jpeg 標識符 rms 代理 更新數據 bitmap 查詢 c51 想要

edis從3.0開始支持集群功能。redis集群采用無中心節點方式實現,無需proxy代理,客戶端直接與redis集群的每個節點連接,根據同樣的hash算法計算出key對應的slot,然後直接在slot對應的redis上執行命令。在redis看來,響應時間是最苛刻的條件,增加一層帶來的開銷是redis不原因接受的。因此,redis實現了客戶端對節點的直接訪問,為了去中心化,節點之間通過gossip協議交換互相的狀態,以及探測新加入的節點信息。redis集群支持動態加入節點,動態遷移slot,以及自動故障轉移。

集群架構

技術分享

每個節點都會跟其他節點保持連接,用來交換彼此的信息。節點組成集群的方式使用cluster meet

命令,meet命令可以讓兩個節點相互握手,然後通過gossip協議交換信息。如果一個節點r1在集群中,新節點r4加入的時候與r1節點握手,r1節點會把集群內的其他節點信息通過gossip協議發送給r4,r4會一一與這些節點完成握手,從而加入到集群中。

技術分享

節點在啟動的時候會生成一個全局的標識符,並持久化到配置文件,在節點與其他節點握手後,這些信息也都持久化下來。節點與其他節點通信,標識符是它唯一的標識,而不是IP、PORT地址。如果一個節點移動位置導致IP、PORT地址發生變更,集群內的其他節點能把該節點的IP、PORT地址糾正過來。

集群數據分布

集群數據以數據分布表的方式保存在各個slot上。數據分布表默認含有16384個slot。

技術分享

key與slot映射使用的CRC16算法,即:slot = CRC16(key) mod 16384。

集群只有在16384個slot都有對應的節點才能正常工作。slot可以動態的分配、刪除和遷移。
每個節點會保存一份數據分布表,節點會將自己的slot信息發送給其他節點,發送的方式使用一個unsigned char的數組,數組長度為16384/8。每個bit標識為0或者1來標識某個slot是否是它負責的。

技術分享

使用這樣的方式傳輸,就能大大減少數據分布表的字節。這種方式使用的字節為2048,如果純粹的傳遞數據分布表,那邊一個slot至少需要2字節的slot值+2字節port+4字節ip,共8 16384=131072字節,或者以ip、port為鍵,把節點對應的slot放在後面,那麽也至少需要2 \

16384加上節點的數量,也遠遠大於2048字節。由於節點間不停的在傳遞數據分布表,所以為了節省帶寬,redis選擇了只傳遞自己的分布數據。但這樣的方式也會帶來管理方面的麻煩,如果一個節點刪除了自己負責的某個slot,這樣該節點傳遞給其他節點數據分布表的slot標識為0,而redis采用了bitmapTestBit方法,只處理slot為1的節點,而並未把每個slot與收到的數據分布表對比,從而產生了節點間數據分布表視圖的不一致。這種問題目前只能通過使用者來避免。

redis目前還支持slot的遷移,可以把一個slot從一個節點遷移到另一個節點,節點上的數據需要使用者通過cluster getkeysinslot去除遷移slot上的key,然後執行migrate命令一個個遷移到新節點。具體細節會在下面的slot遷移章節介紹。

集群訪問

客戶端在初始化的時候只需要知道一個節點的地址即可,客戶端會先嘗試向這個節點執行命令,比如“get key”,如果key所在的slot剛好在該節點上,則能夠直接執行成功。如果slot不在該節點,則節點會返回MOVED錯誤,同時把該slot對應的節點告訴客戶端。客戶端可以去該節點執行命令。目前客戶端有兩種做法獲取數據分布表,一種就是客戶端每次根據返回的MOVED信息緩存一個slot對應的節點,但是這種做法在初期會經常造成訪問兩次集群。還有一種做法是在節點返回MOVED信息後,通過cluster nodes命令獲取整個數據分布表,這樣就能每次請求到正確的節點,一旦數據分布表發生變化,請求到錯誤的節點,返回MOVED信息後,重新執行cluster nodes命令更新數據分布表。

在訪問集群的時候,節點可能會返回ASK錯誤。這種錯誤是在key對應的slot正在進行數據遷移時產生的,這時候向slot的原節點訪問,如果key在遷移源節點上,則該次命令能直接執行。如果key不在遷移源節點上,則會返回ASK錯誤,描述信息會附上遷移目的節點的地址。客戶端這時候要先向遷移目的節點發送ASKING命令,然後執行之前的命令。

這些細節一般都會被客戶端sdk封裝起來,使用者完全感受不到訪問的是集群還是單節點。

集群支持hash tags功能,即可以把一類key定位到同一個slot,tag的標識目前不支持配置,只能使用{},redis處理hash tag的邏輯也很簡單,redis只計算從第一次出現{,到第一次出現}的substring的hash值,substring為空,則仍然計算整個key的值,這樣對於foo{}{bar}、{foo}{bar}、foo這些沖突的{},也能取出tag值。使用者需遵循redis的hash tag規範。

127.0.0.1:6379> CLUSTER KEYSLOT foo{hash_tag}
(integer) 2515
127.0.0.1:6379> CLUSTER KEYSLOT fooadfasdf{hash_tag}
(integer) 2515
127.0.0.1:6379> CLUSTER KEYSLOT fooadfasdfasdfadfasdf{hash_tag}
(integer) 2515

集群版本的redis能夠支持全部的單機版命令。不過還是有些命令會有些限制。

訂閱在使用上與單機版沒有任何區別。訂閱功能通過集群間共享publish消息實現的,客戶端可以向任意一個節點(包括slave節點)訂閱消息,然後在一個節點上執行的publish命令,該節點會把該命令傳播給集群內的每個節點,這樣訂閱該消息的客戶端就能收到該命令。

redis集群版只使用db0,select命令雖然能夠支持select 0。其他的db都會返回錯誤。

127.0.0.1:6379> select 0
OK
127.0.0.1:6379> select 1
(error) ERR SELECT is not allowed in cluster mode

redis集群版對多key命令的支持,只能支持多key都在同一個slot上,即使多個slot在同一個節點上也不行。

127.0.0.1:6379> mget key7 key28
(error) CROSSSLOT Keys in request don‘t hash to the same slot

事務的支持只能在也一個slot上完成。MULTI命令之後的命令的key必須都在同一個slot上,如果某條命令的key對應不在相同的slot上,則事務直接回滾。遷移的時候,在遷移源節點執行命令的key必須在移原節點上存在,否則事務就會回滾。在遷移目的節點執行的時候需要先執行ASKING命令再執行MULTI命令,這樣接下來該slot的命令都能被執行。可以看出,對於單key和相同hash tags的事務,集群還是能很好的支持。

在遷移的時候有個地方需要註意,對於多key命令在遷移目的節點執行時,如果多個key不全在該節點上,則命令無法執行。如下所示,key和key14939對應的slot為12539,其中key在目的節點,key14939既不在目的節點也不在源節點,執行命令的節點是遷移目的節點:

127.0.0.1:6379> asking
OK
127.0.0.1:6379> mget key key14939
(error) TRYAGAIN Multiple keys request during rehashing of slot

集群消息

集群間互相發送消息,使用另外的端口,所有的消息在該端口上完成,可以稱為消息總線,這樣可以做到不影響客戶端訪問redis,可見redis對於性能的追求。目前集群有如下幾種消息:

  • CLUSTERMSG_TYPE_PING:gossip協議的ping消息。
  • CLUSTERMSG_TYPE_PONG:gossip協議的pong消息。
  • CLUSTERMSG_TYPE_MEET:握手消息。
  • CLUSTERMSG_TYPE_FAIL:master節點檢測到,超過半數master認為某master離線,則發送fail消息。
  • CLUSTERMSG_TYPE_PUBLISH:publish消息,向其他節點推送消息。
  • CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST:故障轉移時,slave發送向其他master投票請求。
  • CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK:故障轉移時,其他master回應slave的請求。
  • CLUSTERMSG_TYPE_UPDATE:通知某節點,它負責的某些slot被另一個節點替換。
  • CLUSTERMSG_TYPE_MFSTART:手動故障轉移時,slave請求master停止訪問,從而對比兩者的數據偏移量,可以達到一致。

集群節點間相互通信使用了gossip協議的push/pull方式,ping和pong消息,節點會把自己的詳細信息和已經跟自己完成握手的3個節點地址發送給對方,詳細信息包括消息類型,集群當前的epoch,節點自己的epoch,節點復制偏移量,節點名稱,節點數據分布表,節點master的名稱,節點地址,節點flag位,節點所處的集群狀態。節點根據自己的epoch和對方的epoch來決定哪些數據需要更新,哪些數據需要告訴對方更新。然後根據對方發送的其他地址信息,來發現新節點的加入,從而和新節點完成握手。

節點默認每秒在集群中的其他節點選擇一個節點,發送ping消息。選擇節點步驟是:

  • 隨機 5 個節點。
  • 跳過斷開連接和已經在ping還沒收到pong響應的節點。
  • 從篩選的節點中選擇最近一次接收pong回復距離現在最舊的節點。

除了常規的選擇節點外,對於那些一直未隨機到節點,redis也有所支持。當有節點距離上一次接收到pong消息超過節點超時配置的一半,節點就會給這些節點發送ping消息。

ping消息會帶上其他節點的信息,選擇其他節點步驟是:

  • 最多選擇3個節點。
  • 最多隨機遍歷6個節點,如果因為一些條件不能被選出,可能會不滿3個。
  • 忽略自己。
  • 忽略正在握手的節點。
  • 忽略帶有 NOADDR 標識的節點。
  • 忽略連接斷開而且沒有負責任何slot的節點。

ping消息會把發送節點的ping_sent改成當前時間,直到接收到pong消息,才更新ping_sent為0。當ping消息發送後,超過節點超時配置的一半,就會把發送節點的連接斷開。超過節點超時配置,就會認為該節點已經下線。

接收到某個節點發來的ping或者pong消息,節點會更新對接收節點的認識。比如該節點主從角色是否變化,該節點負責的slot是否變化,然後獲取消息帶上的節點信息,處理新節點的加入。

slot更新這裏要細說下。假設這裏是節點A接收到節點B的消息。A節點會取出自己保存的B節點的分布表與消息的分布表進行對比,B節點如果是slave,則比較的是A節點保存的B的master的分布表和消息中的分布表。比較只是使用memcmp簡單的比較兩份數據是否一樣,一樣則無需處理,不一樣就處理不一致的slot。更新的時候,這裏只是處理消息中分布表為1的slot。如果和A節點保持一致或者該slot正準備遷移到A節點,則繼續處理。如果slot產生了沖突,則以epoch大的為準。如果沖突的slot中有A自己負責的節點,而且B比A的epoch大導致需要更新slot為B負責,此時A負責的slot為0的時候,可以認為B是A的slave。這種情況經常發生在A由原來的master變成slave,B提升為master的場景下。

前面說到slot更新的時候,如果B比A的epoch大,則A更新對slot的認識。如果A比B的epoch大, 在redis接下來的邏輯會再次處理,A會給B發送update消息,B收到A發送的update消息,執行slot更新方法。這種情況也經常發生在主從切換的時候。第一種情況發生在新master把數據分布表推給舊master。第二種情況發生在舊master給新master發消息的時候,新master給舊master發送update消息。

slot遷移

redis cluster支持slot的動態遷移,遷移需要按照指定步驟進行,不然可能破壞當前的集群數據分布表。redis的cluster setslot命令提供了對遷移的支持。cluster setslot <slot> IMPORTING <node ID>命令在遷移目的節點執行,表示需要把該slot遷移到本節點。cluster setslot <slot> MIGRATING <node ID>命令在遷移源節點執行,表示需要把該slot遷出。cluster setslot <slot> NODE <node ID>在遷移完成後在遷移源節點和遷移目的節點執行後,表示遷移完成,數據分布表恢復穩定。如果需要取消遷移操作,在遷移源節點和遷移目的節點上執行cluster setslot <slot> STABLE

下面先來看一下完整的遷移流程:

  • 在遷移目的節點執行cluster setslot <slot> IMPORTING <node ID>命令,指明需要遷移的slot和遷移源節點。
  • 在遷移源節點執行cluster setslot <slot> MIGRATING <node ID>命令,指明需要遷移的slot和遷移目的節點。
  • 在遷移源節點執行cluster getkeysinslot獲取該slot的key列表。
  • 在遷移源節點執行對每個key執行migrate命令,該命令會同步把該key遷移到目的節點。
  • 在遷移源節點反復執行cluster getkeysinslot命令,直到該slot的列表為空。
  • 在遷移源節點和目的節點執行cluster setslot <slot> NODE <node ID>,完成遷移操作。

技術分享

遷移過程中該slot允許繼續有流量進來,redis保證了遷移過程中slot的正常訪問。在遷移過程中,對於該slot的請求,如果key在源節點,則表示該key還沒有遷移到目的節點。如果key不在源節點,源節點會返回ASK錯誤,告訴客戶端去遷移目的節點請求。這樣新的key就直接寫入到遷移目的節點了。客戶端寫入目的節點前需要發送ASKING命令,告訴遷移目的節點我是寫入增量數據,沒有ASKING命令,遷移目的節點會不認這次請求,返回MOVED錯誤,告訴客戶端去遷移源節點請求。

憑借ASK機制migrate命令,redis能保證slot的全量數據和增量數據都能導入目的節點。因為對於源節點返回了ASK錯誤,就能保證該key不在源節點上,那麽它只會出現在目的節點或者不存在。所以客戶端獲取ASK錯誤到向目的節點無需保證原子性。然後migrate命令是個原子操作,它會等待目的節點寫入成功才在源節點返回,保證了遷移期間不接受其他請求,從一個外部客戶端的視角來看,在某個時間點上,遷移的鍵要麽存在於源節點,要麽存在於目的節點,但不會同時存在於源節點和目的節點。

遷移過程中幾乎不影響用戶使用,除了在多key的命令在遷移目的節點無法執行,這個在集群訪問已經說明。

不過由於migrate命令是同步阻塞執行的,所以如果key對應的value很大,會增加阻塞時間,特別對於list、set、zset等結構如果value很大的話,redis並不關心這些結構的長度,而是直接以key為單位一次性遷移。同時遷移過程中大量執行migrate命令,會增加客戶端的響應時間。

遷移的時候在master出現異常的時候,遷移工作需要做些處理。
如果在遷移過程中,源節點宕機,此時需做如下調整:

  • 目的節點執行cluster setslot <slot> IMPORTING <node ID>命令,node ID為源節點group的新master
  • 源節點group內的新master執行cluster setslot <slot> MIGRATING <node ID>命令,遷移該slot到目的節點。

這樣可以繼續完成遷移操作。

如果在遷移過程中,目的節點宕機,此時需做如下調整:

  • 目的節點group內的新master執行cluster setslot <slot> IMPORTING <node ID>命令,node ID為源節點。
  • 源節點執行cluster setslot <slot> MIGRATING <node ID>命令,遷移該slot到目的節點group內的新master。

這樣也可以繼續完成遷移操作。

主從復制

集群間節點支持主從關系,復制的邏輯基本復用了單機版的實現。不過還是有些地方需要註意。

首先集群間節點建立主從關系不再使用原有的SLAVEOF命令和SLAVEOF配置,而是通過cluster replicate命令,這保證了主從節點需要先完成握手,才能建立主從關系。

集群是不能組成鏈式主從關系的,也就是說從節點不能有自己的從節點。不過對於集群外的沒開啟集群功能的節點,redis並不幹預這些節點去復制集群內的節點,但是在集群故障轉移時,這些集群外的節點,集群不會處理。

集群內節點想要復制另一個節點,需要保證本節點不再負責任何slot,不然redis也是不允許的。

集群內的從節點在與其他節點通信的時候,傳遞的消息中數據分布表和epoch是master的值。

故障轉移

集群主節點出現故障,發生故障轉移時,其他主節點會把故障主節點的從節點自動提為主節點,原來的主節點恢復後,自動成為新主節點的從節點。

這裏先說明,把一個master和它的全部slave描述為一個group,故障轉移是以group為單位的,集群故障轉移的方式跟sentinel的實現很類似。某個master節點一段時間沒收到心跳響應,則集群內的master會把該節點標記為pfail,類似sentinel的sdown。集群間的節點會交換相互的認識,超過一半master認為該異常master宕機,則這些master把異常master標記為fail,類似sentinel的odown。fail消息會被master廣播出來。group的slave收到fail消息後開始競選成為master。競選的方式跟sentinel選主的方式類似,都是使用了raft協議,slave會從其他的master拉取選票,票數最多的slave被選為新的master,新master會馬上給集群內的其他節點發送pong消息,告知自己角色的提升。其他slave接著開始復制新master。等舊master上線後,發現新master的epoch高於自己,通過gossip消息交互,把自己變成了slave。大致就是這麽個流程。自動故障轉移的方式跟sentinel很像,具體步驟可以參考本人寫的《redis sentinel 設計與實現》。

redis還支持手動的故障轉移,即通過在slave上執行cluster failover命令,可以讓slave提升為master。failover命令支持傳入FORCE和TAKEOVER參數。

  • 不傳入額外參數:如果主節點異常,則不能進行failover,主節點正常的情況下需要先比較從節點和主節點的偏移量,此時會讓主節點停止客戶端請求,直到超時或者故障轉移完成。主從偏移量相同後開始手動故障轉移流程。
  • FORCE:使用FORCE參數與sentinel的手動故障轉移流程基本類似,強制開始一次故障轉移。
  • TAKEOVER:這種手動故障轉移的方式比較暴力,slave直接提升自己的epoch為最大的epoch。並把自己變成master。這樣在消息交互過程中,舊master能發現自己的epoch小於該slave,同時兩者負責的slot一致,它會把自己降級為slave。

均衡集群的slave(Replica migration)

在集群運行過程中,有的master的slave宕機,導致了該master成為孤兒master(orphaned masters),而有的master有很多slave。此處孤兒master的定義是那些本來有slave,但是全部離線的master,對於那些原來就沒有slave的master不能認為是孤兒master。redis集群支持均衡slave功能,官方稱為Replica migration,而我覺得均衡集群的slave更好理解該概念。集群能把某個slave較多的group上的slave遷移到那些孤兒master上,該功能通過cluster-migration-barrier參數配置,默認為1。slave在每次定時任務都會檢查是否需要遷移slave,即把自己變成孤兒master的slave。 滿足以下條件,slave就會成為孤兒master的slave:

  • 自己所在的group是slave最多的group。
  • 目前存在孤兒master。
  • 自己所在的group的slave數目至少超過2個,只有自己一個的話遷移到其他group,自己原來的group的master又成了孤兒master。
  • 自己所在的group的slave數量大於cluster-migration-barrier配置。
  • 與group內的其他slave基於memcmp比較node id,自己的node id最小。這個可以防止多個slave並發復制孤兒master,從而原來的group失去過多的slave。

網絡分區說明

redis的集群模式下,客戶端需要和全部的節點保持連接,這樣可能出現網絡分區問題,客戶端和一些節點在一個網絡分區,另一部分節點在另一個網絡分區。在分區期間,客戶端仍然能執行命令,直到集群經過cluster-node-timeout發現分區情況,節點探測到有slot無法提供服務,才開始禁止客戶端執行命令。

這時候會出現一種現象,假設客戶端和一個master在小分區,其他節點在大分區。超時後,其他節點共同投票把group內的一個slave提為master,等分區恢復。舊的master會成為新master的slave。這樣在cluster-node-timeout期間對舊master的寫入數據都會丟失。

這個問題可以通過設置cluster-node-timeout來減少不一致。如果對一致性要求高的應用還可以通過min-slaves-to-write配置來提高寫入的要求。

slot保存key列表

redis提供了cluster countkeysinslot和cluster getkeysinslot命令,可以獲得某個slot的全部key列表。通過該列表,可以實現slot的遷移。該功能是通過skiplist實現的,skiplist是redis內部用來實現zset的數據結構,在slot保持key的時候也派上了用場。redis所有在db層對hash表的操作,也會在skiplist上執行相應的操作。比如往hash表增加數據,redis也會往skiplist也寫一份數據,該skiplist的score就是slot的值,value對應了具體的key。這等於是redis在數據分布表上冗余了所有的key。不過相比skiplist所帶來遷移的方便,冗余的結果是可以接受的,這也期望客戶端,不要使用過長的key,從而增加內存的消耗。

附錄1:集群相關命令

cluster meet

集群間相互握手,加入彼此所在的集群。

cluster nodes

獲取集群間節點信息的列表,如下所示,格式為<node ID> <node IP:PORT> <node role> [master node ID|-] <node ping_sent> <node pong_received> <node epoch> <node status>

127.0.0.1:6379> cluster nodes
a15705fdb7cac60e07ff699bf4c514e80f245a2c 10.180.157.205:6379 slave 2b5603326d0fca28031467727fae4558115a99d8 0 1450854214289 11 connected
6477541e4594e60e095c8f440882636236545936 10.180.157.202:6379 slave 9b35a393fa6623887215023b761d531dde452d3c 0 1450854211276 12 connected
ecf9ae60e87ea3358d9c5f1f269e0ed9a387ea40 10.180.157.201:6379 master - 0 1450854214788 5 connected 10923-16383
2b5603326d0fca28031467727fae4558115a99d8 10.180.157.200:6379 master - 0 1450854213283 11 connected 5461-10922
f31f6ce49b3a2f3a246b2d97349c8f8614cf3a2c 10.180.157.208:6379 slave ecf9ae60e87ea3358d9c5f1f269e0ed9a387ea40 0 1450854212286 9 connected
9b35a393fa6623887215023b761d531dde452d3c 10.180.157.199:6379 myself,master - 0 0 12 connected 0-5460

cluster myid

返回節點的id。

127.0.0.1:6379> cluster myid
"9b35a393fa6623887215023b761d531dde452d3c"

cluster slots

返回集群間節點負責的數據分布表。

127.0.0.1:6379> cluster slots
1) 1) (integer) 10923
   2) (integer) 16383
   3) 1) "10.180.157.201"
      2) (integer) 6379
   4) 1) "10.180.157.208"
      2) (integer) 6379
2) 1) (integer) 5461
   2) (integer) 10922
   3) 1) "10.180.157.200"
      2) (integer) 6379
   4) 1) "10.180.157.205"
      2) (integer) 6379
3) 1) (integer) 0
   2) (integer) 5460
   3) 1) "10.180.157.199"
      2) (integer) 6379
   4) 1) "10.180.157.202"
      2) (integer) 6379

cluster flushslots

清空該節點負責slots,必須在節點負責的這些slot都沒有數據的情況下才能執行,該命令需要謹慎使用,由於之前說的bitmapTestBit方法,redis只比較負責的節點,清空的slots信息無法被其他節點同步。

cluster addslots [slot]

在節點上增加slot。

cluster delslots [slot]

在節點上取消slot的負責。這也會導致前面說的slot信息無法同步,而且一旦集群有slot不負責,配置cluster-require-full-coverage為yes的話,該節點就無法提供服務了,所以使用也需謹慎。

cluster setslot MIGRATING

把本節點負責的某個slot設置為遷移到目的節點。

cluster setslot IMPORTING

設置某個slot為從遷移源節點遷移標誌。

cluster setslot STABLE

設置某個slot為從遷移狀態恢復為正常狀態。

cluster setslot NODE

設置某個slot為某節點負責。該命令使用也需要註意,cluster setslot的四個命令需要配置遷移工具使用,單獨使用容易引起集群混亂。該命令在集群出現異常時,需要指定某個slot為某個節點負責時,最好在每個節點上都執行一遍,至少要在遷移的節點和最高epoch的節點上執行成功。

cluster info

集群的一些info信息。

127.0.0.1:6379> 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
cluster_size:3
cluster_current_epoch:12
cluster_my_epoch:12
cluster_stats_messages_sent:1449982
cluster_stats_messages_received:1182698

cluster saveconfig

保存集群的配置文件,集群默認在配置修改的時候會自動保存配置文件,該方法也能手動執行命令保存。

cluster keyslot

可以查詢某個key對應的slot地址。

127.0.0.1:6379> cluster keyslot key
(integer) 12539

cluster countkeysinslot

可以查詢該節點負責的某個slot內部key的數量。

127.0.0.1:6379> cluster countkeysinslot 13252
(integer) 2

cluster getkeysinslot

可以查詢該節點負責的某個slot內部指定數量的key列表。

127.0.0.1:6379> cluster getkeysinslot 13252 10
1) "key0"
2) "key2298"

cluster forget

把某個節點加入黑名單,這樣就無法完成握手。黑名單的過期時為60s,60s後兩節點又會繼續完成握手。

cluster replicate

負責某個節點,成為它的slave。

cluster slaves

列出某個節點slave列表。

127.0.0.1:6379> cluster slaves 2b5603326d0fca28031467727fae4558115a99d8
1) "a15705fdb7cac60e07ff699bf4c514e80f245a2c 10.180.157.205:6379 slave 2b5603326d0fca28031467727fae4558115a99d8 0 1450854932667 11 connected"

cluster count-failure-reports

列出某個節點的故障轉移記錄的長度。

cluster failover [FORCE|TAKEOVER]

手動執行故障轉移。

cluster set-config-epoch

設置節點epoch,只有在節點加入集群前才能設置。

cluster reset [SOFT|HARD]

重置集群信息,soft是清空其他節點的信息,但不修改自己的id。hard還會修改自己的id。不傳該參數則使用soft方式。

readonly

在slave上執行,執行該命令後,可以在slave上執行只讀命令。

readwrite

在slave上執行,執行該命令後,取消在slave上執行命令。

附錄2:集群相關配置

cluster-enabled

  • 說明:集群開關,默認是不開啟集群模式。
  • 默認值:no。
  • 是否可以動態修改:no。
  • 值的範圍:yes|no。

cluster-config-file

  • 說明:集群配置文件的名稱,每個節點都有一個集群相關的配置文件,持久化保存集群的信息。
  • 默認值:”nodes.conf”。
  • 是否可以動態修改:no。
  • 值的範圍:文件路徑。

cluster-node-timeout

  • 說明:節點的超時時間,單位是毫秒。
  • 默認值:15000。
  • 是否可以動態修改:yes。
  • 值的範圍:大於0。

cluster-slave-validity-factor

  • 說明:在進行故障轉移的時候,group的全部slave都會請求申請為master,但是有些slave可能與master斷開連接一段時間了,導致數據過於陳舊,這樣的slave不應該被提升為master。該參數就是用來判斷slave節點與master斷線的時間是否過長。判斷方法是比較slave斷開連接的時間和(node-timeout * slave-validity-factor) + repl-ping-slave-period
  • 默認值:10。
  • 是否可以動態修改:yes。
  • 值的範圍:大於等於0。

cluster-migration-barrier

  • 說明:master的slave數量大於該值,slave才能遷移到其他孤兒master上,具體說明見均衡集群的slave章節。
  • 默認值:1。
  • 是否可以動態修改:yes。
  • 值的範圍:大於等於0。

cluster-require-full-coverage

  • 說明:默認情況下,集群全部的slot有節點負責,集群狀態才為ok,才能提供服務。設置為no,可以在slot沒有全部分配的時候提供服務。不建議打開該配置,這樣會造成分區的時候,小分區的master一直在接受寫請求,而造成很長時間數據不一致。
  • 默認值:yes。
  • 是否可以動態修改:yes。
  • 值的範圍:yes|no。

redis3.0 cluster功能介紹