Redis集羣的配置與故障恢復

集羣

Redis在主從複製模式下,每一個數據庫依然存有集羣中的全部數據,從而致使集羣的總數據存儲量受限於內存最小的服務器。node

另外,對Redis進行水平擴展比較麻煩,一般使用客戶端分片來解決這個問題,由客戶端決定每一個鍵存儲到哪一個節點。但擴容時想增長新的節點就須要對數據進行手工遷移,爲了保證遷移過程當中,數據的一致性,還須要將Redis暫時下線。redis

Redis在3.0版本推出了集羣模式,在該模式中由Redis決定key存儲在哪一個節點,以及查詢時從哪一個節點查詢。算法

準備8個虛擬機,安裝好redis:數據庫

  • 192.168.2.104
  • 192.168.2.105
  • 192.168.2.106
  • 192.168.2.107
  • 192.168.2.108
  • 192.168.2.109
  • 192.168.2.110
  • 192.168.2.111

先將前6個節點組成集羣,而後在將後兩個節點以擴容的形式加入到集羣。bash

配置

要使用集羣,首先要開啓集羣的配置:服務器

cluster-enabled yes

若是由防火牆,打開16937端口(默認)測試

啓動Redis後,在redis-cli終端下執行INFO cluster查詢集羣是否正常:ui

[root@localhost redis-5.0.7]# redis-cli
127.0.0.1:6379> INFO cluster
# Cluster
cluster_enabled:1

我測試的時候使用了6個節點:spa

接下來執行redis的集羣命令就能夠了。3d

在Redis3.0時,須要使用redis-trib.rb進行集羣搭建,不然要自動手動經過命令搭建,可是在高版本的Redis中(我用的5.0),redis-cli已經實現了redis-trib.rb的功能。

在各個服務器節點上執行命令:

redis-cli --cluster create 192.168.2.104:6379 192.168.2.105:6379 192.168.2.106:6379 192.168.2.107:6379 192.168.2.108:6379 192.168.2.109:6379 --cluster-replicas 1

把6個節點的ip和端口填寫上,參數--cluster-replicas 1 是表示每一個數據庫擁有的從數據庫個數。

執行這個命令後,集羣中共有3個主數據庫和3個從數據庫,此致,你的集羣已經搭建完畢了。能夠在redis-cli終端下執行CLUSTER NODES命令查詢集羣的節點狀態。

插槽的分配

在理解插槽之間,先記錄一下Redis若是對Key進行分區的。

Redis經過CRC16(Key) % 16384計算出一個值,根據這個值把數據存到值對應的插槽裏。

Redis集羣模式下一共有16384個插槽,至於爲何是16384個插槽,你們能夠在網上查一下看看緣由,在這裏就不說了。

因此在一個集羣中,全部的Key會被分配到16384個插槽中的一個插槽裏。那麼3個主數據庫默認沒人承擔16384/3個插槽。

能夠在redis-cli終端下執行CLUSTER SLOTS命令,查看每一個節點負責的插槽區間,Redis不要求每一個主節點負責的插槽是連續的。

擴容

對集羣添加新節點時,節點類型分爲主節點和從節點。

添加主節點

添加主節點作法以下,執行命令:

redis-cli --cluster add-node 192.168.2.110:6379 192.168.2.106:6379

命令的後兩個參數,左邊的是新節點的IP和端口(192.168.2.110:6379),右邊的是集羣中的任意一個節點的IP和端口(192.168.2.106:6379)。該命令會將新節點加入到集羣中,並設置成主節點。

剛加入到集羣中的主節點是沒有負責的插槽的,執行命令:

redis-cli --cluster reshard 192.168.2.106:6379

該命令用來申請插槽,最後一個參數是集羣中任意一個節點的IP和端口。執行該命令有幾個交互步驟:

終端:How many slots do you want to move (from 1 to 16384) ? 

填寫一個數字,表明相申請多少個slot給新添加到進羣的節點,我寫了4096,接下來回詢問:

what is the receiving node ID?

要求輸入一個nodeID來接收這4096個slot,我經過CLUSTER NODES命令查詢到了192.168.2.110的NodeID填寫進去,接下來回詢問:

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.

這裏是要求填入把那些節點的slots轉移到新節點下,能夠有2種寫法:

一種是寫入指定節點的nodeID,寫好後輸入done。

一種是寫all,Redis回自動從全部節點中提取出4096個slot給新節點。

我這裏寫的all,回車,輸入yes肯定執行。主節點添加並申請slot完畢。

添加從節點

下面爲剛纔添加的主節點(192.168.2.110)添加一個從節點,執行命令:

redis-cli --cluster add-node --cluster-slave --cluster-master-id 691b4cb6563da921d4d9bd191d8fa98a7cef0c23 192.168.2.111:6379 192.168.2.110:6379

