天天看點

Redis Cluster的實作和管理

Redis Cluster在redis3.0版本以上開始支援,以ruby環境運作。他可以把多個redis執行個體整合在一起,形成一個叢集,叢集内配置設定slot(分片槽),實作資料的分片存放。用戶端隻要以叢集的模式連接配接上叢集内任意一個節點,就可以操作整個叢集。

叢集角色有Master和Slave。Master之間配置設定slots,一共16384個slot。Slave向它指定的Master同步資料,實作備份。當其中的一個Master無法提供服務時,該Master的Slave講提升為Master,保證叢集間slot的完整性。一旦其中的某一個Master和它的Slave都失效,導緻了slot不完整,叢集失效。

環境準備:

Redis節點:

          192.168.189.144:9000

          192.168.189.144:9001

          192.168.189.145:8000

          192.168.189.145:8001

          192.168.189.146:7000

          192.168.189.146:7001

  在上述節點安裝3.0以上的redis版本,安裝完成後有redis-trib.rb檔案,這個檔案用于操作管理reids cluster。

選擇192.168.189.144為Cluster操作機器,安裝ruby環境,ruby環境要在1.8.5以上。

1

2

3

<code>#rpm  -ivh  http://yum.puppetlabs.com/el/5/products/x86_64/puppetlabs-release-5-6.noarch.rpm</code>

<code>#yum install ruby.x86_64 ruby-devel.x86_64 rubygems.noarch </code>

<code>#gem install redis    ---安裝ruby的redis接口</code>

叢集配置:

開啟每個redis的redis cluster功能,配置如下,根據執行個體配置設定端口:

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

<code>#grep -v ^# redis.conf  | grep -v ^$</code>

<code>daemonize </code><code>yes</code>

<code>pidfile </code><code>/usr/local/redis_cluster/9000/var/redis</code><code>.pid</code>

<code>port 9000</code>

<code>tcp-backlog 511</code>

<code>timeout 0</code>

<code>tcp-keepalive 0</code>

<code>loglevel notice</code>

<code>logfile </code><code>"/usr/local/redis_cluster/9000/redis.log"</code>

<code>databases 16</code>

<code>stop-writes-on-bgsave-error </code><code>yes</code>

<code>rdbcompression </code><code>yes</code>

<code>rdbchecksum </code><code>yes</code>

<code>dbfilename dump.rdb</code>

<code>dir</code> <code>/usr/local/redis_cluster/9000/data</code>

<code>slave-serve-stale-data </code><code>yes</code>

<code>slave-</code><code>read</code><code>-only </code><code>yes</code>

<code>repl-diskless-</code><code>sync</code> <code>no</code>

<code>repl-diskless-</code><code>sync</code><code>-delay 5</code>

<code>repl-disable-tcp-nodelay no</code>

<code>slave-priority 100</code>

<code>appendonly no</code>

<code>appendfilename </code><code>"appendonly.aof"</code>

<code>appendfsync everysec</code>

<code>no-appendfsync-on-rewrite no</code>

<code>auto-aof-rewrite-percentage 100</code>

<code>auto-aof-rewrite-min-size 64mb</code>

<code>aof-load-truncated </code><code>yes</code>

<code>lua-</code><code>time</code><code>-limit 5000</code>

<code>cluster-enabled </code><code>yes</code>       <code>-----開啟cluster</code>

<code>cluster-config-</code><code>file</code> <code>nodes.conf</code>

<code>cluster-node-timeout 5000</code>

<code>slowlog-log-slower-than 10000</code>

<code>slowlog-max-len 128</code>

<code>latency-monitor-threshold 0</code>

<code>notify-keyspace-events </code><code>""</code>

<code>hash</code><code>-max-ziplist-entries 512</code>

<code>hash</code><code>-max-ziplist-value 64</code>

<code>list-max-ziplist-entries 512</code>

<code>list-max-ziplist-value 64</code>

<code>set</code><code>-max-intset-entries 512</code>

<code>zset-max-ziplist-entries 128</code>

