windows redis 集羣搭建(三)

1、redis數據分片的原理 

    Redis 集羣沒有使用一致性hash, 而是引入了哈希槽的概念.node

    Redis 集羣有16384個哈希槽,每一個key經過CRC16校驗後對16384取模來決定放置哪一個槽.集羣的每一個節點負責一部分hash槽,舉個例子,好比當前集羣有3個節點,那麼:git

  • 節點 A 包含 0 到 5500號哈希槽.github

  • 節點 B 包含5501 到 11000 號哈希槽.web

  • 節點 C 包含11001 到 16384號哈希槽.redis

    這種結構很容易添加或者刪除節點. 好比若是我想新添加個節點D, 我須要從節點 A, B, C中得部分槽到D上. 若是我像移除節點A,須要將A中得槽移到B和C節點上,而後將沒有任何槽的A節點從集羣中移除便可.shell

    因爲從一個節點將哈希槽移動到另外一個節點並不會中止服務,因此不管添加刪除或者改變某個節點的哈希槽的數量都不會形成集羣不可用的狀態.安全

    另一種狀況,某一個主節點失效,好比上面的A節點失效,會形成 0 到 5500號槽點不可用, 因爲redis支持主從模型的支持,咱們在建立A主節點的時候建立a1從節點,即使一個主節點A失效,他的a1也會立馬升爲新的主節點繼續服務,從而使集羣可繼續服務。ruby


2、集羣從新分片

   集羣的管理中,集羣分片管理最爲核心,是添加,移除集羣的基礎,咱們優先介紹。網絡

  從新分片操做基本上就是將某些節點上的哈希槽移動到另一些節點上面,從新分片並不會對正在運行的集羣程序產生任何影響,能夠在運行時分片。異步

 個人集羣目錄結構:

   

  查看主從節點的佈局 CLUSTER NODES

#進入redis client ,端口隨意
redis-cli.exe -c -p 7003
#查看節點佈局
 cluster nodes
#節點信息
 7d1c4b578836ac19fc18fb3052f4a615d90f2bc2 127.0.0.1:7002 master - 0 1420428414526
 0 connected 5494-10921
e5a0d9656dcac9519ea32e81dadefcb8b051831e 127.0.0.1:7004 slave 77d2016c8a40b46b81
f172f6f3eab4cef2ae16fb 0 1420428415526 0 connected
6c0eafd99a6a1153b6aa0f1a81209bf083495098 :0 myself,master - 0 0 0 connected 1095
6-16383
113e9b14bb52702cda940854ccbe56c7f0ea2cef 127.0.0.1:7007 master - 0 1420428412025
 0 connected 0-32 5461-5493 10922-10955
b2524f2f3ebfac4da75fb415e1d0eb2fe514a96c 127.0.0.1:7006 slave 6c0eafd99a6a1153b6
aa0f1a81209bf083495098 0 1420428410525 0 connected
2b95f078f327523a5185b26239c2baeb8773613b 127.0.0.1:7005 slave 7d1c4b578836ac19fc
18fb3052f4a615d90f2bc2 0 1420428412525 0 connected
77d2016c8a40b46b81f172f6f3eab4cef2ae16fb 127.0.0.1:7001 master - 0 1420428413525
 0 connected 33-5460

  以上咱們看到,主節點爲: 7002,7007,7001,7003  子節點爲:7004,  7006,7005。每一個節點的槽區域,以及子節點的主節點是誰均可以展示。

cluster nodes 命令輸出的含義:

          

一、節點ID
二、IP
三、端口
四、標誌: master, slave, myself, fail, ...
五、若是是個從節點, 這裏是它的主節點的NODE ID
六、集羣最近一次向節點發送 PING 命令以後, 過去了多長時間還沒接到回覆。.
七、節點最近一次返回 PONG 回覆的時間。
八、節點的配置紀元(configuration epoch):詳細信息請參考 Redis 集羣規範 。
九、本節點的網絡鏈接狀況:例如 connected 。
十、節點目前包含的槽:例如 127.0.0.1:7001 目前包含號碼爲 5960 至 10921 的哈希槽。

    如今開始分片,咱們嘗試從新將10個槽從新分片,從節點7002分配到7001,注意:

    一、必須知道目標節點的id

    二、必須知道槽的來源,能夠是all(其餘每一個master取一些),也能夠是從其餘節點借調(須要指定借調節點id)

    三、目標和借調者,最好是主節點

   分片操做(必須得有redis-trib.rb文件,沒有的去源碼src下找或者從上一篇文字找):

