Redis命令詳解:Cluster

前文中我們介紹過了Redis的三種集羣方案,沒有了解過的同學可以自行前往。今天要介紹的Redis的親兒子Cluster相關的命令。

CLUSTER ADDSLOTS

最早可用版本:3.0.0

時間複雜度:O(N),N是參數中hash的slot總數

這個命令是用來將指定的slot分配給接收命令的機器。如果執行成功,該機器就擁有這些slot,並會在集羣中進行廣播。

需要注意的是:

  1. 該命令只有在當所有指定的slot在接收命令的節點上沒有被分配時生效。節點將拒絕接納已經分配到其他節點的slot。

  2. 如果相同的slot被多次指定,命令就會執行失敗。

  3. 如果一個slot作爲參數被設置爲importing,一旦節點向自己分配該slot,這個狀態將會被清除。

這個命令的應用場景有兩種:

  1. 創建新的集羣時,ADDSLOTS用於主節點初始化分配可用的hash slots

  2. 修復有未分配slots的壞集羣

如果一個節點爲自己分配了一個slot集合,它會將這個信息在心跳包的header裏傳播出去。然而其他節點只有在他們的slot沒有被其他節點綁定或者沒有作爲新節點傳播時纔會接收這個信息。

這意味着這個命令應該僅通過redis集羣應用管理客戶端,例如redis-trib。如果這個命令使用了錯誤的上下文會導致集羣處於錯誤的狀態或者導致數據丟失,因此這個命令需要謹慎使用。

CLUSTER COUNT-FAILURE-REPORTS

最早可用版本:3.0.0

時間複雜度:O(N),N是故障報告的數量

這個命令返回指定節點的故障報告。故障報告是Redis Cluster用來將節點從PFAIL狀態轉換到FAIL狀態的方式。

更多的細節:

  • 一個節點會用PFAIL標記一個不可達時間超過超時時間,這個超時時間是Redis Cluster配置中的基本選項

  • 處於PFAIL狀態的節點會將狀態信息提供在心跳包的gossip部分。

  • 每當一個節點處理來自其他節點的gossip信息時,該節點會建立故障報告,並且會記住發送消息包的節點說的其他節點是在PFAIL狀態的消息。

  • 每個故障報告的生存時間是節點超時時間的兩倍

  • 如果在一段時間一個節點被另一個節點標記爲PFAIL狀態,並且在同一時間收到大多數主節點關於該節點的故障報告,那麼該節點的故障狀態會從PFAIL變成FAIL,並且廣播這個信息,讓所有可達的節點將這個節點標記爲FAIL。

該節點返回當前節點的故障報告數,該計數值不包括當前節點。

CLUSTER COUNTKEYSINSLOT

最早可用版本:3.0.0

時間複雜度:O(1)

這個命令返回指定Redis集羣的slot的key的數量。該命令只查詢連接節點的本地數據集,如果指定的slot被分配在別的節點上,就會返回0。

CLUSTER DELSLOTS

最早可用版本:3.0.0

時間複雜度:O(N),N是slot參數的數量

在Redis Cluster中,每個節點都會知道哪些主節點正在負責哪些slot。

DELSLOTS命令使一個特定的節點忘記主節點負責的hash slot。在這之後,這些hash slot就被認爲是未綁定狀態的。需要注意的是:

  1. 命令只在參數指定的hash slot和某些節點綁定時有效

  2. 如果同一個hash slot被指定多次,該命令會失效

  3. 節點可能因爲沒有覆蓋全部slot而變成下線狀態

CLUSTER FAILOVER

最早可用版本:3.0.0

時間複雜度:O(1)

用法:CLUSTER FAILOVER [FORCE|TAKEOVER]

該命令只能在集羣slave節點執行,讓slave節點進行一次人工的故障切換。

