redis集羣搭建

                                                                    redis集羣搭建


一、下載redis 編譯

redis-4.0.8.tar.gz


二、建6個目錄

[root@server1 ~]# cd /usr/local/
[root@server1 local]# mkdir rediscluster    #先建一個根目錄

[root@server1 local]# cd rediscluster/
[root@server1 rediscluster]# mkdir 700{1..6} 


Screenshot from 2018-07-03 22-36-52.png


注:與大多數分佈式中間件一樣,redis的cluster也是依賴選舉算法來保證集羣的高可用,所以類似ZK一樣,一般是奇數個節點(可以允許N/2以 下的節點失效),再考慮到每個節點做Master-Slave互爲備份,所以一個redis cluster集羣最少也得6個節點


三、配置文件

[root@server1 rediscluster]# cd 7001
[root@server1 7001]# vim redis.conf

port 7001       # 修改啓動端口爲7001

cluster-enabled yes    # 開啓允許集羣

cluster-config-file nodes.conf       # 修改集羣配置文件指向路徑
daemonize yes     # 開啓守護進程模式

  dir /usr/local/rediscluster/7001   #目錄

  cluster-node-timeout 5000        #集羣中各節點相互通訊時,允許"失聯"的最大毫秒數,配置爲5秒,超過5秒某個節點沒向其它節點彙報成功,認爲該節點掛了。


  appendonly yes        #開啓持久化


把上面的redis.conf,放到每個目錄的redis目錄中,注意修改port端口,即7001目錄下的port爲7001,7002目錄下的port爲7002...

[root@server1 rediscluster]# cp 7001/redis.conf 7002/    依次複製過去並修改

[root@server1 ~]# cd redis-4.0.8


[root@server1 redis-4.0.8]# cd src/


[root@server1 src]# scp redis-trib.rb /usr/local/bin/


[root@server1 src]# cd /usr/local/bin/


Screenshot from 2018-07-03 22-47-01.png


雖然可以把6個redis server啓動成功,但是啓動後彼此之間是完全獨立的,需要藉助其它工具將其加入cluster,而這個工具就是redis提供的一個名爲redis-trib.rb的ruby腳本



四、安裝redis的ruby模塊

ruby-2.2.3-1.el6.x86_64.rpm
rubygems-1.3.7-5.el6.noarch.rpm
libyaml-0.1.3-4.el6_6.x86_64.rpm


[root@server1 ~]# yum install -y rubygems-1.3.7-5.el6.noarch.rpm

[root@server1 ~]# yum install -y ruby-2.2.3-1.el6.x86_64.rpm    libyaml-0.1.3-4.el6_6.x86_64.rpm


[root@server1 ~]# gem list      查看模塊

Screenshot from 2018-07-03 22-56-32.png


[root@server1 ~]# gem install --local redis-4.0.1.gem     安裝模塊


Screenshot from 2018-07-03 22-59-07.png


Screenshot from 2018-07-03 22-59-55.png


五、依次啓動各個redis

[root@server1 rediscluster]# cd 7001


[root@server1 7001]# redis-server redis.conf 


Screenshot from 2018-07-03 23-02-15.png


如下,各個端口已開


Screenshot from 2018-07-03 23-04-33.png


六、創建cluster


[root@server1 ~]# redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006



replicas 1的意思,就是每個節點創建1個副本(即:slave),所以最終的結果,就是後面的127.0.0.1:7001~127.0.0.1:7006中,會有3個會指定成master,而其它3個會指定成slave。


Screenshot from 2018-07-03 23-09-51.png


注:利用redis-trib創建cluster的操作,只需要一次即可,假設系統關機,把所有6個節點全關閉後,下次重啓後,即自動進入cluster模式,不用再次redis-trib.rb create。


如果想知道,哪些端口的節點是master,哪些端口的節點是slave,可以用下面的命令:


[root@server1 ~]# redis-trib.rb check 127.0.0.1:7001

Screenshot from 2018-07-03 23-14-40.png


[root@server1 ~]# redis-trib.rb info 127.0.0.1:7001

Screenshot from 2018-07-03 23-15-57.png


它會把所有的master信息輸出,包括這個master上有幾個緩存key,有幾個slave,所有master上的keys合計,以及平均每個slot上有多少key.


解釋slot

