redis集羣搭建

搭建

第一步、安裝必須依賴包

 

    yum install -y gcc automake autoconf libtool make gcc gcc-c++ zlib zlib-devel openssl openssl-devel pcre pcre-devel curl

 

第二步、創建集羣目錄

    mkdir -p  /usr/local/redis-cluster

    mkdir -p  /usr/local/redis-cluster/bin

    cd /usr/local/redis-cluster/

    mkdir -p 9001/data  9002/data  9003/data  9004/data  9005/data  9006/data

 

第三步、將已安裝好的redis腳本拷貝值集羣bin

    cd /usr/local/redis327/src/   (備註:以前安裝的mysql目錄)

    cp mkreleasehdr.sh redis-benchmark redis-check-aof redis-check-rdb  redis-cli redis-sentinel  redis-server redis-trib.rb /usr/local/redis-cluster/bin/

    cd /usr/local/redis-cluster/

    cp -rf  /usr/local/redis327/* 9001/

    cp -rf  /usr/local/redis327/* 9002/

    cp -rf  /usr/local/redis327/* 9003/

    cp -rf  /usr/local/redis327/* 9004/

    cp -rf  /usr/local/redis327/* 9005/

    cp -rf  /usr/local/redis327/* 9006/

 

第四步、準備redis.conf文件

    注意:每隔redis.conf文件對應自己的配置,如下9001配置,其他同理

    # 端口配置

    port 9001

    # 精靈進程

    daemonize yes

    # 關閉保護模式

    protected-mode no

    #requirepass qktz123$%^

    dir /usr/local/redis-cluster/9001/data/

    pidfile /var/run/redis_9001.pid

    cluster-enabled yes

    cluster-config-file nodes9001.conf

    cluster-node-timeout 15000

    appendonly yes

 

第五步、依次啓動6個節點

    /usr/local/redis-cluster/bin/redis-server  /usr/local/redis-cluster/9001/redis.conf

    ...

    /usr/local/redis-cluster/bin/redis-server  /usr/local/redis-cluster/9006/redis.conf

   測試是否啓動成功:

        /usr/local/redis-cluster/bin/redis-cli -h 10.30.0.31 -p 9001 -c

    如下圖:

    

第六步、安裝ruby環境

    yum install ruby

    yum install rubygems

    gem install redis  (注意:如果這步出錯則按照下面解決問題)

   

 

    curl -L get.rvm.io | bash -s stable

    source  /usr/local/rvm/scripts/rvm

    rvm list known

    rvm install 2.3.4

    ruby -version

     注意:安裝成功後需要再次執行gem install redis

 

第七步、創建集羣

    /usr/local/redis-cluster/bin/redis-trib.rb create --replicas 1 10.30.0.31:9001 10.30.0.31:9002 10.30.0.31:9003 10.30.0.31:9004 10.30.0.31:9005 10.30.0.31:9006

     如下圖:

     

      執行/usr/local/redis-cluster/bin/redis-cli -h 10.30.0.31 -p 9001 -c,此時集羣創建成功

      

 

第七步、重啓或者關閉集羣

ps -ef | grep redis | awk '{print $2}' | kill -15

Redis客戶端操作

1.1. 命令行工具redis-cli

官方提供的命令行客戶端工具,在單機版redis基礎上指定參數-c”即可。以下是在192.168.0.251上執行redis-cli的記錄:

$ ./redis-cli -c -p 6379

127.0.0.1:6379> set foo bar

-> Redirected to slot [12182] located at 192.168.0.253:6379

OK

192.168.0.253:6379> set hello world

-> Redirected to slot [866] located at 192.168.0.251:6379

OK

192.168.0.251:6379> get foo

-> Redirected to slot [12182] located at 192.168.0.253:6379

"bar"

192.168.0.253:6379> get hello

-> Redirected to slot [866] located at 192.168.0.251:6379

"world"

 

查看集羣中的節點:

192.168.0.251:6379> cluster nodes

1.2. 從slaves讀數據

默認不能從slaves讀取數據,但建立連接後,執行一次命令READONLY ,即可從slaves讀取數據。如果想再次恢復不能從slaves讀取數據,可以執行下命令READWRITE

1.3. jedisjava cluster client

官網:https://github.com/xetorthio/jedis

編程示例:

Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();

//Jedis Cluster will attempt to discover cluster nodes automatically

jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7379));

JedisCluster jc = new JedisCluster(jedisClusterNodes);

jc.set("foo", "bar");

String value = jc.get("foo");

1.4. r3cC++ cluster client

官網:https://github.com/eyjian/r3c

新增節點

2.1. 添加一個新主(master)節點

先以單機版配置和啓動好redis-server,然後執行命令:

./redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000

 

執行上面這條命令時,可能遇到錯誤“[ERR] Sorry, can't connect to node 127.0.0.1:7006”。引起該問題的原因可能是因爲ruby的版本過低(運行ruby -v可以查看ruby的版本),可以嘗試升級ruby再嘗試,比如ruby 1.8.7版本就需要升級。對於Redis 3.0.5Redis 3.2.0,使用Ruby 2.3.1操作正常。請注意升級到最新版本的ruby也可能遇到這個錯誤。

 

另一個會引起這個問題的原因是從Redis 3.2.0版本開始引入了“保護模式(protected mode),防止redis-cli遠程訪問”,僅限redis-cli綁定到127.0.0.1纔可以連接Redis server

爲了完成添加新主節點,可以暫時性的關閉保護模式,使用redis-cli,不指定-h參數(但可以指定-p參數,或者-h參數值爲127.0.0.1)進入操作界面:CONFIG SET protected-mode no

 

注意7006是新增的節點,而7000是已存在的節點(可爲masterslave)。如果需要將7006變成某masterslave節點,執行命令:

cluster replicate 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e

 

新加入的master節點上沒有任何數據(slots,運行redis命令cluster nodes可以看到這個情況)。當一個slave想成爲master時,由於這個新的master節點不管理任何slots,它不參與選舉。

可以使用工具redis-trib.rbresharding特性爲這個新master節點分配slots,如:

redis-trib.rb reshard 127.0.0.1:7000,其中7000爲集羣中任意一個節點即可,redis-trib.rb將自動發現其它節點。

reshard過程中,將會詢問reshard多少slots

How many slots do you want to move (from 1 to 16384)?,取值範圍爲1~16384,其中16384redis cluster的擁有的slots總數,比如想只移動100個,輸入100即可。如果遷移的slots數量多,應當設置redis-trib.rb的超時參數--timeout值大一點。否則,遷移過程中易遇到超時錯誤[ERR] Calling MIGRATE: IOERR error or timeout reading to target instance”,導致只完成部分,可能會造成數據丟失。

接着,會提示“What is the receiving node ID?”,輸入新加入的master節點ID。過程中如果遇到錯誤Sorry, can't connect to node 10.225.168.253:6380”,則可能需要暫時先關閉相應的保護模式。

 

如果在遷移過程遇到下面這樣的錯誤:

>>> Check for open slots...

[WARNING] Node 192.168.0.3:6379 has slots in importing state (5461).

[WARNING] Node 192.168.0.5:6380 has slots in migrating state (5461).

[WARNING] The following slots are open: 5461

 

可以考慮使用命令“redis-trib.rb fix 192.168.0.3:6379”嘗試修復。需要顯示有節點處於migratingimporting狀態,可以登錄到相應的節點,使用命令cluster setslot 5461 stable”修改,參數5461爲問題顯示的slotID

2.2. 添加一個新從(slave)節點

./redis-trib.rb add-node --slave 127.0.0.1:7006 127.0.0.1:7000

 

注意這種方式,如果添加了多個slave節點,可能導致masterslaves不均衡,比如一些有3slave,其它只1slave。可以在slave節點上執行redis命令CLUSTER REPLICATE”進行調整,讓它成爲其它masterslaveCLUSTER REPLICATE”帶一個參數,即master ID,注意使用redis-cli -c登錄到slave上執行。

上面方法沒有指定7006master,而是隨機指定。下面方法可以明確指定爲哪個masterslave

./redis-trib.rb add-node --slave --master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:7006 127.0.0.1:7000

 

刪除節點

從集羣中刪除一個節點:

./redis-trib.rb del-node 127.0.0.1:7000 <node-id>

 

第一個參數爲集羣中任意一個節點,第二個參數爲需要刪除節點的ID

 

成功刪除後,再調用下CLUSTER FORGET

CLUSTER FORGET <node-id>

 

注意如果是刪除一個master節點,則需要先將它管理的slots的遷走,然後纔可以刪除它。

如果是masterslave機器不能連接,比如硬件故障導致無法啓動,這個時候做不了del-node,只需要直接做CLUSTER 即可,在FORGET後,節點狀態變成handshake

!!!請注意,需要在所有node上執行一次“CLUSTER FORGET”,否則可能遇到被剔除node的總是處於handshake狀態。

master機器硬件故障

這種情況下,master機器可能無法啓動,導致其上的master無法連接,master將一直處於master,fail”狀態,如果是slave則處於slave,fail”狀態。

如果是master,則會它的slave變成了master,因此只需要添加一個新的從節點作爲原slave(已變成master)的slave節點。完成後,通過CLUSTER FORGET將故障的masterslave從集羣中剔除即可。

!!!請注意,需要在所有node上執行一次“CLUSTER FORGET”,否則可能遇到被剔除node的總是處於handshake狀態。

檢查節點狀態

redis-trib.rb check 127.0.0.1:6380

 

如發現如下這樣的錯誤:

[WARNING] Node 192.168.0.11:6380 has slots in migrating state (5461).

[WARNING] The following slots are open: 5461

 

可以使用redis命令取消slots遷移(5461slotID):

cluster setslot 5461 stable

需要注意,須登錄到192.168.0.11:6380上執行redissetslot子命令。

變更主從關係

使用命令cluster replicate,參數爲master節點ID,注意不是IP和端口,在被遷移的slave上執行該命令。

slots相關命令

CLUSTER ADDSLOTS slot1 [slot2] ... [slotN]

CLUSTER DELSLOTS slot1 [slot2] ... [slotN]

CLUSTER SETSLOT slot NODE node

CLUSTER SETSLOT slot MIGRATING node

CLUSTER SETSLOT slot IMPORTING node

 

3.1. 遷移slosts

示例:將slot8從節點A遷移到節點B,有如下兩種方法:

在節點B上執行:CLUSTER SETSLOT 8 IMPORTING A

在節點A上執行:CLUSTER SETSLOT 8 MIGRATING B

3.2. redis-trib.rb rebalance

當有增減節點時,可以使用命令:

redis-trib.rb rebalance 192.168.0.31:6379 --auto-weights

做一次均衡,簡單點可以只指定兩個參數:“192.168.0.31:6379”爲集羣中已知的任何一個節點,參數“-auto-weights”表示自動權重。

人工主備切換

在需要的slaves節點上執行命令:CLUSTER FAILOVER

查看集羣信息

對應的redis命令爲:cluster info,示例:

127.0.0.1:6381> cluster info

cluster_state:ok 所有slots正常則顯示爲OK,否則爲error

cluster_slots_assigned:16384 多少slots被分配了,即多少被master管理了,16384爲全部slots

cluster_slots_ok:16384 有多少slots是正常的

cluster_slots_pfail:0 有多少slots可能處於異常狀態,處於這個狀態並不表示有問題,仍能繼續提供服務

cluster_slots_fail:0 有多少slots處於異常狀態,需要修復才能服務

cluster_known_nodes:10 集羣中的節點數

cluster_size:3 集羣中master個數

cluster_current_epoch:11 本地的當前時間變量,用於故障切換時生成獨一無二的增量版本號

cluster_my_epoch:0

cluster_stats_messages_sent:4049 通過集羣消息總線發送的消息總數

cluster_stats_messages_received:4051 通過過集通過羣消息總線收到的消息總數

禁止指定命令

KEYS命令很耗時,FLUSHDBFLUSHALL命令可能導致誤刪除數據,所以線上環境最好禁止使用,可以在Redis配置文件增加如下配置:

rename-command KEYS ""

rename-command FLUSHDB ""

rename-command FLUSHALL ""

 

常見故障

1[root@qkzhi-appzookeeper-1 bin]# ./redis-trib.rb create 10.30.0.31:9002

[ERR] Sorry, can't connect to node 10.30.0.31:9002

解決思路:

如果在升級ruby的前提下,出現這種問題,一般是redis配置了#masterauth "qktz123$%^"

#requirepass "qktz123$%^"後,需要進行如下修改:

vi /usr/local/rvm/gems/ruby-2.3.4/gems/redis-4.0.1/lib/redis/client.rb

 

如果不需要密碼認證後,直接將password這一行刪掉。

2如果最後一條日誌爲“16367:M 08 Jun 14:48:15.560 # Server started, Redis version 3.2.0”,節點狀態始終終於fail狀態,則可能是aof文件損壞了,這時可以使用工具edis-check-aof --fix進行修改,如:

../../bin/redis-check-aof --fix appendonly-6380.aof 

0x        a1492b9b: Expected prefix '

AOF analyzed: size=2705928192, ok_up_to=2705927067, diff=1125

This will shrink the AOF from 2705928192 bytes, with 1125 bytes, to 2705927067 bytes

Continue? [y/N]: y

3 in `call': ERR Slot 16011 is already busy (Redis::CommandError)

將所有節點上的配置項cluster-config-file指定的文件刪除,然後重新啓;或者在所有節點上執行下FLUSHALL命令。

另外,如果使用主機名而不是IP,也可能遇到這個錯誤,如:redis-trib.rb create --replicas 1 redis1:6379 redis2:6379 redis3:6379 redis4:6379 redis5:6379 redis6:6379”,可能也會得到錯誤“ERR Slot 16011 is already busy (Redis::CommandError)”。

4for lack of backlog (Slave request was: 51875158284)

默認值:

# redis-cli config get repl-timeout

A) "repl-timeout"

B) "10"

# redis-cli config get client-output-buffer-limit

A) "client-output-buffer-limit"

B) "normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60"

 

增大:

redis-cli config set "client-output-buffer-limit" "normal 0 0 0 slave 2684354560 671088640 60 pubsub 33554432 8388608 60"

5 複製中斷場景

A) masterslave緩衝區達到限制的硬或軟限制大小,與參數client-output-buffer-limit相關;

B) 複製時間超過repl-timeout指定的值,與參數repl-timeout相關。

 

slave反覆循環從master複製,如果調整以上參數仍然解決不了,可以嘗試刪除slave上的aofrdb文件,然後再重啓進程複製,這個時候可能能正常完成複製。

 

 

 

 


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