後三個參數一次是:主節點NodeID,從節點IP和端口,主節點IP和端口。

這樣有完成了一次擴容,添加了一個主節點和其對應的從節點,並分配給新節點4096個slot,能夠經過CLUSTER NODES和CLUSTER SLOTS查詢:

[root@localhost redis-5.0.7]# redis-cli
127.0.0.1:6379> CLUSTER NODES
691b4cb6563da921d4d9bd191d8fa98a7cef0c23 192.168.2.110:6379@16379 master - 0 1580832752462 9 connected 0-1364 5461-6826 10923-12287
ee1a9c31eb1571254e2679e5e84a32f7931c8b37 192.168.2.107:6379@16379 slave 3fab72ba46dd8f50fc4c665f1011c41940152385 0 1580832753000 8 connected
392006bd13d86e92d8c5dca2d89030adb7d2ed51 192.168.2.109:6379@16379 slave 435eff563051e89e7680dbc8a6146c7f4b637a36 0 1580832750445 6 connected
931f465e35513355c7043b2faba7974d1c762020 192.168.2.108:6379@16379 slave 76130efb66918698579473a592a5b9188922fa73 0 1580832749000 5 connected
435eff563051e89e7680dbc8a6146c7f4b637a36 192.168.2.105:6379@16379 master - 0 1580832751000 2 connected 6827-10922
76130efb66918698579473a592a5b9188922fa73 192.168.2.104:6379@16379 myself,master - 0 1580832751000 1 connected 1365-5460
3fab72ba46dd8f50fc4c665f1011c41940152385 192.168.2.106:6379@16379 master - 0 1580832753468 8 connected 12288-16383
f1e3cd10ed6ef51a04601f179b8446c58f2f52f1 192.168.2.111:6379@16379 slave 691b4cb6563da921d4d9bd191d8fa98a7cef0c23 0 1580832751453 9 connected
[root@localhost redis-5.0.7]# redis-cli
127.0.0.1:6379> CLUSTER SLOTS
1) 1) (integer) 0
   2) (integer) 1364
   3) 1) "192.168.2.110"
      2) (integer) 6379
      3) "691b4cb6563da921d4d9bd191d8fa98a7cef0c23"
   4) 1) "192.168.2.111"
      2) (integer) 6379
      3) "f1e3cd10ed6ef51a04601f179b8446c58f2f52f1"
2) 1) (integer) 5461
   2) (integer) 6826
   3) 1) "192.168.2.110"
      2) (integer) 6379
      3) "691b4cb6563da921d4d9bd191d8fa98a7cef0c23"
   4) 1) "192.168.2.111"
      2) (integer) 6379
      3) "f1e3cd10ed6ef51a04601f179b8446c58f2f52f1"
3) 1) (integer) 10923
   2) (integer) 12287
   3) 1) "192.168.2.110"
      2) (integer) 6379
      3) "691b4cb6563da921d4d9bd191d8fa98a7cef0c23"
   4) 1) "192.168.2.111"
      2) (integer) 6379
      3) "f1e3cd10ed6ef51a04601f179b8446c58f2f52f1"
4) 1) (integer) 6827
   2) (integer) 10922
   3) 1) "192.168.2.105"
      2) (integer) 6379
      3) "435eff563051e89e7680dbc8a6146c7f4b637a36"
   4) 1) "192.168.2.109"
      2) (integer) 6379
      3) "392006bd13d86e92d8c5dca2d89030adb7d2ed51"
5) 1) (integer) 1365
   2) (integer) 5460
   3) 1) "192.168.2.104"
      2) (integer) 6379
      3) "76130efb66918698579473a592a5b9188922fa73"
   4) 1) "192.168.2.108"
      2) (integer) 6379
      3) "931f465e35513355c7043b2faba7974d1c762020"
6) 1) (integer) 12288
   2) (integer) 16383
   3) 1) "192.168.2.106"
      2) (integer) 6379
      3) "3fab72ba46dd8f50fc4c665f1011c41940152385"
   4) 1) "192.168.2.107"
      2) (integer) 6379
      3) "ee1a9c31eb1571254e2679e5e84a32f7931c8b37"

測試集羣

當要經過redis-cli向集羣中寫入數據時,有可能會發生下面的錯誤:

[root@localhost redis-5.0.7]# redis-cli
127.0.0.1:6379> set hello world
(error) MOVED 866 192.168.2.110:6379

我在192.168.2.104上的redis-cli終端執行set hello world命令,提示error,由於key通過CRC16('hello') % 16384後等於866,而866號slot所在的節點不是當前節點。能夠用redis-cli -c啓動終端,就能夠進行測試了。