<code>zset-max-ziplist-value 64</code>

<code>hll-sparse-max-bytes 3000</code>

<code>activerehashing </code><code>yes</code>

<code>client-output-buffer-limit normal 0 0 0</code>

<code>client-output-buffer-limit slave 256mb 64mb 60</code>

<code>client-output-buffer-limit pubsub 32mb 8mb 60</code>

<code>hz 10</code>

<code>aof-rewrite-incremental-fsync </code><code>yes</code>

啟動所有的redis節點:

      192.168.189.144:

<code>#/usr/local/redis_cluster/9000/bin/redis-server /usr/local/redis_cluster/9000/etc/redis.conf </code>

<code>#/usr/local/redis_cluster/9001/bin/redis-server /usr/local/redis_cluster/9001/etc/redis.conf</code>

    192.168.189.145:

<code>#/usr/local/redis_cluster/8000/bin/redis-server /usr/local/redis_cluster/8000/etc/redis.conf </code>

<code>#/usr/local/redis_cluster/8001/bin/redis-server /usr/local/redis_cluster/8001/etc/redis.conf</code>

    192.168.189.146:

<code>#/usr/local/redis_cluster/7000/bin/redis-server /usr/local/redis_cluster/7000/etc/redis.conf </code>

<code>#/usr/local/redis_cluster/7001/bin/redis-server /usr/local/redis_cluster/7001/etc/redis.conf</code>

啟動完所有節點後,檢視日志,顯示如下:

<a href="http://s3.51cto.com/wyfs02/M00/72/16/wKiom1XdMQvRXoLBAADqJ4Kfgag589.jpg" target="_blank"></a>

找不到叢集配置,這是因為還沒有初始化叢集。

在192.168.189.144上使用redis-trib.rb工具,建立叢集:

<code>#bin/redis-trib.rb create --replicas 1 192.168.189.144:9000 192.168.189.145:8000 192.168.189.146:7000 192.168.189.144:9001 192.168.189.145:8001 192.168.189.146:7001</code>

(--replicas 1為每個Master指定了1個Slave,Master和Slave的角色,由輸入的順序決定)

<a href="http://s3.51cto.com/wyfs02/M00/72/12/wKioL1XdMzyzGwd_AAiLJUQ725E108.jpg" target="_blank"></a>

   從以上建立資訊可以看到,叢集自動配置設定出了Master和各自的Slave,并在Master之間配置設定了slot。叢集就建立成功了。

檢視叢集資訊(随意指定叢集中的一個節點):

<code>#bin/redis-trib.rb check 192.168.189.144:9000</code>

<code>#bin/redis-cli  -c -h 192.168.189.144 -p 9000 cluster nodes</code>

<a href="http://s3.51cto.com/wyfs02/M00/72/12/wKioL1XdM2OT6yvXAAL2hwFnRiI979.jpg" target="_blank"></a>

以上方法都可以看到叢集的狀态和各節點的資訊。

Cluster測試:

以叢集的模式,使用redis用戶端連上一個Master節點,插入一些資料:

可以看到,插入資料時,資料會自動插入到不同Master節點上的slot。說明實作了分片的目的,形成了叢集。

這時可以連接配接到叢集中的另一個結點去檢視之前插入的資料:

可以發現叢集會自動定位到key值的位置,并跳到該redis執行個體去取到需要的資料。

節點的增減:

在192.168.189.144新增兩個6000,6001的空執行個體。新增6000為叢集的新的Master,6001為6000的slave。

啟動新增執行個體:

<code>#/usr/local/redis_cluster/6000/bin/redis-server /usr/local/redis_cluster/6000/etc/redis.conf </code>

<code>#/usr/local/redis_cluster/6001/bin/redis-server /usr/local/redis_cluster/6001/etc/redis.conf</code>

添加6000為Master節點:

<code>#bin/redis-trib.rb add-node 192.168.189.144:6000 192.168.189.144:9000   (前面為新增的節點,後面為叢集裡已有的随意節點)</code>