人工故障切換時一種常規操作,而不是真的出了故障。當我們希望當前的master和它的slave進行一次安全的主備切換時,流程如下:

  1. 當前slave節點告知其master停止處理來自客戶端的請求。

  2. master節點將當前replication offset回覆給slave

  3. 該slave節點在未應用至replication offset之前不做任何操作,以保證master傳來的數據均被處理

  4. 該slave節點進行故障轉移,從集羣中大多數master獲取一個新的配置,並廣播自己的最新配置

  5. 舊的master更新配置,解除客戶端阻塞,回覆重定向信息,以便客戶端可以和新的master通信。

該命令有兩個選項:FORCE和TAKEOVER,下面我們來解釋一下這兩個選項的作用。

FORCE選項:slave節點不會和master做協商,直接從上述第4步開始進行故障切換

TAKEOVER選項:忽略集羣一致驗證的人工故障切換。有時會出現集羣中master節點不夠的情況,此時我們就需要使用TAKEOVER選項將slave批量切換爲master節點。

TAKEOVER選項實現了FORCE選項的所有功能,當一個slave節點收到CLUSTER FAILOVER TAKEOVER命令時會有如下操作:

  1. 生成一個新的configEpoch,如果本地配置的epoch不是最大的,就需要將其配置爲最大。

  2. 將原master節點管理的所有slot分配給自己,同時儘快分發最新的配置給所有可達節點。

CLUSTER FORGET

最早可用版本:3.0.0

時間複雜度:O(1)

這個命令用於移除指定node-id的node。如果一個node屬於某個集羣,那麼集羣中其他節點都會知道它的存在,因此CLUSTER FORGET命令會發送給集羣中剩下的所有節點。

然而這個命令並不是簡單的把node從node表中刪除,它還禁止這個節點再次被添加進集羣。

假設我們有4個節點:A、B、C、D,此時我們刪除D,如果不把D加入禁用列表,就會發生以下情況:

  1. 把D負責的slot重新分配給A、B、C

  2. 此時D沒有負責的slot了,但仍然在node表中

  3. 給A發送命令CLUSTER FORGET D

  4. B給A發送一個心跳包,其中包含了D的信息

  5. A不知道D的信息,就又開始聯繫D

  6. D又被重新加入到A的node表中

這樣我們的刪除命令就無效了,除非我們在各個節點沒有互相發送心跳包的時候同時給他們發送CLUSTER FORGET命令。但這顯然不合理,所以我們實際上應該這樣做:

  1. 指定的節點從node表中刪除

  2. 被刪除的節點的node-id加入禁用列表一分鐘

  3. node在處理心跳消息時會忽略禁用列表中的所有node-id的節點

在一些特殊情況下,這個命令會無法執行並返回一個錯誤。

  1. 指定的node-id沒有在node表中

  2. 收到命令的節點是從節點,而要刪除的節點是它的主節點

  3. 收到命令的節點和待刪除的節點是同一個節點

CLUSTER GETKEYSINSLOT

最早可用版本:3.0.0

時間複雜度:O(log(N)),N是請求的key的數量

用法:CLUSTER GETKEYSINSLOT slot count

這個命令返回連接節點指定的slot裏key的列表。key的最大數量由count指定。所以這個API可以用作key的批處理。這個命令的主要用途是在做rehash的過程中,把slot從一個節點移動到另外一個節點。

CLUSTER INFO

最早可用版本:3.0.0

時間複雜度:O(1)

提供Redis集羣的相關信息。

 1cluster_state:ok
 2cluster_slots_assigned:16384
 3cluster_slots_ok:16384
 4cluster_slots_pfail:0
 5cluster_slots_fail:0
 6cluster_known_nodes:6
 7cluster_size:3
 8cluster_current_epoch:6
 9cluster_my_epoch:2