Screenshot from 2018-07-03 23-17-54.png


如上圖,redis-cluster把整個集羣的存儲空間劃分爲16384個slot(譯爲:插槽?),當6個節點分爲3主3從時,相當於整個 cluster中有3組HA的節點,3個master會平均分攤所有slot,每次向cluster中的key做操作時(比如:讀取/寫入緩 存),redis會對key值做CRC32算法處理,得到一個數值,然後再對16384取模,通過餘數判斷該緩存項應該落在哪個slot上,確定了 slot,也就確定了保存在哪個master節點上,當cluster擴容或刪除節點時,只需要將slot重新分配即可(即:把部分slot從一些節點移 動到其它節點)。


七、redis-cli客戶端操作


[root@server1 ~]# redis-cli -c -h localhost -p 7001   注意加參數-c,表示進入cluster模式,隨便添加一個緩存試試


[root@server1 ~]# redis-cli -c -h localhost -p 7001
localhost:7001> set name cara
-> Redirected to slot [5798] located at 127.0.0.1:7002
OK
127.0.0.1:7002> get name
"cara"
127.0.0.1:7002> set password redhat
OK
127.0.0.1:7002> get password
"redhat"
127.0.0.1:7002> quit


[root@server1 ~]# redis-cli -c -h localhost -p 7002
localhost:7002> set user liu
OK
localhost:7002> quit


參考如下,理解

localhost:7000> set user1 jimmy
-> Redirected to slot [8106] located at 127.0.0.1:7001
OK

注意第2行的輸出,表示user1這個緩存通過計算後,落在8106這個slot上,最終定位在7001這個端口對應的節點上(解釋:因爲7000 是slave,7001纔是master,只有master才能寫入),如果是在7001上重複上面的操作時,不會出現第2行(解釋:7001是 master,所以不存在redirect的過程)


➜  src ./redis-cli -c -h localhost -p 7001
localhost:7001> set user1 yang
OK
localhost:7001>


八、FailOver測試

先用redis-trib.rb 查看下當前的主、從情況

[root@server1 ~]# redis-trib.rb check 127.0.0.1:7001
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: b3b4e08e73e09d7f87158118e2b6e748109c1d08 127.0.0.1:7001
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 60427b62e3b9ffe991dda6498ceeca5d611b3b8e 127.0.0.1:7005
   slots: (0 slots) slave
   replicates b3b4e08e73e09d7f87158118e2b6e748109c1d08
S: 0f907e0d51e0a9ff2a5c415a714badbf666eb87f 127.0.0.1:7006
   slots: (0 slots) slave
   replicates 770c0d7a31be9204e244fd61ed17b8a041b2eb74
M: 3dbafd70a2f4f1c608c996b6ad82964a2f473f42 127.0.0.1:7003
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
M: 770c0d7a31be9204e244fd61ed17b8a041b2eb74 127.0.0.1:7002
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 5b9745fabdd98b820616a11d4f397db1410aa073 127.0.0.1:7004
   slots: (0 slots) slave
   replicates 3dbafd70a2f4f1c608c996b6ad82964a2f473f42
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

從輸出上看7005是7001(b3b4e08e73e09d7f87158118e2b6e748109c1d08)的slave,現在我們人工把7001的redis進程給kill掉,然後觀察7005的終端輸出:


Screenshot from 2018-07-03 23-50-30.png


[root@server1 ~]# kill -9 1131

3872:S 21 Mar 10:55:55.771 # Cluster state changed: fail
3872:S 21 Mar 10:55:55.869 # Start of election delayed for 954 milliseconds (rank #0, offset 183).

3872:S 21 Mar 10:55:56.911 # Failover election won: I'm the new master.


注意這幾行,第1行表明由於7001宕機,cluster狀態已經切換到fail狀態,第2行表示發起選舉,第3行表示7005端口對應的節點當選爲new master。

注:如果一組分片中的master、slave全掛了,整個cluster集羣不再接受任何讀/寫指令,redis-cli終端裏會直接報cluster down,但是info等其它指令仍然可用,直到這一組分片中,有一個節點恢復爲止。


九、cluster 擴容

再添加2個節點,先把7001複製二份,變成7007,7008,然後進入7007/7008目錄redis的src子目錄下

