Redis集羣搭建與管理

集羣簡介:
Redis 集羣是一個能夠在多個 Redis 節點之間進行數據共享的設施(installation)。
Redis 集羣不支持那些須要同時處理多個鍵的 Redis 命令, 由於執行這些命令須要在多個 Redis 節點之間移動數據, 而且在高負載的狀況下, 這些命令將下降 Redis 集羣的性能, 並致使不可預測的行爲。
Redis 集羣經過分區(partition)來提供必定程度的可用性(availability): 即便集羣中有一部分節點失效或者沒法進行通信, 集羣也能夠繼續處理命令請求。
Redis 集羣提供瞭如下兩個好處:
將數據自動切分(split)到多個節點的能力。
當集羣中的一部分節點失效或者沒法進行通信時, 仍然能夠繼續處理命令請求的能力。
 
redis集羣數據共享:
Redis 集羣使用數據分片(sharding)而非一致性哈希(consistency hashing)來實現: 一個 Redis 集羣包含 16384 個哈希槽(hash slot), 數據庫中的每一個鍵都屬於這 16384 個哈希槽的其中一個, 集羣使用公式 CRC16(key) % 16384 來計算鍵 key 屬於哪一個槽, 其中 CRC16(key) 語句用於計算鍵 key 的 CRC16 校驗和 。
集羣中的每一個節點負責處理一部分哈希槽。 舉個例子, 一個集羣能夠有三個哈希槽, 其中:
節點 A 負責處理 0 號至 5500 號哈希槽。
節點 B 負責處理 5501 號至 11000 號哈希槽。
節點 C 負責處理 11001 號至 16384 號哈希槽。
這種將哈希槽分佈到不一樣節點的作法使得用戶能夠很容易地向集羣中添加或者刪除節點。 好比說:
若是用戶將新節點 D 添加到集羣中, 那麼集羣只須要將節點 A 、B 、 C 中的某些槽移動到節點 D 就能夠了。
與此相似, 若是用戶要從集羣中移除節點 A , 那麼集羣只須要將節點 A 中的全部哈希槽移動到節點 B 和節點 C , 而後再移除空白(不包含任何哈希槽)的節點 A 就能夠了。
由於將一個哈希槽從一個節點移動到另外一個節點不會形成節點阻塞, 因此不管是添加新節點仍是移除已存在節點, 又或者改變某個節點包含的哈希槽數量, 都不會形成集羣下線。
 
redis集羣中的主從複製:
爲了使得集羣在一部分節點下線或者沒法與集羣的大多數(majority)節點進行通信的狀況下, 仍然能夠正常運做, Redis 集羣對節點使用了主從複製功能: 集羣中的每一個節點都有 1 個至 N 個複製品(replica), 其中一個複製品爲主節點(master), 而其他的 N-1 個複製品爲從節點(slave)。
在以前列舉的節點 A 、B 、C 的例子中, 若是節點 B 下線了, 那麼集羣將沒法正常運行, 由於集羣找不到節點來處理 5501 號至 11000 號的哈希槽。
另外一方面, 假如在建立集羣的時候(或者至少在節點 B 下線以前), 咱們爲主節點 B 添加了從節點 B1 , 那麼當主節點 B 下線的時候, 集羣就會將 B1 設置爲新的主節點, 並讓它代替下線的主節點 B , 繼續處理 5501 號至 11000 號的哈希槽, 這樣集羣就不會由於主節點 B 的下線而沒法正常運做了。
不過若是節點 B 和 B1 都下線的話, Redis 集羣仍是會中止運做。
 