10cluster_stats_messages_sent:1483972
11cluster_stats_messages_received:1483968
  • cluster_state:ok狀態表示節點可以接收查詢請求,fail表示至少有一個slot沒有分配或者在error狀態。

  • cluster_slots_assigned:已經分配到集羣節點的slot。16384個slot全部被分配到集羣節點是集羣節點正常運行的必要條件

  • cluster_slots_ok:slot不是FAIL或PFAIL狀態的數量

  • cluster_slots_pfail:slot狀態是PFAIL的數量

  • cluster_slots_fail:slot狀態是FAIL的數量,如果不是0,那麼集羣節點將無法提供服務,除非cluster-require-full-coverage被設置爲no

  • cluster_known_nodes:集羣中的節點數量

  • cluster_size:至少包含一個slot且能夠提供服務的master節點數量

  • cluster_current_epoch:集羣本地Current Epoch的值

  • cluster_my_epoch:當前正在使用節點的Config Epoch值

  • cluster_stats_messages_sent:通過點到點總線發送消息的數量

  • cluster_stats_messages_received:通過點到點總線接收消息的數量

CLUSTER KEYSLOT

最早可用版本:3.0.0

時間複雜度:O(N),N是key的字節數

返回一個整數,用於標識指定鍵所散列到的slot。這個命令主要是用於調試和測試。因爲它通過一個API來暴露Redis底層hash算法的實現。

CLUSTER MEET

最早可用版本:3.0.0

時間複雜度:O(1)

CLUSTER MEET命令用來連接不同Redis節點,以進入工作集羣。

有一點基本的共識是節點之間互相都是不信任的,並且被認爲是未知節點。以避免因爲系統管理錯誤或者網絡地址被修改而導致多個集羣的節點混合成一個。

因此,爲了使給定的節點能接收另一個節點到Redis Cluster中,有兩種方法:

  1. 系統管理員發送CLUSTER MEET命令強制一個節點會面另一個節點

  2. 一個已知節點發送一個保存在gossip部分的節點列表,包含着未知節點。如果接收的節點已經將發送節點標記爲已知節點,那麼它會處理gossip中的位置節點信息,並給它發送一個握手消息。

Redis Cluster是一個完整的網絡,在創建網絡時,並不需要給所有節點發送CLUSTER MEET命令,只要發送了足夠的命令,保證每個節點都有已知節點,其他的事情就交給gossip來處理了。

CLUSTER NODES

最早可用版本:3.0.0

時間複雜度:O(N),N是集羣中的節點數

該命令提供了當前連接節點所屬集羣的配置信息。信息格式和Redis集羣在磁盤上存儲使用的序列化格式完全一樣。

通常,如果你想知道hash slot與節點的關聯關係,你應該使用CLUSTER SLOTS命令。CLUSTER NODES主要用於管理任務,調試和配置監控。redis-trib也會使用該命令管理集羣。

命令的結構如下:

1<id> <ip:port> <flags> <master> <ping-sent> <pong-recv> <config-epoch> <link-state> <slot> <slot> ... <slot>

CLUSTER REPLICAS

最早可用版本:5.0.0

時間複雜度:O(1)

該命令會列出主節點的從節點列表。輸出格式與CLUSTER NODES格式相同。

若特定節點狀態未知,或在接收命令節點不是主節點,則命令失敗。

CLUSTER REPLICATE

最早可用版本:3.0.0

時間複雜度:O(1)

該命令重新配置一個節點成爲指定master的從節點。如果收到命令的節點是empty master,那麼該節點的角色將由master轉換爲slave。

一旦一個節點變成另一個master的slave,不需要將這一變化告知集羣內的其他節點,心跳消息會把最新配置同步給其他節點。

一個從節點接收這個命令需要滿足以下條件:

  1. 指定節點存在它的節點列表中

  2. 指定節點對接收命令的節點未知

  3. 指定節點是master

如果收到命令的節點不是slave而是master,只有在如下情況下,命令纔會執行成功:

  1. 該節點不保存任何hash slot

  2. 該節點是空的,key空間沒有任何key

CLUSTER RESET

最早可用版本:3.0.0

時間複雜度:O(N),N是已知節點的數量