[root@server1 rediscluster]# cd 7001
[root@server1 7001]# ls
appendonly.aof  dump.rdb  nodes.conf  redis.conf
[root@server1 7001]# rm appendonly.aof dump.rdb nodes.conf

由於7001我們剛纔啓動過,裏面有已經有一些數據了,所以要把數據文件,日誌文件,以及cluster的nodes.conf文件刪除,變成一個空的redis獨立節點,否則無法加入cluster。

[root@server1 rediscluster]# mkdir 700{7..8}
[root@server1 rediscluster]# ls
7001  7002  7003  7004  7005  7006  7007  7008
[root@server1 rediscluster]# cp 7001/redis.conf 7007
[root@server1 rediscluster]# cp 7001/redis.conf 7008

7/8的文件修改

Screenshot from 2018-07-04 00-26-49.png


修改完成後,分別開啓

[root@server1 7007]# redis-server redis.conf

[root@server1 7008]# redis-server redis.conf

將上面關掉的7001開啓,redis-server redis.conf


然後加入集羣

[root@server1 ~]# redis-trib.rb add-node 127.0.0.1:7008 127.0.0.1:7001

注:第1個參數爲新節點的"IP:端口",第2個參數爲集羣中的任一有效的節點


Screenshot from 2018-07-04 00-31-35.png


用下面的命令把7008當成slave加入

redis-trib.rb add-node --slave --master-id 226d1af3c95bf0798ea9fed86373b89347f889da 127.0.0.1:7008 127.0.0.1:7006

這裏多出了二個參數:--slave 表示準備將新節點當成slave加入,--master-id xxxxx 則是指定要當誰的slave,後面的xxx部分,即爲前面check的輸出結果中,7006的ID,完事之後,可以再次確認狀態


十、reshard 重新劃分slot


增加新的節點之後,問題就來了,16384個slot已經被其它3組節點分完了,新節點沒有slot,沒辦法存放緩存,所以需要將slot重新分佈。