redis集羣的數據一致性:
Redis 集羣不保證數據的強一致性(strong consistency): 在特定條件下, Redis 集羣可能會丟失已經被執行過的寫命令。
使用異步複製(asynchronous replication)是 Redis 集羣可能會丟失寫命令的其中一個緣由。 考慮如下這個寫命令的例子:
客戶端向主節點 B 發送一條寫命令。
主節點 B 執行寫命令,並向客戶端返回命令回覆。
主節點 B 將剛剛執行的寫命令複製給它的從節點 B1 、 B2 和 B3 。
如你所見, 主節點對命令的複製工做發生在返回命令回覆以後, 由於若是每次處理命令請求都須要等待複製操做完成的話, 那麼主節點處理命令請求的速度將極大地下降 —— 咱們必須在性能和一致性之間作出權衡。
Redis 集羣另一種可能會丟失命令的狀況是, 集羣出現網絡分裂(network partition), 而且一個客戶端與至少包括一個主節點在內的少數(minority)實例被孤立。
舉個例子, 假設集羣包含 A 、 B 、 C 、 A1 、 B1 、 C1 六個節點, 其中 A 、B 、C 爲主節點, 而 A1 、B1 、C1 分別爲三個主節點的從節點, 另外還有一個客戶端 Z1 。
假設集羣中發生網絡分裂, 那麼集羣可能會分裂爲兩方, 大多數(majority)的一方包含節點 A 、C 、A1 、B1 和 C1 , 而少數(minority)的一方則包含節點 B 和客戶端 Z1 。
在網絡分裂期間, 主節點 B 仍然會接受 Z1 發送的寫命令:
若是網絡分裂出現的時間很短, 那麼集羣會繼續正常運行;
可是, 若是網絡分裂出現的時間足夠長, 使得大多數一方將從節點 B1 設置爲新的主節點, 並使用 B1 來代替原來的主節點 B , 那麼 Z1 發送給主節點 B 的寫命令將丟失。
注意, 在網絡分裂出現期間, 客戶端 Z1 能夠向主節點 B 發送寫命令的最大時間是有限制的, 這一時間限制稱爲節點超時時間(node timeout), 是 Redis 集羣的一個重要的配置選項:
對於大多數一方來講, 若是一個主節點未能在節點超時時間所設定的時限內從新聯繫上集羣, 那麼集羣會將這個主節點視爲下線, 並使用從節點來代替這個主節點繼續工做。
對於少數一方, 若是一個主節點未能在節點超時時間所設定的時限內從新聯繫上集羣, 那麼它將中止處理寫命令, 並向客戶端報告錯誤。
下面開始集羣的搭建和管理:首先介紹一下咱們的實驗環境
測試環境兩臺:
server1:172.16.16.34
server2:172.16.16.35
redis版本:redis3.2

搭建環境:redis集羣,server1有7001,7002,7003三主,server2有7001,7002,7003三從,總共六個節點。這樣作是爲了保證redis的集羣的高可用。redis的複製也是採用異步複製的方式。node

1,安裝redis
複製代碼
cd /home/maxiangqian
tar xzf redis-3.2.8.tar.gz
cd redis-3.2.8
yum install gcc
make
 
複製代碼

2:建立redis目錄文件夾web

在server1和server2上都建立相應的文件夾:
mkdir /home/redis7001/data
mkdir -p /home/redis7001/data /home/redis7001/log /home/redis7001/tmp
mkdir -p /home/redis7002/data /home/redis7002/log /home/redis7002/tmp
mkdir -p /home/redis7003/data /home/redis7003/log /home/redis7003/tmp

3:爲server1和server2的三個節點分別配置配置文件redis

以一個配置文件爲例:
複製代碼
port 7001
timeout 300
 
daemonize yes
pidfile "/home/redis7001/tmp/redis_7001.pid"
 
loglevel notice
logfile "/home/redis7001/log/redis_7001.log"
 
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename "dump.rdb"
dir "/home/redis7001/data"
 
slave-serve-stale-data yes
#slave-read-only yes # yes開啓從庫只讀
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
 
appendonly yes
#appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
 
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
 
requirepass "maxiangqianredis"
masterauth "maxiangqianredis"
 
#cluster
cluster-enabled yes
cluster-config-file /home/redis7001/nodes7001.conf
cluster-node-timeout 5000
複製代碼

上面是redis7001的配置文件內容mongodb

而後啓動7001的redis:
redis-server /home/redis7001/redis7001.conf

咱們看一下啓動日誌:數據庫

1574:M 03 May 16:22:53.444 * No cluster configuration found, I'm 363ecec54c92c2548dcab016146bdb4c104e5e84

 

每一個實例都會爲本身生成一個惟一的ID,用來識別集羣中的惟一身份。
而後使用一樣的方法啓動其他五個實例
複製代碼
server1 7001
server1 7002
server1 7003
server2 7001
server2 7002
server2 7003
複製代碼