#ip和端口隨意,只要存在服務便可
redis-trib.rb reshard 127.0.0.1:7001
...一些檢測信息...
OK] All nodes agree about slots configuration.
>> Check for open slots...
>> Check slots coverage...
OK] All 16384 slots covered.
#上面檢測成功,開始詢問你
ow many slots do you want to move (from 1 to 16384)?

    輸出到上面這句的時候,就是問你將要移動(分配)多少個槽,此時只須要輸入想要分配的數量便可,咱們如今分配10個槽,輸入10.

What is the receiving node ID?

  詢問你目標節點id,記得是ID哦,咱們目標是7002,id爲:7d1c4b578836ac19fc18fb3052f4a615d90f2bc2。輸入

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:

   此時詢問你從哪裏借調,有2個選擇,輸入all,此時系統會自動從其餘節點借調,或者輸入借調節點的id,從指定節點借調,咱們從7001借調,輸入節點id:77d2016c8a40b46b81f172f6f3eab4cef2ae16fb

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:77d2016c8a40b46b81f172f6f3eab4cef2ae16fb
Source node #2:

  再次詢問,輸入done便可。

....一些移動檢測信息...
Do you want to proceed with the proposed reshard plan (yes/no)?

   詢問是否執行,輸入yes

Do you want to proceed with the proposed reshard plan (yes/no)? yes
Moving slot 33 from 127.0.0.1:7001 to 127.0.0.1:7002:
Moving slot 34 from 127.0.0.1:7001 to 127.0.0.1:7002:
Moving slot 35 from 127.0.0.1:7001 to 127.0.0.1:7002:
Moving slot 36 from 127.0.0.1:7001 to 127.0.0.1:7002:
Moving slot 37 from 127.0.0.1:7001 to 127.0.0.1:7002:
Moving slot 38 from 127.0.0.1:7001 to 127.0.0.1:7002:
Moving slot 39 from 127.0.0.1:7001 to 127.0.0.1:7002:
Moving slot 40 from 127.0.0.1:7001 to 127.0.0.1:7002:
Moving slot 41 from 127.0.0.1:7001 to 127.0.0.1:7002:
Moving slot 42 from 127.0.0.1:7001 to 127.0.0.1:7002:

   此時能夠在執行下 clluster nodes 查看下節點的槽區域。



3、添加節點

添加新的節點的基本過程就是添加一個空的節點而後移動一些數據給它,有兩種狀況,添加一個主節點和添加一個從節點(添加從節點時須要將這個新的節點設置爲集羣中某個節點的複製)

  1.  添加主節點  

    建立新的節點7008,配置和以前同樣,只需把端口號改下,過程以下:     

一、 進入cluster目錄
二、建立7008文件夾
三、 拷貝其餘端口全部文件,從redis.conf更改端口號爲7008
四、 啓動節點,redis-server.exe redis.conf

     使用redis-trib 來添加這個節點到現有的集羣中去.

#第一個參數新節點地址,第二個參數任意一個已存在的節點ip和端口
redis-trib.rb add-node 127.0.0.1:7008 127.0.0.7001
#添加成功
....其餘信息...
[OK] All 16384 slots covered.
Connecting to node 127.0.0.1:7008: OK
>>> Send CLUSTER MEET to node 127.0.0.1:7008 to make it join the cluster.
[OK] New node added correctly.

    添加成功後可使用 cluster nodes 來查看節點的信息。

   

   以上能夠看到7008已經鏈接行集羣了,能夠對客戶端的命令進行轉向了,可是此時的節點:

一、新節點沒有包含任何數據, 由於它沒有包含任何哈希槽.
二、儘管新節點沒有包含任何哈希槽, 但它仍然是一個主節點, 因此在集羣須要將某個從節點升級爲新的主節點時, 這個新節點不會被選中。

     此時節點還沒法存儲數據,想要能使用起來,須要使用上面從新分片的流程,將集羣中其餘一些數量的哈希槽移動到新節點,新節點就能夠儲存數據了。此處再也不多說。

  1.  添加從節點

    添加從節點有兩種方式,不指定主節點和指定住節點。

    不指定主節點

#slave代表是從節點,第一個是節點ip和端口,第二個隨意存在就能夠
redis-trib.rb add-node --slave 127.0.0.1:7008 127.0.0.1:7001

此處的命令和添加一個主節點命令相似,此處並無指定添加的這個從節點的主節點,這種狀況下系統會在其餘的複製集中的主節點中隨機選取一個做爲這個從節點的主節點。

       指定主節點