[root@localhost redis-5.0.7]# redis-cli -c
127.0.0.1:6379> set hello world!!
-> Redirected to slot [866] located at 192.168.2.110:6379
OK

故障恢復

主節點沒有從節點

假如你的集羣節點有一個主節點down掉了,而且這個主節點沒有從節點,那麼默認狀況下你的集羣是不可用的。

若是想在這種狀況下集羣使用集羣,能夠修改配置:

cluster-require-full-coverage no # 默認是yes

這樣就能夠正常使用了。

主節點有從節點

若是主節點down了,可是有至少一個從節點,那麼集羣就會進行故障修復,將down掉的主節點的一個從節點升級爲主節點,選擇哪一個從節點的過程與哨兵中選擇領頭哨兵的算法同樣,都是基於Raft算法的。

當其中一個從數據庫當選後,會經過SLAVEOF ON ONE將本身升級成主數據庫,並將down掉得主數據庫得slot轉換給本身。

測試一下,在192.168.2.110關閉reids服務:

[root@localhost redis-5.0.7]# /etc/init.d/redis stop
Stopping ...
Redis stopped

在其餘節點查看集羣信息,會發現192.168.2.111已經升級成了master,而且負責了原來192.168.2.110所負責得slots:

127.0.0.1:6379> cluster nodes
691b4cb6563da921d4d9bd191d8fa98a7cef0c23 192.168.2.110:6379@16379 master,fail - 1580833747361 1580833745000 9 disconnected
ee1a9c31eb1571254e2679e5e84a32f7931c8b37 192.168.2.107:6379@16379 slave 3fab72ba46dd8f50fc4c665f1011c41940152385 0 1580833864374 8 connected
392006bd13d86e92d8c5dca2d89030adb7d2ed51 192.168.2.109:6379@16379 slave 435eff563051e89e7680dbc8a6146c7f4b637a36 0 1580833861000 6 connected
931f465e35513355c7043b2faba7974d1c762020 192.168.2.108:6379@16379 slave 76130efb66918698579473a592a5b9188922fa73 0 1580833865382 5 connected
435eff563051e89e7680dbc8a6146c7f4b637a36 192.168.2.105:6379@16379 master - 0 1580833862000 2 connected 6827-10922
76130efb66918698579473a592a5b9188922fa73 192.168.2.104:6379@16379 myself,master - 0 1580833864000 1 connected 1365-5460
3fab72ba46dd8f50fc4c665f1011c41940152385 192.168.2.106:6379@16379 master - 0 1580833862356 8 connected 12288-16383
f1e3cd10ed6ef51a04601f179b8446c58f2f52f1 192.168.2.111:6379@16379 master - 0 1580833863365 11 connected 0-1364 5461-6826 10923-12287

下面在啓動192.168.2.110的redis服務:

[root@localhost redis-5.0.7]# /etc/init.d/redis start
Starting Redis server...
2706:C 05 Feb 2020 00:32:59.512 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2706:C 05 Feb 2020 00:32:59.512 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=2706, just started
2706:C 05 Feb 2020 00:32:59.512 # Configuration loaded

查看集羣信息,192.168.2.110已經變爲192.168.2.111的從節點了:

127.0.0.1:6379> cluster nodes
691b4cb6563da921d4d9bd191d8fa98a7cef0c23 192.168.2.110:6379@16379 slave f1e3cd10ed6ef51a04601f179b8446c58f2f52f1 0 1580834002000 11 connected
ee1a9c31eb1571254e2679e5e84a32f7931c8b37 192.168.2.107:6379@16379 slave 3fab72ba46dd8f50fc4c665f1011c41940152385 0 1580834000000 8 connected
392006bd13d86e92d8c5dca2d89030adb7d2ed51 192.168.2.109:6379@16379 slave 435eff563051e89e7680dbc8a6146c7f4b637a36 0 1580834000000 6 connected
931f465e35513355c7043b2faba7974d1c762020 192.168.2.108:6379@16379 slave 76130efb66918698579473a592a5b9188922fa73 0 1580834001773 5 connected
435eff563051e89e7680dbc8a6146c7f4b637a36 192.168.2.105:6379@16379 master - 0 1580834002780 2 connected 6827-10922
76130efb66918698579473a592a5b9188922fa73 192.168.2.104:6379@16379 myself,master - 0 1580833999000 1 connected 1365-5460
3fab72ba46dd8f50fc4c665f1011c41940152385 192.168.2.106:6379@16379 master - 0 1580834000000 8 connected 12288-16383
f1e3cd10ed6ef51a04601f179b8446c58f2f52f1 192.168.2.111:6379@16379 master - 0 1580834000764 11 connected 0-1364 5461-6826 10923-12287
相關文章
相關標籤/搜索