OK,如今已經有六個已經啓動的redis實例了。咱們下一步開始作集羣ruby

 4:開始建立集羣
redis-trib.rb create --replicas 1 10.103.16.34:7001 10.103.16.34:7002 10.103.16.34:7003 10.103.16.35:7001 10.103.16.35:7002 10.103.16.35:7003

執行報錯:網絡

/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- redis (LoadError)
from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
from /home/maxiangqian/redis-3.2.8/src/redis-trib.rb:25

咱們須要安裝如下幾個包:app

yum -y install zlib ruby rubygems
gem install redis

而後從新啓動建立集羣的操做:less

[root@localhost redis7003]# redis-trib.rb create --replicas 1 10.103.16.34:7001 10.103.16.34:7002 10.103.16.34:7003 10.103.16.35:7001 10.103.16.35:7002 10.103.16.35:7003
>>> Creating cluster
[ERR] Sorry, can't connect to node 10.103.16.34:7001

又報錯了我擦。異步

網上各類搜資料諮詢,最好仍是發現不是什麼版本問題,是由於個人配置文件里加瞭如下兩行配置:
requirepass "maxiangqianredis"
masterauth "maxiangqianredis"

羣集認證是要配置完成再添加的,並且兩個參數配置必須同樣,咱們如今暫時不配置認證模式:

複製代碼
[root@localhost redis7003]# redis-trib.rb create --replicas 1 10.103.16.34:7001 10.103.16.34:7002 10.103.16.34:7003 10.103.16.35:7001 10.103.16.35:7002 10.103.16.35:7003
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
10.103.16.35:7001
10.103.16.34:7001
10.103.16.35:7002
Adding replica 10.103.16.34:7002 to 10.103.16.35:7001
Adding replica 10.103.16.35:7003 to 10.103.16.34:7001
Adding replica 10.103.16.34:7003 to 10.103.16.35:7002
M: 363ecec54c92c2548dcab016146bdb4c104e5e84 10.103.16.34:7001
slots:5461-10922 (5462 slots) master
S: 93a0e8d405959480fcbd310a5d15a92346c69d43 10.103.16.34:7002
replicates d015a22abc57c021f568973f4f1c03c7a5c7b772
S: 78f77749f9f9a5f0d7c99427e0311912a3fa04e7 10.103.16.34:7003
replicates 89147e5837e378b69233dd2b8290267975719bc4
M: d015a22abc57c021f568973f4f1c03c7a5c7b772 10.103.16.35:7001
slots:0-5460 (5461 slots) master
M: 89147e5837e378b69233dd2b8290267975719bc4 10.103.16.35:7002
slots:10923-16383 (5461 slots) master
S: ce9d635236567ccde4c864f78863fa0a4b26f25a 10.103.16.35:7003
replicates 363ecec54c92c2548dcab016146bdb4c104e5e84
Can I set the above configuration? (type 'yes' to accept):
複製代碼

OK,已經提示成功了,咱們直接選擇yes就行了。

複製代碼
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join..
>>> Performing Cluster Check (using node 10.103.16.34:7001)
M: 363ecec54c92c2548dcab016146bdb4c104e5e84 10.103.16.34:7001
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: 78f77749f9f9a5f0d7c99427e0311912a3fa04e7 10.103.16.34:7003
slots: (0 slots) slave
replicates 89147e5837e378b69233dd2b8290267975719bc4
M: d015a22abc57c021f568973f4f1c03c7a5c7b772 10.103.16.35:7001
slots:0-5460 (5461 slots) master
1 additional replica(s)
M: 89147e5837e378b69233dd2b8290267975719bc4 10.103.16.35:7002
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: ce9d635236567ccde4c864f78863fa0a4b26f25a 10.103.16.35:7003
slots: (0 slots) slave
replicates 363ecec54c92c2548dcab016146bdb4c104e5e84
S: 93a0e8d405959480fcbd310a5d15a92346c69d43 10.103.16.34:7002
slots: (0 slots) slave
replicates d015a22abc57c021f568973f4f1c03c7a5c7b772
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
複製代碼