#master-id 主節點id, 從節點ip和端口 ,主節點ip和端口
redis-trib.rb add-node --slave --master-id 77d2016c8a40b46b81f172f6f3eab4cef2ae16fb 127.0.0.1:7008 127.0.0.1:7001

  以上是給主節點 127.0.0.1:7001添加一個從節點127.0.0.1:7001,主節點是:77d2016c8a40b46b81f172f6f3eab4cef2ae16fb

  改變從節點的主節點

   


4、移除節點

  命令:redis-tribdel-node 任意節點ip:port 移除的節點id

  好比咱們要移除節點7008

redis-trib del-node 127.0.0.1:7001 b29720bfc1a52df3ee8e101eb5b07e30a09af965
>>> Removing node b29720bfc1a52df3ee8e101eb5b07e30a09af965 from cluster 127.0.0.
1:7001
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7007: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7006: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7008: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7004: OK
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

 移除成功,須要注意的是,須要確保這個主節點是空的. 若是不是空的,須要將這個節點的數據從新分片到其餘主節點上,具體的移除該節點的槽,根據從新分片流程來便可。



5、節點遷移

改變一個從節點的主節點的狀況,命令: cluster replicate 主節點id

#當前節點7008 的主節點改變爲 7001, 命令後面是主節點id
redis 127.0.0.1:7008> cluster replicate 77d2016c8a40b46b81f172f6f3eab4cef2ae16fb

以上就是改變7008的歸屬主節點。



6、故障轉移

   通常狀況下,某一個主節點產生了故障了,系統會自動進行故障轉移,把他的從節點自動升級爲主節點。因爲redis使用的是異步複製,因此在執行故障轉移期間,集羣會丟失某些寫的命令。

  或者咱們在主節點沒有任何問題的狀況下強制手動故障轉移也是頗有必要的,好比想要升級主節點的Redis進程,咱們能夠經過故障轉移將其轉爲slave再進行升級操做來避免對集羣的可用性形成很大的影響。

Redis集羣使用 CLUSTER FAILOVER命令來進行故障轉移,不過要被轉移的主節點的從節點上執行該命令

手動故障轉移比主節點失敗自動故障轉移更加安全,由於手動故障轉移時客戶端的切換是在確保新的主節點徹底複製了失敗的舊的主節點數據的前提下下發生的,因此避免了數據的丟失。

  手動故障轉移,命令:


7、測試

測試階段,主要是下載一個redis-rb-cluster ,這個是ruby實現的,對redis-rb的簡單包裝,解壓後更改下example_test.rb的配置,咱們能夠看到以下輸出:

redis-rb-cluster-master>example_test.rb
1
2
3
4
5
6
7
8
9
10
11
12

   這個就是不斷的向集羣裏面寫入foo和讀取foo,主要是用來測試集羣的寫入的.

   (此處轉的)redis-rb-cluster 項目包含了一個名爲 consistency-test.rb 的示例應用, 這個應用比起 example.rb 有趣得多: 它建立了多個計數器(默認爲 1000 個), 並經過發送 INCR 命令來增長這些計數器的值。

在增長計數器值的同時, consistency-test.rb 還執行如下操做:

  • 每次使用 INCR 命令更新一個計數器時, 應用會記錄下計數器執行 INCR 命令以後應該有的值。 舉個例子, 若是計數器的起始值爲 0 , 而此次是程序第 50 次向它發送 INCR 命令, 那麼計數器的值應該是 50 。

  • 在每次發送 INCR 命令以前, 程序會隨機從集羣中讀取一個計數器的值, 並將它與本身記錄的值進行對比, 看兩個值是否相同。

換句話說, 這個程序是一個一致性檢查器(consistency checker): 若是集羣在執行 INCR 命令的過程當中, 丟失了某條 INCR 命令, 又或者多執行了某條客戶端沒有確認到的 INCR 命令, 那麼檢查器將察覺到這一點 —— 在前一種狀況中, consistency-test.rb 記錄的計數器值將比集羣記錄的計數器值要大; 而在後一種狀況中, consistency-test.rb 記錄的計數器值將比集羣記錄的計數器值要小。

運行 consistency-test 程序將產生相似如下的輸出:

$ ruby consistency-test.rb
925 R (0 err) | 925 W (0 err) |
5030 R (0 err) | 5030 W (0 err) |
9261 R (0 err) | 9261 W (0 err) |
13517 R (0 err) | 13517 W (0 err) |
17780 R (0 err) | 17780 W (0 err) |
22025 R (0 err) | 22025 W (0 err) |
25818 R (0 err) | 25818 W (0 err) |
相關文章
相關標籤/搜索