根據reset類型(hard或soft)重置一個集羣的節點。當主節點hold住一個或多個key時,這個命令無法執行,必須先使用FLUSHALL命令刪除所有的key。該命令的影響是:

  1. 集羣中的節點都被忽略

  2. 所有已分配的slot會被reset,slots-to-nodes關係被完全清除

  3. 如果節點是slave,它會被切換成空master。

  4. Hard模式:生成新的節點ID

  5. Hard模式:currentEpoch和configEpoch被置爲0

  6. 新配置被持久化到節點磁盤上的集羣配置信息文件中

CLUSTER SAVECONFIG

最早可用版本:3.0.0

時間複雜度:O(1)

強制保存配置nodes.conf到磁盤。該命令主要用於nodes.conf文件丟失或刪除時重新生成文件。

CLUSTER SET-CONFIG-EPOCH

最早可用版本:3.0.0

時間複雜度:O(1)

該命令爲一個全新的節點設置config epoch,只在以下情況有效:

  1. 節點的節點信息表是空的

  2. 節點的config epoch是0

人工修改一個節點的config epoch是不安全的,但是當epoch產生衝突時,自動解決又非常慢,這時可以使用這個命令進行人工干預。

CLUSTER SETSLOT

最早可用版本:3.0.0

時間複雜度:O(1)

用法:CLUSTER SETSLOTslot IMPORTING|MIGRATING|STABLE|NODE [node-id]

CLUSTER SETSLOT根據子命令修改節點的hash slot狀態:

  1. MIGRATING:將一個hash slot設置爲migrating狀態

  2. IMPORTING:將一個hash slot設置爲importing狀態

  3. STABLE:清除migrating或importing狀態

  4. NODE:把hash slot綁定到其他節點

該命令通常在rehash時使用,將源節點的hash slot置爲migrating狀態,目標節點的hash slot置爲importing狀態。

  • CLUSTER SETSLOT

該命令將slot設置爲migrating狀態,接下來要處理的key如果存在,命令正常執行。如果不存在,則節點發出ASK重定向,讓客戶端去請求destination-node節點。對於批量key處理,如果只有部分節點存在,則返回TRYAGAIN錯誤。

  • CLUSTER SETSLOT

這是MIGRATING的反操作,接下來涉及該slot的命令都被拒絕,併產生一個MOVED重定向,除非命令跟着一個ASK重定向。

CLUSTER SLAVES

最早可用版本:3.0.0

時間複雜度:O(1)

該命令會列出指定master節點的所有slave節點,格式和CLUSTER NODES相同。當指定節點未知或不是master時,命令返回一個錯誤。

CLUSTER SLOTS

最早可用版本:3.0.0

時間複雜度:O(N),N是slot的總數

該命令返回slot和Redis實例的映射關係。這個命令對客戶端很有用,在執行命令時,客戶端會根據這個命令返回的信息去連接正確的節點執行命令。

每個節點的信息結構如下:

  • 起始slot編號

  • 結束slot編號

  • slot對應的master節點,用IP/Port表示

  • master節點的第一個副本

  • 第二個副本

READONLY

最早可用版本:3.0.0

時間複雜度:O(1)

開啓與Redis Cluster從節點連接的讀請求

通常從節點將重定向客戶端到認證過的主節點,以獲取在指定命令中所涉及的slot,然而客戶端可以通過READONLY命令將從節點設置爲只讀模式。

READONLY告訴Redis Cluster從節點願意讀取可能過時的數據。

當連接處於只讀模式,只有操作涉及到該從節點的主節點不服務的鍵時,集羣將會發送一個重定向給客戶端,這可能是因爲:

  1. 客戶端發送一個有關這個從節點的主節點不服務hash slot的命令

  2. 集羣被重新配置並且從節點不在服務給定hash slot的命令

READWRITE

最早可用版本:3.0.0

時間複雜度:O(1)

禁止與Redis Cluster從節點連接的讀請求。

默認情況下禁止Redis Cluster從節點的讀請求,但是可以使用READONLY去在每一個連接的基礎上改變這個行爲,READWRITE命令將連接的只讀模式重置爲讀寫模式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章