這樣羣集就設置成功了。

查看一下集羣的狀態,測試一下:
在10.103.16.34:7001建立name測試字符串,而後驗證
複製代碼
[root@mxqmongodb2 sa]# redis-cli -c -p 7001
127.0.0.1:7001> get name
-> Redirected to slot [5798] located at 10.103.16.34:7001
"txt"
10.103.16.34:7001> exit
[root@mxqmongodb2 sa]# redis-cli -c -p 7002
127.0.0.1:7002> get name
-> Redirected to slot [5798] located at 10.103.16.34:7001
"txt"
10.103.16.34:7001> exit
[root@mxqmongodb2 sa]# redis-cli -c -p 7003
127.0.0.1:7003> get name
-> Redirected to slot [5798] located at 10.103.16.34:7001
"txt"
複製代碼

5:咱們接下來查看一下集羣的基本信息:

複製代碼
[root@localhost redis7003]# redis-cli -p 7001 cluster nodes
78f77749f9f9a5f0d7c99427e0311912a3fa04e7 10.103.16.34:7003 slave 89147e5837e378b69233dd2b8290267975719bc4 0 1493879665448 5 connected
d015a22abc57c021f568973f4f1c03c7a5c7b772 10.103.16.35:7001 master - 0 1493879663946 4 connected 0-5460
89147e5837e378b69233dd2b8290267975719bc4 10.103.16.35:7002 master - 0 1493879664948 5 connected 10923-16383
ce9d635236567ccde4c864f78863fa0a4b26f25a 10.103.16.35:7003 slave 363ecec54c92c2548dcab016146bdb4c104e5e84 0 1493879665949 6 connected
93a0e8d405959480fcbd310a5d15a92346c69d43 10.103.16.34:7002 slave d015a22abc57c021f568973f4f1c03c7a5c7b772 0 1493879664446 4 connected
363ecec54c92c2548dcab016146bdb4c104e5e84 10.103.16.34:7001 myself,master - 0 0 1 connected 5461-10922
複製代碼

能夠看到如今的集羣有六個節點,三個主節點和三個從節點。並且每一個主節點都會記錄本身分配的哈希槽,從中咱們能夠看到

103.16.35:7001 master - 0 1493879663946 4 connected 0-5460
10.103.16.34:7001 myself,master - 0 0 1 connected 5461-10922
10.103.16.35:7002 master - 0 1493879664948 5 connected 10923-16383

固然咱們也能夠對這些節點的哈希槽進行從新的分配,咱們如今打算將103.16.35:7001的前100個哈希槽移動到10.103.16.34:7001

[root@localhost redis7003]# redis-trib.rb reshard 10.103.16.34:7001

而後會提示我輸入數值以及從哪裏遷移到哪裏:

複製代碼
How many slots do you want to move (from 1 to 16384)? 100
What is the receiving node ID? 363ecec54c92c2548dcab016146bdb4c104e5e84
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1:d015a22abc57c021f568973f4f1c03c7a5c7b772
Source node #2:done
複製代碼

執行完之後就能夠進行遷移了,遷移完之後咱們再打印出來節點信息看一下:

複製代碼
[root@localhost redis7003]# redis-cli -p 7001 cluster nodes
78f77749f9f9a5f0d7c99427e0311912a3fa04e7 10.103.16.34:7003 slave 89147e5837e378b69233dd2b8290267975719bc4 0 1493881167965 5 connected
d015a22abc57c021f568973f4f1c03c7a5c7b772 10.103.16.35:7001 master - 0 1493881166460 4 connected 101-5460
89147e5837e378b69233dd2b8290267975719bc4 10.103.16.35:7002 master - 0 1493881166962 5 connected 10923-16383
ce9d635236567ccde4c864f78863fa0a4b26f25a 10.103.16.35:7003 slave 363ecec54c92c2548dcab016146bdb4c104e5e84 0 1493881167465 7 connected
93a0e8d405959480fcbd310a5d15a92346c69d43 10.103.16.34:7002 slave d015a22abc57c021f568973f4f1c03c7a5c7b772 0 1493881167965 4 connected
363ecec54c92c2548dcab016146bdb4c104e5e84 10.103.16.34:7001 myself,master - 0 0 7 connected 0-100 5461-10922
複製代碼