[root@server1 ~]# redis-trib.rb info 127.0.0.1:7001
127.0.0.1:7001 (3d8958bc...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7003 (cbd94e6e...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7007 (78f82a30...) -> 0 keys | 0 slots | 0 slaves.
127.0.0.1:7002 (e27caa19...) -> 0 keys | 5462 slots | 1 slaves.
127.0.0.1:7008 (a2776c09...) -> 0 keys | 0 slots | 0 slaves.
[OK] 0 keys in 5 masters.
0.00 keys per slot on average.

用下面的命令可以重新分配slot

1
redis-trib.rb reshard 127.0.0.1:7001

reshard後面的IP:port,只要是在cluster中的有效節點即可。


執行

[root@server1 ~]# redis-trib.rb reshard 127.0.0.1:7001

How many slots do you want to move (from 1 to 16384)? 1000    #這裏輸入要移動多少slot


What is the receiving node ID? 78f82a304e1056ae6c5c358350fe77a1c0191ba3    #這裏輸入目標節點的id


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:all    #將所有node都當成源節點


Do you want to proceed with the proposed reshard plan (yes/no)? yes      #確認執行


注:第一個交互詢問,填寫多少slot移動時,要好好想想,如果填成16384,則將所有slot都移動到一個固定節點上,會導致更加不均衡!建議每次移動500~1000,這樣對線上的影響比較小。

另外在填寫source node時,除了all之外,還可以直接填寫源節點的id,即:



How many slots do you want to move (from 1 to 16384)? 300
What is the receiving node ID? a2776c0928507f893ca43bdb9c146dd77e95af66
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:3d8958bc397e6a37095ba0ea1ef8e1f8e3b85996         #這裏填寫源節點的id


Source node #2:done           #這裏輸入done表示,不再繼續添加源節點了


Do you want to proceed with the proposed reshard plan (yes/no)? yes


查看分佈情況:

[root@server1 ~]# redis-trib.rb info 127.0.0.1:7001
127.0.0.1:7001 (3d8958bc...) -> 0 keys | 4828 slots | 1 slaves.
127.0.0.1:7003 (cbd94e6e...) -> 0 keys | 5128 slots | 1 slaves.
127.0.0.1:7007 (78f82a30...) -> 0 keys | 1000 slots | 0 slaves.
127.0.0.1:7002 (e27caa19...) -> 0 keys | 5128 slots | 1 slaves.
127.0.0.1:7008 (a2776c09...) -> 0 keys | 300 slots | 0 slaves.
[OK] 0 keys in 5 masters.
0.00 keys per slot on average.


十一、刪除節點del-node

某些節點不再需要時,可以用del-node刪除


刪除節點命令:

1
redis-trib.rb del-node 127.0.0.1:7008 a2776c0928507f893ca43bdb9c146dd77e95af66

del-node後面的ip:port只要是cluster中有效節點即可,最後一個參數爲目標節點的id

注意:只有slave節點和空的master節點可以刪除,如果 master非空,先用reshard把上面的slot移動到其它node後再刪除,如果有一組master-slave節點,將master上所有 slot移到其它節點,然後將master刪除,剩下的slave會另尋他主,變成其它master的slave。


另外:刪除節點的含義,不僅僅是從cluster中將這個節點移除,還會直接將目標節點的redis服務停止。


如下報錯

[root@server1 ~]# redis-trib.rb del-node 127.0.0.1:7008 a2776c0928507f893ca43bdb9c146dd77e95af66
>>> Removing node a2776c0928507f893ca43bdb9c146dd77e95af66 from cluster 127.0.0.1:7001
[ERR] Node 127.0.0.1:7008 is not empty! Reshard data away and try again.

redis cluster提示7001已經有數據了,不能夠被刪除,需要將他的數據轉移出去,也就是和新增主節點一樣需重新分片。

[root@server1 ~]# redis-trib.rb info 127.0.0.1:7008
127.0.0.1:7008 (a2776c09...) -> 0 keys | 300 slots | 0 slaves.
127.0.0.1:7003 (cbd94e6e...) -> 0 keys | 5128 slots | 1 slaves.
127.0.0.1:7002 (e27caa19...) -> 0 keys | 5128 slots | 1 slaves.
127.0.0.1:7007 (78f82a30...) -> 0 keys | 1000 slots | 0 slaves.
127.0.0.1:7001 (3d8958bc...) -> 0 keys | 4828 slots | 1 slaves.
[OK] 0 keys in 5 masters.
0.00 keys per slot on average.

可以看出7008佔用300個槽點

[root@server1 ~]# redis-trib.rb reshard 127.0.0.1:7008
How many slots do you want to move (from 1 to 16384)? 300     #寫入所佔槽
What is the receiving node ID? 3d8958bc397e6a37095ba0ea1ef8e1f8e3b85996    #7001 ( 移給誰 )
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:a2776c0928507f893ca43bdb9c146dd77e95af66    #7008 
Source node #2:done

Do you want to proceed with the proposed reshard plan (yes/no)? yes


[root@server1 ~]# redis-trib.rb info 127.0.0.1:7008
127.0.0.1:7008 (a2776c09...) -> 0 keys | 0 slots | 0 slaves.
127.0.0.1:7003 (cbd94e6e...) -> 0 keys | 5128 slots | 1 slaves.
127.0.0.1:7002 (e27caa19...) -> 0 keys | 5128 slots | 1 slaves.
127.0.0.1:7007 (78f82a30...) -> 0 keys | 1000 slots | 0 slaves.
127.0.0.1:7001 (3d8958bc...) -> 0 keys | 5128 slots | 1 slaves.
[OK] 0 keys in 5 masters.
0.00 keys per slot on average.


再次刪除節點

[root@server1 ~]# redis-trib.rb del-node 127.0.0.1:7008 a2776c0928507f893ca43bdb9c146dd77e95af66
>>> Removing node a2776c0928507f893ca43bdb9c146dd77e95af66 from cluster 127.0.0.1:7008
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.


如下7008在進程中已消失
 1267 ?        Ssl    0:09 redis-server *:7001 [cluster]
 1272 ?        Ssl    0:07 redis-server *:7002 [cluster]
 1277 ?        Ssl    0:07 redis-server *:7003 [cluster]
 1282 ?        Ssl    0:05 redis-server *:7004 [cluster]
 1287 ?        Ssl    0:05 redis-server *:7005 [cluster]
 1292 ?        Ssl    0:05 redis-server *:7006 [cluster]
 1311 pts/0    Sl+    0:07 redis-server *:7007 [cluster]

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