2. Redis 3.0.5 叢集的命令、使用、維護
前言
上一篇中,對redis cluster的有了較為深入的實踐,並且一整套都實踐了,redis cluster 確實挺好用,隨著版本的更新,它會越來越成熟和穩定,一定是未來的方向。
這一篇對後續的一些尾巴來學習下,包括 CLUSTER *
一系列命令,以及容災性的資料遷移,以及在php的使用。
cluster命令
CLUSTER INFO
列印叢集的資訊CLUSTER NODES
列出叢集當前已知的所有節點(node),以及這些節點的相關資訊。
//節點CLUSTER MEET <ip> <port>
將 ip 和 port 所指定的節點新增到叢集當中,讓它成為叢集的一份子。CLUSTER FORGET <node_id>
從叢集中移除 node_id 指定的節點。CLUSTER REPLICATE <node_id>
將當前節點設定為 node_id 指定的節點的從節點。CLUSTER SAVECONFIG
將節點的配置檔案儲存到硬盤裡面。CLUSTER ADDSLOTS <slot> [slot ...]
將一個或多個槽(slot)指派(assign)給當前節點。CLUSTER DELSLOTS <slot> [slot ...]
移除一個或多個槽對當前節點的指派。CLUSTER FLUSHSLOTS
移除指派給當前節點的所有槽,讓當前節點變成一個沒有指派任何槽的節點。CLUSTER SETSLOT <slot> NODE <node_id>
將槽 slot 指派給 node_id 指定的節點。CLUSTER SETSLOT <slot> MIGRATING <node_id>
將本節點的槽 slot 遷移到 node_id 指定的節點中。CLUSTER SETSLOT <slot> IMPORTING <node_id>
從 node_id 指定的節點中匯入槽 slot 到本節點。CLUSTER SETSLOT <slot> STABLE
取消對槽 slot 的匯入(import)或者遷移(migrate)。
//鍵CLUSTER KEYSLOT <key>
計算鍵 key 應該被放置在哪個槽上。CLUSTER COUNTKEYSINSLOT <slot>
返回槽 slot 目前包含的鍵值對數量。CLUSTER GETKEYSINSLOT <slot> <count>
返回 count 個 slot 槽中的鍵。
//新增CLUSTER SLAVES node-id
返回一個master節點的slaves 列表
我們來一個一個的實踐一下。
我按照上一篇的理論實踐知識的基礎上,再次搭建了一個叢集,這次運行了8個埠,用實際的ip代替127.0.0.1:
redis-trib.rb create --replicas 1 192.168.33.13:7000 192.168.33.13:7001 192.168.33.13:7002 192.168.33.13:7003 192.168.33.13:7004 192.168.33.13:7005 192.168.33.13:7006 192.168.33.13:7007 192.168.33.13:7008
這個命令過後,就會建立一個redis cluster 叢集,包括4個Master
和5個slave
。OK,現在我們來一一試一下上述的CLUSTER *
命令。
cluster info
這個命令是顯示當前連線的叢集的各種資訊。
[[email protected] 7008]# redis-cli -c -p 7000
127.0.0.1:7000> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:9
cluster_size:4
cluster_current_epoch:9
cluster_my_epoch:1
cluster_stats_messages_sent:41417
cluster_stats_messages_received:41417
- cluster_state:叢集的狀態。
ok
表示叢集是成功的,如果至少有一個solt
壞了,就將處於error
狀態。 - cluster_slots_assigned:有多少槽點被分配了,如果是16384,表示全部槽點已被分配。
- cluster_slots_ok:多少槽點狀態是OK的, 16384 表示都是好的。
- cluster_slots_pfail:多少槽點處於暫時
疑似下線[PFAIL]
狀態,這些槽點疑似出現故障,但並不表示是有問題,也會繼續提供服務。 - cluster_slots_fail:多少槽點處於暫時
下線[FAIL]
狀態,這些槽點已經出現故障,下線了。等待修復解決。 - cluster_known_nodes:已知節點的叢集中的總數,包括在節點 握手的狀態可能不是目前該叢集的成員。這裡總公有9個。
- cluster_size:(The number of master nodes serving at least one hash slot in the cluster) 簡單說就是叢集中主節點[Master]的數量。
- cluster_current_epoch:本地當前時期變數。這是使用,以創造獨特的不斷增加的版本號過程中失敗接管。{不懂}
- cluster_my_epoch:這是分配給該節點的當前配置版本。{不懂}
cluster_stats_messages_sent:通過群集節點到節點的二進位制匯流排傳送的訊息數。
cluster_stats_messages_received:通過群集節點到節點的二進位制總線上接收報文的數量。
cluster nodes
獲取叢集上的所有的節點資訊。一般這個命令用的比較多。
127.0.0.1:7008> cluster nodes
8916fb224bbae3dc0291ca47e066dca0a62fba19 192.168.33.13:7004 slave 3d2b7dccfc45ae2eb7aeb9e0bf001b0ac8f7b3da 0 1446115185933 5 connected
404cf1ecf54d4df46d5faaec4103cfdf67888ad2 192.168.33.13:7001 master - 0 1446115184929 2 connected 4096-8191
a035546046a607487436cf354c187b1712edf39b 192.168.33.13:7006 slave 6f5cd78ee644c1df9756fc11b3595403f51216cc 0 1446115184929 7 connected
6f5cd78ee644c1df9756fc11b3595403f51216cc 192.168.33.13:7002 master - 0 1446115185432 3 connected 8192-12287
f325d80e770ce319e4490818a49bad033cce942c 192.168.33.13:7008 myself,slave 3d2b7dccfc45ae2eb7aeb9e0bf001b0ac8f7b3da 0 0 9 connected
e357bea5151b32a971c1f7a5788271106195f99a 192.168.33.13:7005 slave 404cf1ecf54d4df46d5faaec4103cfdf67888ad2 0 1446115186435 6 connected
3d2b7dccfc45ae2eb7aeb9e0bf001b0ac8f7b3da 192.168.33.13:7000 master - 0 1446115184426 1 connected 0-4095
6650a95b874cacf399f174cb7a1b3802fc9bcef9 192.168.33.13:7007 slave 35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 0 1446115184426 8 connected
35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003 master - 0 1446115184426 4 connected 12288-16383
先看下每一條的結構:
<id> <ip:port> <flags> <master> <ping-sent> <pong-recv> <config-epoch> <link-state> <slot> <slot> ... <slot>
[節點id] [ip:埠] [標誌(master、myself、salve)] [(- 或者主節id)] [ping傳送的毫秒UNIX時間,0表示沒有ping] [pong接收的unix毫秒時間戳] [配置-epoch] [連線狀態] [槽點]
cluster meet
將 ip 和 port 所指定的節點新增到叢集當中,讓它成為叢集的一份子
我們一般會用redis-trib.rb add-node 192.168.33.13:7009 192.168.33.13:7000
這種方式將一個節點加入佇列。這是不需要連線redis-cli
客戶端。
其實,也可以用cluster meet
命令,使用方法:
cluster meet <ip> <port>
我們來實踐下,新建一個7009
新節點,然後試著用這個命令加入到叢集中來:
127.0.0.1:7000> cluster meet 192.168.33.13 7009
OK
127.0.0.1:7000> cluster nodes
....
70795a3a7b93b7d059124e171cd46ba1683d6b7d 192.168.33.13:7009 master - 0 1446198910590 0 connected
現在7009
已經成功加入到來叢集當中,同樣,還沒有分配槽點給它。槽點分配在下面的命令中再仔細說。
cluster forget
從叢集中移除一個節點。這個功能:
redis-trib del-node 192.168.33.13:7009 `<node-id>`
類似。同樣,刪除從節點,可以直接刪除。刪除主節點,要是有slot的話需要先遷移。
我們就來刪除上一步加的這個192.168.33.13 7009
,他是一個master 節點,但是裡面還沒分配slot,所以,我們刪除試一下:
使用方法為:
cluster forget <node_id>
開始:
127.0.0.1:7000> cluster forget 70795a3a7b93b7d059124e171cd46ba1683d6b7d
OK
提示OK了,說明已經成功了。
再看下node 列表:
127.0.0.1:7000> cluster nodes
a035546046a607487436cf354c187b1712edf39b 192.168.33.13:7006 slave 6f5cd78ee644c1df9756fc11b3595403f51216cc 0 1448519211988 7 connected
f325d80e770ce319e4490818a49bad033cce942c 192.168.33.13:7008 slave 3d2b7dccfc45ae2eb7aeb9e0bf001b0ac8f7b3da 0 1448519212994 9 connected
e357bea5151b32a971c1f7a5788271106195f99a 192.168.33.13:7005 slave 404cf1ecf54d4df46d5faaec4103cfdf67888ad2 0 1448519213499 6 connected
8916fb224bbae3dc0291ca47e066dca0a62fba19 192.168.33.13:7004 slave 3d2b7dccfc45ae2eb7aeb9e0bf001b0ac8f7b3da 0 1448519212994 5 connected
35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003 master - 0 1448519211485 4 connected 12288-16383
3d2b7dccfc45ae2eb7aeb9e0bf001b0ac8f7b3da 192.168.33.13:7000 myself,master - 0 0 1 connected 0-4095
6650a95b874cacf399f174cb7a1b3802fc9bcef9 192.168.33.13:7007 slave 35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 0 1448519212493 8 connected
6f5cd78ee644c1df9756fc11b3595403f51216cc 192.168.33.13:7002 master - 0 1448519213499 3 connected 8192-12287
404cf1ecf54d4df46d5faaec4103cfdf67888ad2 192.168.33.13:7001 master - 0 1448519213499 2 connected 4096-8191
嗯。節點被移除了。
但是,其實是沒有真正移除!不知道為啥。
[[email protected] 7009]$ redis-trib.rb check 192.168.33.13:7009
Connecting to node 192.168.33.13:7009: OK
Connecting to node 192.168.33.13:7004: OK
Connecting to node 192.168.33.13:7007: OK
Connecting to node 192.168.33.13:7000: OK
Connecting to node 192.168.33.13:7008: OK
Connecting to node 192.168.33.13:7006: OK
Connecting to node 192.168.33.13:7003: OK
Connecting to node 192.168.33.13:7005: OK
Connecting to node 192.168.33.13:7001: OK
Connecting to node 192.168.33.13:7002: OK
程序也還在。
[vagrant@web3 7009]$ ps -ef|grep redis
root 3017 1 0 Nov23 ? 00:04:24 redis-server *:7009 [cluster]
而且也還能連上:
[[email protected] 7009]$ redis-cli -p 7009 -c
127.0.0.1:7009> cluster nodes
70795a3a7b93b7d059124e171cd46ba1683d6b7d 192.168.33.13:7009 myself,master - 0 0 0 connected
日了狗了!!!!為啥啊。不管啦。繼續。
cluster replicate
將當前節點
設定為 node_id 指定的節點的從節點
。
既然剛才沒把7009刪掉,那就用這個命令把它設定成7003的從節點吧。
使用方法為:
cluster replicate <master_nodeId>
先用7009連線
[root@web3 7009]# redis-cli -p 7009 -c
127.0.0.1:7009> cluster replicate 35bdcb51ceeff00f9cc608fa1b4364943c7c07ce
OK
OK了,說明成功了,我們再看下:
127.0.0.1:7009> cluster nodes
...
b3917e10123230f2f5b0e2c948a7eeda7f88ccf7 192.168.33.13:7009 myself,slave 35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 0 0 0 connected
357bea5151b32a971c1f7a5788271106195f99a 192.168.33.13:7003 master - 0 1448525721782 4 connected 12288-16383
OK,說明設定成功了,那我推出cli
用redis-trib
看下:
[[email protected] 7009]# redis-trib.rb check 192.168.33.13:7000
Connecting to node 192.168.33.13:7009: OK
M: 35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003
slots:12288-16383 (4096 slots) master
2 additional replica(s)
S: 6650a95b874cacf399f174cb7a1b3802fc9bcef9 192.168.33.13:7007
slots: (0 slots) slave
replicates 35bdcb51ceeff00f9cc608fa1b4364943c7c07ce
S: b3917e10123230f2f5b0e2c948a7eeda7f88ccf7 192.168.33.13:7009
slots: (0 slots) slave
replicates 35bdcb51ceeff00f9cc608fa1b4364943c7c07ce
成功了!
cluster saveconfig
將節點的配置檔案儲存到硬盤裡面.
試一下:
127.0.0.1:7009> cluster saveconfig
OK
ok說明成功了,它會覆蓋配置資料夾裡的nodes.conf
檔案。這樣做是為了某種情況下nodes檔案丟失,這樣就會生成一個最新的節點配置檔案。
為了說明是新生成的,我們可以先刪除掉7009目錄下的nodes.conf
檔案:
[[email protected] 7009]# ll
total 52
-rw-r--r-- 1 root root 0 Nov 26 08:14 appendonly.aof
-rw-r--r-- 1 root root 18 Nov 26 08:14 dump.rdb
-rw-r--r-- 1 root root 1269 Nov 26 08:50 nodes.conf
-rw-r--r-- 1 root root 41550 Oct 30 03:40 redis.conf
[[email protected] 7009]# rm -rf nodes.conf
[[email protected] 7009]# ll
total 42
-rw-r--r-- 1 root root 0 Nov 26 08:14 appendonly.aof
-rw-r--r-- 1 root root 18 Nov 26 08:14 dump.rdb
-rw-r--r-- 1 root root 41550 Oct 30 03:40 redis.conf
[[email protected] 7009]# redis-cli -p 7009 -c
127.0.0.1:7009> cluster saveconfig
OK
127.0.0.1:7009> exit
[[email protected] 7009]# ll
total 52
-rw-r--r-- 1 root root 0 Nov 26 08:14 appendonly.aof
-rw-r--r-- 1 root root 18 Nov 26 08:14 dump.rdb
-rw-r--r-- 1 root root 1269 Nov 26 08:51 nodes.conf
-rw-r--r-- 1 root root 41550 Oct 30 03:40 redis.conf
[[email protected] 7009]#
cluster delslots
移除當前節點
的一個或多個槽點。只能刪除自己的節點,刪除別人的沒用。
因為master才會有槽點,所以,也是隻能在master 節點上操作,在slave 操作也沒用。
用法是:
cluster delslots slots1 slotes2 slots3
我們看一下槽點的分配情況:
[[email protected] 7009]# redis-cli -p 7009 -c cluster nodes| grep master
3d2b7dccfc45ae2eb7aeb9e0bf001b0ac8f7b3da 192.168.33.13:7000 master - 0 1448529511113 1 connected 0-4095
404cf1ecf54d4df46d5faaec4103cfdf67888ad2 192.168.33.13:7001 master - 0 1448529511113 2 connected 4096-8191
6f5cd78ee644c1df9756fc11b3595403f51216cc 192.168.33.13:7002 master - 0 1448529509101 3 connected 8192-12287
35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003 master - 0 1448529510609 4 connected 12288-16383
4臺master,那就把16381 16382 16383 3個槽點給刪掉。
開始:
[[email protected] 7009]# redis-cli -p 7003
127.0.0.1:7003> cluster delslots 16381 16382 16383
OK
127.0.0.1:7003> cluster nodes
35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003 myself,master - 0 0 4 connected 12288-16380
看,7003的缺失少了3個節點。我們在看下cluster info
127.0.0.1:7003> cluster info
cluster_state:fail
cluster_slots_assigned:16381
cluster_slots_ok:16381
只有16381個,確實少了4個。但是,注意:cluster_state:fail
,叢集失敗了!!!
為什麼呢?為什麼刪除了3個槽點就失敗了呢。因為叢集就是要滿足所有的16364個槽點全部分配才會成功。所以。就失敗了。
資料讀取自然也會失敗:
127.0.0.1:7003> get name
(error) CLUSTERDOWN The cluster is down
我們用redis-trib
檢查一下,就知道了:
[[email protected] 7009]# redis-trib.rb check 192.168.33.13:7000
...
...
[ERR] Nodes don't agree about configuration!
>>> Check for open slots...
>>> Check slots coverage...
[ERR] Not all 16384 slots are covered by nodes.
那如何挽救呢?那就順便看下下面的這個命令吧。
cluster addslots
將一個或多個槽(slot)指派(assign)給當前節點
。
用法是:
cluster addslots slots1 slotes2 slots3
那,我就用這個命令將上面刪掉的3個槽點再加到7003上看看:
127.0.0.1:7003> cluster addslots 16381 16382 16383
OK
127.0.0.1:7003>
OK了,看下是不是真的成功了:
127.0.0.1:7003> cluster nodes
35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003 myself,master - 0 0 4 connected 12288-16383
確實回來了,再看下叢集狀態,啟動了沒?
127.0.0.1:7003> cluster info
cluster_state:ok
資料讀取也正常了:
127.0.0.1:7003> get name
-> Redirected to slot [5798] located at 192.168.33.13:7001
"123"
192.168.33.13:7001>
cluster flushslots
移除當前節點
的所有
槽點,讓當前節點變成一個沒有指派任何槽的節點。
我們還是拿7003來開刀吧。誰叫它在最後呢哈哈哈哈哈哈��
[root@web3 ~]# redis-cli -p 7003 -c
127.0.0.1:7003> cluster flushslots
OK
ok了,理論上7003上的槽點應該都被移除了,它被懸空了,那麼叢集也應該失效了吧。看看:
127.0.0.1:7003> cluster info
cluster_state:fail
cluster_slots_assigned:12288
cluster_slots_ok:12288
果然,移除了7003的所有4006個槽點,而且叢集也失敗了。用redis-trib
看看。
[[email protected] ~]# redis-trib.rb check 192.168.33.13:7000
M: 35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003
slots: (0 slots) master
2 additional replica(s)
[ERR] Nodes don't agree about configuration!
>>> Check for open slots...
>>> Check slots coverage...
[ERR] Not all 16384 slots are covered by nodes.
可憐的7003上,已經沒有任何slot了。
cluster setslot <\slot> node <\node_id>
將slot 指派給 node_id指定的節點,如果槽已經指派給另一個節點,那麼先讓另一個節點刪除該槽,然後再進行指派。
剛才7003的全部slot已經空出來了,那用這個命令試一下轉移。
開始搞,把12288-16384 這中間的幾個節點移動到7002上去。
127.0.0.1:7003> cluster setslot 16383 node 6f5cd78ee644c1df9756fc11b3595403f51216cc
OK
127.0.0.1:7003> cluster setslot 16382 node 6f5cd78ee644c1df9756fc11b3595403f51216cc
OK
媽的,這個命令只能一個一個的移動,太變態了!!!
那看看。剛才移動的幾個好了沒?
127.0.0.1:7003> cluster nodes
6f5cd78ee644c1df9756fc11b3595403f51216cc 192.168.33.13:7002 master - 0 1448611602575 3 connected 8192-12287 16382-16383
果然,這2個slot被移動過來了。那,再移動下,把 16382 丟給 7000看看:
127.0.0.1:7003> cluster setslot 16382 node 3d2b7dccfc45ae2eb7aeb9e0bf001b0ac8f7b3da
OK
看看好了沒?
127.0.0.1:7003> cluster nodes
3d2b7dccfc45ae2eb7aeb9e0bf001b0ac8f7b3da 192.168.33.13:7000 master - 0 1448611827539 1 connected 0-4095 16382
嗯,已經移動過來了。
cluster setslot <\slot> migrating <\destination-node-id>
將本節點
的槽 slot 遷移到 node_id 指定的節點中
試一下 16382 ,把她給移會去。可憐。。。
[[email protected] 7000]# redis-cli -p 7002 -c
127.0.0.1:7002> cluster setslot 16383 migrating 35bdcb51ceeff00f9cc608fa1b4364943c7c07ce
(error) ERR I'm not the owner of hash slot 16383
居然出錯了!!!為啥啊。說 16383 不是 7002的槽點,無法移動。我了個叉,怎麼會不是呢?
我看下:
6f5cd78ee644c1df9756fc11b3595403f51216cc 192.168.33.13:7002 myself,master - 0 0 3 connected 8192-12287
35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003 master - 0 1448619265700 4 connected 12288-16383
我了個擦的。確實不是啊。我明明已經把7003的槽點全部置空了啊,為什麼這裡還有啊。日了狗啊。
進 7003看看呢?
[root@web3 7000]# redis-cli -p 7003 -c
看看:
127.0.0.1:7003> cluster nodes
35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003 myself,master - 0 0 4 connected
6f5cd78ee644c1df9756fc11b3595403f51216cc 192.168.33.13:7002 master - 0 1448619384580 3 connected 8192-12287 16383
嗶了狗了,居然2邊的資訊不一樣!!!我擦。這尼瑪。
我退出去check看看。
[root@web3 7000]# redis-trib.rb check 192.168.33.13:7000
看看結果:
M: 35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003
slots: (0 slots) master
2 additional replica(s)
M: 6f5cd78ee644c1df9756fc11b3595403f51216cc 192.168.33.13:7002
slots:8192-12287 (4096 slots) master
1 additional replica(s)
我日了,16383 和 16382 用上面的setslot <slot> node <node_id>
根本沒移動過去,這尼瑪。無語了。。。不管了吧。繼續下面的命令學習吧。
cluster setslot <\slot> importing <\node_id>
從 node_id 指定的節點中匯入 slot 到本節點。
上面的命令居然失效了,日了狗,現在看下這個命令呢?
127.0.0.1:7003> cluster setslot 16383 importing 6f5cd78ee644c1df9756fc11b3595403f51216cc
OK
127.0.0.1:7003>
將 7002 上的 18383轉移到 7003上來,居然成功了。好吧。��
127.0.0.1:7003> cluster nodes
35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003 myself,master - 0 0 4 connected [16383-<-6f5cd78ee644c1df9756fc11b3595403f51216cc]
6f5cd78ee644c1df9756fc11b3595403f51216cc 192.168.33.13:7002 master - 0 1448621921706 3 connected 8192-12287 16383
居然顯示成這樣的,屌屌屌。然而,16383還在 7002上。哎。無法理解。
check 下:
[[email protected] 7000]# redis-trib.rb check 192.168.33.13:7000
...
M: 35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003
slots: (0 slots) master
2 additional replica(s)
...
>>> Check for open slots...
[WARNING] Node 192.168.33.13:7003 has slots in importing state (16383).
[WARNING] The following slots are open: 16383
>>> Check slots coverage...
[ERR] Not all 16384 slots are covered by nodes.
它提示叢集失敗,說正在匯入!什麼鬼啊。完全搞不懂。跳過吧,看下一個命令:
cluster setslot <\slot> stable
取消 slot 的匯入(import)或者遷移(migrate)。
這個命令屌啊,還可以反悔啊。趕緊試一試:
127.0.0.1:7003> cluster setslot 16383 stable
OK
看下回去了沒?
127.0.0.1:7003> cluster nodes
35bdcb51ceeff00f9cc608fa1b4364943c7c07ce 192.168.33.13:7003 myself,master - 0 0 4 connected
6f5cd78ee644c1df9756fc11b3595403f51216cc 192.168.33.13:7002 master - 0 1448623146511 3 connected 8192-12287 16383
果然回去了,贊贊贊。再 check 下:
[ERR] Nodes don't agree about configuration!
>>> Check for open slots...
>>> Check slots coverage...
[ERR] Not all 16384 slots are covered by nodes.
剛才那個錯誤訊息了。好吧。繼