咱們能夠很清楚的看到已經遷移成功了。

 
6:咱們來測試一下集羣的故障轉移功能
首先咱們要看一下集羣的主節點信息:
[root@localhost redis7003]# redis-cli -p 7001 cluster nodes | grep master
d015a22abc57c021f568973f4f1c03c7a5c7b772 10.103.16.35:7001 master - 0 1493883826713 4 connected 101-5460
89147e5837e378b69233dd2b8290267975719bc4 10.103.16.35:7002 master - 0 1493883827213 5 connected 10923-16383
363ecec54c92c2548dcab016146bdb4c104e5e84 10.103.16.34:7001 myself,master - 0 0 7 connected 0-100 5461-10922

咱們如今要使10.103.16.35:7001這個主節點斷掉,而後重啓看一下基本信息

[root@mxqmongodb2 sa]# /home/maxiangqian/redis-3.2.8/src/redis-cli -p 7001
127.0.0.1:7001> SHUTDOWN
not connected> exit
[root@mxqmongodb2 sa]# redis-server /home/redis7001/redis7001.conf

而後再打印一下集羣信息看一下:

複製代碼
[root@localhost redis7003]# redis-cli -p 7001 cluster nodes
78f77749f9f9a5f0d7c99427e0311912a3fa04e7 10.103.16.34:7003 slave 89147e5837e378b69233dd2b8290267975719bc4 0 1493884247801 5 connected
d015a22abc57c021f568973f4f1c03c7a5c7b772 10.103.16.35:7001 slave 93a0e8d405959480fcbd310a5d15a92346c69d43 0 1493884247300 8 connected
89147e5837e378b69233dd2b8290267975719bc4 10.103.16.35:7002 master - 0 1493884246798 5 connected 10923-16383
ce9d635236567ccde4c864f78863fa0a4b26f25a 10.103.16.35:7003 slave 363ecec54c92c2548dcab016146bdb4c104e5e84 0 1493884246298 7 connected
93a0e8d405959480fcbd310a5d15a92346c69d43 10.103.16.34:7002 master - 0 1493884248301 8 connected 101-5460
363ecec54c92c2548dcab016146bdb4c104e5e84 10.103.16.34:7001 myself,master - 0 0 7 connected 0-100 5461-10922
複製代碼

經過信息咱們能夠很明顯的看到了10.103.16.35:7001這個主節點已經變成了從節點,而自己他的從節點也上升爲主節點了。

可是咱們須要注意的是在故障轉移的時間段內,一些10.103.16.35:7001的寫操做是會丟失的。直到他的從庫提高爲主庫爲止,這是redis爲了保證數據一致性而採起的措施。
 
7:集羣的節點管理:
咱們先看一下怎麼添加節點,添加節點分爲兩類(主節點或者從節點)
主節點:
./redis-trib.rb add-node 10.103.16.34:7004 10.103.16.34:7001

這樣咱們就把10.103.16.34:7004添加爲集羣的新的主節點,不過咱們要注意的是,這時候他僅僅是一個沒有哈希槽的主節點,並不會存儲任何數據。

咱們可使用 redis-trib 程序, 將集羣中的某些哈希桶移動到新節點裏面, 新節點就會成爲真正的主節點了。
從節點:
./redis-trib.rb add-node 10.103.16.34:7004 10.103.16.34:7001
redis 10.103.16.34::7004> cluster replicate 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e

將新節點指定爲ID爲3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e的從節點。

接下來咱們看一下怎麼移除某個節點,語法格式以下:
./redis-trib del-node 127.0.0.1:7000 `<node-id>`

可是咱們要注意一點,移除主節點的時候必須保證主節點是空的,也就是事先將要移除的主節點的哈希槽給轉移到其餘的主節點上。

 

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 列表
複製代碼