<a href="http://s3.51cto.com/wyfs02/M02/72/16/wKiom1XdMZuBjbkyAAWQ_80ZNf0531.jpg" target="_blank"></a>

<a href="http://s3.51cto.com/wyfs02/M00/72/12/wKioL1XdM7KjkPl5AAGbmtc79ss284.jpg" target="_blank"></a>

  使用check指令檢視叢集狀态,可以看到192.168.189.144:6000已經加入叢集,角色為Master,沒有配置設定slot,是以沒有資料。

是以,需要給144:6000配置設定slot,使它能夠存放資料。

<code>#bin/redis-trib.rb reshard 192.168.189.144:6000</code>

這裡為新的節點配置設定了1000個slot。此指令可也可用于線上reshard。

在檢視144:6000的資訊,就可以看到它已有的slot了,因為試驗中我選擇了all當作source node,是以slot是從其他的各個Master配置設定過來的。一共配置設定了1000個。

為144:6000新增slave節點:

首先,先把144:6001節點加入叢集:

<code>#bin/redis-trib.rb add-node 192.168.189.144:6001 192.168.189.144:9000</code>

看到新增的節點,預設的角色都是Master,若想改變它的角色,需連接配接到該執行個體,為它指定Master。

<a href="http://s3.51cto.com/wyfs02/M01/72/12/wKioL1XdNEXwmMs6AACW-2UM1-o427.jpg" target="_blank"></a>

(後面加上的為144:6000的node ID) 

<a href="http://s3.51cto.com/wyfs02/M02/72/16/wKiom1XdMk_AKICfAABdPt_cZ3o831.jpg" target="_blank"></a>

<a href="http://s3.51cto.com/wyfs02/M01/72/12/wKioL1XdNJGzpqgGAACbQIE3zHk721.jpg" target="_blank"></a>

可以看到144:6001已經變成144:6000的Slave。

删除Slave節點:

<code>#bin/redis-trib.rb del-node 192.168.189.144:6001 '39dba7707191d350dab2ef3c47e21e21d3eaf13c'</code>

slave節點,144:6001删除完成。

删除Master節點:

<code>#bin/redis-trib.rb del-node 192.168.189.144:6000 '53f3ff88141bde0fcf1bb1d9cf044ea79b423f7d'</code>

<a href="http://s3.51cto.com/wyfs02/M02/72/16/wKiom1XdMpawYBNpAAGn8hmE0V4837.jpg" target="_blank"></a>

删除144:6000節點時,發現删除失敗,提示說該執行個體不是空的。因為144:6000上還配置設定有slot,若删除,會導緻叢集slot的不完整,是以需先移除該節點上的所有slot,才能進行删除。

<a href="http://s3.51cto.com/wyfs02/M00/72/12/wKioL1XdNLmju34lAAFu0BdzSJw622.jpg" target="_blank"></a>

用reshard指令移除slot到另一個Master節點。

<a href="http://s3.51cto.com/wyfs02/M01/72/12/wKioL1XdNMSzwvzdAAGUlMo3z2E789.jpg" target="_blank"></a>

這時再執行删除,删除成功。

叢集備援測試:

Redis Cluster的正常狀态前提是slot的完整,換句話說,隻要叢集的slot是完整的16384,則叢集就能正常工作。

關閉一個Master:

<code>#bin/redis-cli -h 192.168.189.146 -p 7000 shutdown</code>

檢視叢集狀态:

可以看到146:7000節點已經下線,它的Slave145:8001提升為Master,叢集正常工作,因為slot還保持完整。

關閉145:8001:

<code>#bin/redis-cli -h 192.168.189.145 -p 8001 shutdown</code>

可以看到145:8001已經無法連接配接,且它已經沒有備份了。這時叢集的slot發生了不完整的情況,叢集失效。

   這時再嘗試往叢集裡寫資料,提示說cluster is down,即叢集失效了。

本文轉自 icenycmh 51CTO部落格,原文連結:http://blog.51cto.com/icenycmh/1688407,如需轉載請自行聯系原作者