redis 有不少命令,贊成,加入到cluster後,也有一些列的命令,如今一一來看下 (http://redis.io/commands/cluster-addslots):

 

咱們來一個一個的實踐一下。

我按照上一篇的理論實踐知識的基礎上,再次搭建了一個集羣,此次運行了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個Master5個slave。OK,如今咱們來一一試一下上述的CLUSTER *命令。

 

cluster info

這個命令是顯示當前鏈接的集羣的各類信息。

 
複製代碼
[root@web3 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
複製代碼

嗯。節點被移除了。

可是,實際上是沒有真正移除!不知道爲啥。

複製代碼
 
[vagrant@web3 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]

並且也還能連上:

 
[vagrant@web3 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,說明設置成功了,那我推出cliredis-trib看下:

 
複製代碼
[root@web3 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文件:

 
複製代碼
[root@web3 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
[root@web3 7009]# rm -rf nodes.conf
[root@web3 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
[root@web3 7009]# redis-cli -p 7009 -c
127.0.0.1:7009> cluster saveconfig
OK
127.0.0.1:7009> exit
[root@web3 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
[root@web3 7009]#
複製代碼
 

cluster delslots

移除當前節點的一個或多個槽點。只能刪除本身的節點,刪除別人的沒用。

由於master纔會有槽點,因此,也是隻能在master 節點上操做,在slave 操做也沒用。

用法是:

cluster delslots slots1 slotes2 slots3

咱們看一下槽點的分配狀況:

 
[root@web3 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個槽點給刪掉。

開始:

 
[root@web3 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檢查一下,就知道了:

複製代碼
[root@web3 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看看。

 
複製代碼
[root@web3 ~]# 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 ,把她給移會去。可憐。。。

 
[root@web3 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 下:

 
複製代碼
[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)
...
>>> 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.

剛纔那個錯誤消息了。好吧。繼續學習其它命令吧。

cluster keyslot <\key>

計算鍵 key 應該被放置在哪一個槽上。這個是個蠻不錯的功能。有時候很想找一個key在哪一個節點。看下能不能用。

 
127.0.0.1:7000> cluster keyslot name
(integer) 5798
127.0.0.1:7000> get name
-> Redirected to slot [5798] located at 192.168.33.13:7001
"123"
192.168.33.13:7001>

這個很簡單,就是一個運算,以前也講過: CRC16('name')%16384 = 5798

cluster countkeysinslot <\slot>

計算一個slot 包含多少個key。這也是一個很使用的小功能。

試一下:

 
192.168.33.13:7001> cluster countkeysinslot 5798
(integer) 1

因爲是測試,因此,slot裏數據不多,這裏顯示1個,估計就是上面的name

cluster getkeysinslot <\slot> <\count>

返回 一個 slot 中 count 個 key 的集合。 也是一個蠻實用的功能。

試一下:

 
127.0.0.1:7000> cluster getkeysinslot 5798 1
(empty list or set)

 那設置幾個值吧:

  
複製代碼
192.168.33.13:7000> set name1 yangyi
-> Redirected to slot [12933] located at 192.168.33.13:7003
OK
192.168.33.13:7003> set name2 yangyi
-> Redirected to slot [742] located at 192.168.33.13:7000
OK
192.168.33.13:7000> set name3 yangyi
-> Redirected to slot [4807] located at 192.168.33.13:7001
OK
192.168.33.13:7001> set name4 yangyi
-> Redirected to slot [8736] located at 192.168.33.13:7002
OK
192.168.33.13:7002> set name5 yangyi
-> Redirected to slot [12801] located at 192.168.33.13:7003
OK
192.168.33.13:7003> set name6 yangyi
-> Redirected to slot [610] located at 192.168.33.13:7000
OK
192.168.33.13:7000> set name7 yangyi
-> Redirected to slot [4675] located at 192.168.33.13:7001
OK
192.168.33.13:7001>
複製代碼
好。咱們再取一下:
192.168.33.13:7001> cluster getkeysinslot 4675 1
1) "name7"

cluster slaves <\node-id>

返回一個master節點的slaves 列表 

192.168.33.13:7001> cluster slaves 7b39b81b5ba94a9f4d96931dd0879cc13dab6f07
1) "f8c7a3113497d8d828bdb05fec4041b382e5fd0a 192.168.33.13:7005 slave 7b39b81b5ba94a9f4d96931dd0879cc13dab6f07
0 1450671948824 6 connected"

cluster nodes命令查看的結果是同樣的。

相關文章
相關標籤/搜索