redis之cluster集群部署

一、redis cluster簡介

Redis在3.0版正式引入了集群這個特性。

Redis集群是一個提供在多個Redis間節(jié)點間共享數(shù)據(jù)的程序集。

Redis集群是一個分布式(distributed)、容錯(fault-tolerant)的Redis內(nèi)存K/V服務(wù),集群可以使用的功能是普通單機Redis所能使用的功能的一個子集(subset),比如Redis集群并不支持處理多個keys的命令,因為這需要在不同的節(jié)點間移動數(shù)據(jù),從而達不到像Redis那樣的性能,在高負載的情況下可能會導(dǎo)致不可預(yù)料的錯誤。還有比如set里的并集(unions)和交集(intersections)操作,就沒有實現(xiàn)。通常來說,那些處理命令的節(jié)點獲取不到鍵值的所有操作都不會被實現(xiàn)。在將來,用戶或許可以通過使用MIGRATE COPY命令,在集群上用計算節(jié)點(Computation Nodes) 來執(zhí)行多鍵值的只讀操作, 但Redis集群本身不會執(zhí)行復(fù)雜的多鍵值操作來把鍵值在節(jié)點間移來移去。

Redis集群不像單機版本的Redis那樣支持多個數(shù)據(jù)庫,集群只有數(shù)據(jù)庫0,而且也不支持SELECT命令。

Redis集群通過分區(qū)來提供一定程度的可用性,在實際環(huán)境中當某個節(jié)點宕機或者不可達的情況下繼續(xù)處理命令。

Redis集群的優(yōu)點:

無中心架構(gòu),分布式提供服務(wù)。

數(shù)據(jù)按照slot存儲分布在多個redis實例上。

增加slave做standby數(shù)據(jù)副本,用于failover,使集群快速恢復(fù)。

實現(xiàn)故障auto failover,節(jié)點之間通過gossip協(xié)議交換狀態(tài)信息;投票機制完成slave到master角色的提升。

支持在線增加或減少節(jié)點。

降低硬件成本和運維成本,提高系統(tǒng)的擴展性和可用性。

Redis集群的缺點:

client實現(xiàn)復(fù)雜,驅(qū)動要求實現(xiàn)smart client,緩存slots mapping信息并及時更新。

目前僅JedisCluster相對成熟,異常處理部分還不完善,比如常見的“max redirect exception”。

客戶端的不成熟,影響應(yīng)用的穩(wěn)定性,提高開發(fā)難度。

節(jié)點會因為某些原因發(fā)生阻塞(阻塞時間大于clutser-node-timeout),被判斷下線。這種failover是沒有必要,sentinel也存在這種切換場景。


二、環(huán)境說明:

1、操作系統(tǒng):CentOS Linux release 7.3.1611

2、redis版本:redis-4.0.6

3、服務(wù)器共3臺:

192.168.10.91

192.168.10.92

192.168.10.93


三、安裝redis(3臺服務(wù)器都需要安裝)

1、下載redis源碼包:

wget http://download.redis.io/releases/redis-4.0.6.tar.gz

2、解壓源碼包:

tar zxvf redis-4.0.6.tar.gz

3、編譯安裝:

make

make PREFIX=/app/redis install


四、集群部署

1、創(chuàng)建集群需要的目錄(三臺機器都要創(chuàng)建)

mkdir -p /data/redis/cluster-6379/{conf,data,log,pid}

mkdir -p /data/redis/cluster-6380/{conf,data,log,pid}

mkdir -p /data/redis/cluster-6381/{conf,data,log,pid}

2、為每個實例創(chuàng)建配置文件(三臺機器都要配置),以端口6379為例,其他實例省略

cat?/data/redis/cluster-6379/conf/redis.conf

port 6379

bind 0.0.0.0

daemonize yes

protected-mode yes

cluster-enabled yes

cluster-config-file /data/redis/cluster-6379/nodes.conf

cluster-node-timeout 5000

appendonly yes

dir /data/redis/cluster-6379/data

3、啟動各實例并查看

./redis-server /data/redis/cluster-6379/conf/redis.conf

./redis-server /data/redis/cluster-6380/conf/redis.conf

./redis-server /data/redis/cluster-6381/conf/redis.conf

現(xiàn)在我們已經(jīng)有了9個正在運行中的Redis實例, 接下來我們需要使用這些實例來創(chuàng)建集群。通過使用Redis集群命令行工具redis-trib,編寫節(jié)點配置文件的工作可以非常容易地完成:redis-trib位于Redis源碼的src文件夾中,它是一個Ruby程序,這個程序通過向?qū)嵗l(fā)送特殊命令來完成創(chuàng)建新集群, 檢查集群, 或者對集群進行重新分片(reshared)等工作。但是redis-trib是Ruby程序,所以需要解決Ruby依賴。

4、安裝集群依賴環(huán)境

4.1、安裝ruby2.4.1

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

source /usr/local/rvm/scripts/rvm

rvm list known

rvm install 2.4.1

ruby --version

4.2、安裝gem redis

gem install redis

5、創(chuàng)建集群

./redis-trib.rb create --replicas 2 192.168.10.91:6379 192.168.10.91:6380 192.168.10.91:6381 192.168.10.92:6379 192.168.10.92:6380 192.168.10.92:6381 192.168.10.93:6379 192.168.10.93:6380 192.168.10.93:6381

>>> Creating cluster

>>> Performing hash slots allocation on 9 nodes...

Using 3 masters:

192.168.10.91:6379

192.168.10.92:6379

192.168.10.93:6379

Adding replica 192.168.10.92:6380 to 192.168.10.91:6379

Adding replica 192.168.10.93:6380 to 192.168.10.91:6379

Adding replica 192.168.10.91:6380 to 192.168.10.92:6379

Adding replica 192.168.10.91:6381 to 192.168.10.92:6379

Adding replica 192.168.10.92:6381 to 192.168.10.93:6379

Adding replica 192.168.10.93:6381 to 192.168.10.93:6379

M: f0ddd134da674ac6f7d2805c5b6a59c346df9c80 192.168.10.91:6379

? slots:0-5460 (5461 slots) master

S: cd1520b19c7374d82b9712c6f42b8ec3b599d04f 192.168.10.91:6380

? replicates fb843114f6e4d7988971422be3f370bfce2c1fb9

S: 8728bc5408f9b305fbd0354ba7eaf74e71f00128 192.168.10.91:6381

? replicates fb843114f6e4d7988971422be3f370bfce2c1fb9

M: fb843114f6e4d7988971422be3f370bfce2c1fb9 192.168.10.92:6379

? slots:5461-10922 (5462 slots) master

S: c899a39d04a287e0a65b649a88b1369eb1916b97 192.168.10.92:6380

? replicates f0ddd134da674ac6f7d2805c5b6a59c346df9c80

S: f7c4e797a02f75d9e4e0f26dae448cde3be864d7 192.168.10.92:6381

? replicates 724c6c355513dabd8f017817443a4631fbcf72fe

M: 724c6c355513dabd8f017817443a4631fbcf72fe 192.168.10.93:6379

? slots:10923-16383 (5461 slots) master

S: 8096d93d8b2b00810cf528554d6a17981547183a 192.168.10.93:6380

? replicates f0ddd134da674ac6f7d2805c5b6a59c346df9c80

S: 4236e756d7df651956895c608153233230e8bb9e 192.168.10.93:6381

? replicates 724c6c355513dabd8f017817443a4631fbcf72fe

Can I set the above configuration? (type 'yes' to accept): yes

>>> Nodes configuration updated

>>> Assign a different config epoch to each node

>>> Sending CLUSTER MEET messages to join the cluster

Waiting for the cluster to join.....

>>> Performing Cluster Check (using node 192.168.10.91:6379)

M: f0ddd134da674ac6f7d2805c5b6a59c346df9c80 192.168.10.91:6379

? slots:0-5460 (5461 slots) master

? 2 additional replica(s)

S: 8728bc5408f9b305fbd0354ba7eaf74e71f00128 192.168.10.91:6381

? slots: (0 slots) slave

? replicates fb843114f6e4d7988971422be3f370bfce2c1fb9

M: 724c6c355513dabd8f017817443a4631fbcf72fe 192.168.10.93:6379

? slots:10923-16383 (5461 slots) master

? 2 additional replica(s)

M: fb843114f6e4d7988971422be3f370bfce2c1fb9 192.168.10.92:6379

? slots:5461-10922 (5462 slots) master

? 2 additional replica(s)

S: c899a39d04a287e0a65b649a88b1369eb1916b97 192.168.10.92:6380

? slots: (0 slots) slave

? replicates f0ddd134da674ac6f7d2805c5b6a59c346df9c80

S: 4236e756d7df651956895c608153233230e8bb9e 192.168.10.93:6381

? slots: (0 slots) slave

? replicates 724c6c355513dabd8f017817443a4631fbcf72fe

S: 8096d93d8b2b00810cf528554d6a17981547183a 192.168.10.93:6380

? slots: (0 slots) slave

? replicates f0ddd134da674ac6f7d2805c5b6a59c346df9c80

S: cd1520b19c7374d82b9712c6f42b8ec3b599d04f 192.168.10.91:6380

? slots: (0 slots) slave

? replicates fb843114f6e4d7988971422be3f370bfce2c1fb9

S: f7c4e797a02f75d9e4e0f26dae448cde3be864d7 192.168.10.92:6381

? slots: (0 slots) slave

? replicates 724c6c355513dabd8f017817443a4631fbcf72fe

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

這個命令在這里用于創(chuàng)建一個新的集群(create),選項–replicas 2表示我們希望為集群中的每個主節(jié)點創(chuàng)建2個從節(jié)點。之后跟著的其他參數(shù)則是這個集群實例的地址列表,3個master6個slave。redis-trib會打印出一份預(yù)想中的配置給你看,如果你覺得沒問題的話,就可以輸入yes ,redis-trib就會將這份配置應(yīng)用到集群當中,讓各個節(jié)點開始互相通訊,最后可以得到如下信息:

6、集群狀態(tài)查看

/app/redis/bin/redis-cli -c -p 6379

6.1、集群節(jié)點信息查看命令“cluster nodes”

127.0.0.1:6379> CLUSTER nodes

8728bc5408f9b305fbd0354ba7eaf74e71f00128 192.168.10.91:6381@16381 slave fb843114f6e4d7988971422be3f370bfce2c1fb9 0 1515492930073 4 connected

724c6c355513dabd8f017817443a4631fbcf72fe 192.168.10.93:6379@16379 master - 0 1515492930000 7 connected 10923-16383

fb843114f6e4d7988971422be3f370bfce2c1fb9 192.168.10.92:6379@16379 master - 0 1515492931075 4 connected 5461-10922

f0ddd134da674ac6f7d2805c5b6a59c346df9c80 192.168.10.91:6379@16379 myself,master - 0 1515492931000 1 connected 0-5460

c899a39d04a287e0a65b649a88b1369eb1916b97 192.168.10.92:6380@16380 slave f0ddd134da674ac6f7d2805c5b6a59c346df9c80 0 1515492932080 5 connected

4236e756d7df651956895c608153233230e8bb9e 192.168.10.93:6381@16381 slave 724c6c355513dabd8f017817443a4631fbcf72fe 0 1515492930074 9 connected

8096d93d8b2b00810cf528554d6a17981547183a 192.168.10.93:6380@16380 slave f0ddd134da674ac6f7d2805c5b6a59c346df9c80 0 1515492930074 8 connected

cd1520b19c7374d82b9712c6f42b8ec3b599d04f 192.168.10.91:6380@16380 slave fb843114f6e4d7988971422be3f370bfce2c1fb9 0 1515492931000 4 connected

f7c4e797a02f75d9e4e0f26dae448cde3be864d7 192.168.10.92:6381@16381 slave 724c6c355513dabd8f017817443a4631fbcf72fe 0 1515492931578 7 connected

第一個參數(shù):節(jié)點ID;

第二個參數(shù):IP和端口;

第三、四個參數(shù):節(jié)點狀態(tài),會有master, slave, myself, fail, …這幾種;如果是個從節(jié)點, 這里是它的主節(jié)點的NODE ID;

第五、六個參數(shù):集群最近一次向節(jié)點發(fā)送PING命令之后,過去了多長時間還沒接到回復(fù);

第七、八個參數(shù):節(jié)點最近一次返回PONG回復(fù)的時間節(jié)點的配置紀元(configuration epoch),詳細信息請參考Redis集群規(guī)范;

第九、十個參數(shù):本節(jié)點的網(wǎng)絡(luò)連接情況,例如connected。

第十一個參數(shù):節(jié)點目前包含的槽,例如10.99.73.11:6551目前包含號碼為0至5460的哈希槽。

6.2、集群狀態(tài)信息查看命令“cluster info”

127.0.0.1:6379> CLUSTER info

cluster_state:ok

cluster_slots_assigned:16384

cluster_slots_ok:16384

cluster_slots_pfail:0

cluster_slots_fail:0

cluster_known_nodes:9

cluster_size:3

cluster_current_epoch:9

cluster_my_epoch:1

cluster_stats_messages_ping_sent:622

cluster_stats_messages_pong_sent:614

cluster_stats_messages_sent:1236

cluster_stats_messages_ping_received:606

cluster_stats_messages_pong_received:622

cluster_stats_messages_meet_received:8

cluster_stats_messages_received:1236


五、集群測試

Redis集群現(xiàn)階段的一個問題是客戶端實現(xiàn)很少,以下是官網(wǎng)給出的目前Redis集群僅有的客戶端的實現(xiàn):

redis-rb-cluster,是作者編寫的Ruby實現(xiàn),用于作為其他實現(xiàn)的參考。該實現(xiàn)是對redis-rb的一個簡單包裝,高效地實現(xiàn)了與集群進行通訊所需的最少語義(semantic)。

redis-py-cluster,看上去是redis-rb-cluster的一個Python版本, 這個項目有一段時間沒有更新了(最后一次提交是在好幾個月之前), 不過可以將這個項目用作學習集群的起點。

Jedis,Jedis最近添加了對集群的支持,使用最多的是java客戶端,詳細請查看項目README中Jedis Cluster部分。

StackExchange.Redis,提供對C#的支持(并且包括大部分 .NET 下面的語言,比如: VB, F#等等)。

thunk-redis,提供對Node.js和io.js的支持。

測試Redis集群比較簡單的辦法就是使用redis-rb-cluster或者redis-cli ,接下來我們將使用redis-cli為例來進行演示:

我們輸入redis-cli -h 127.0.0.1 -p 6551 -c命令,切忌要加入-c,否則我們進入的不是集群環(huán)境。進入客戶端以后,我們輸入set a 100發(fā)現(xiàn)他會進行跳轉(zhuǎn),這就是因為他經(jīng)過計算以后,要存儲100的hash槽在7003實例上。這樣就表示我們的集群成功了!

#/app/redis/bin/redis-cli -c -p 6379

127.0.0.1:6379> set name WADE

OK

127.0.0.1:6379> set address shenzhen

-> Redirected to slot [3680] located at 192.168.10.91:6379

OK

192.168.10.91:6379> get name

-> Redirected to slot [5798] located at 192.168.10.92:6379

"WADE"

192.168.10.92:6379> get address

-> Redirected to slot [3680] located at 192.168.10.91:6379

"shenzhen"

redis-cli對集群的支持是非常基本的,所以它總是依靠 Redis 集群節(jié)點來將它轉(zhuǎn)向(redirect)至正確的節(jié)點。一個真正的(serious)集群客戶端應(yīng)該做得比這更好: 它應(yīng)該用緩存記錄起哈希槽與節(jié)點地址之間的映射(map), 從而直接將命令發(fā)送到正確的節(jié)點上面。這種映射只會在集群的配置出現(xiàn)某些修改時變化, 比如說, 在一次故障轉(zhuǎn)移(failover)之后, 或者系統(tǒng)管理員通過添加節(jié)點或移除節(jié)點來修改了集群的布局(layout)之后, 諸如此類。

另外關(guān)閉redis集群不能直接kill掉進程,或者關(guān)機,我們要通過命令:

# redis-cli -p -c 6379 shutdown

進行關(guān)閉,這樣在關(guān)閉之前,數(shù)據(jù)才能夠進行保存。

一般應(yīng)用程序端在操作redis cluster的時候只需要把集群節(jié)點都添加進配置文件即可,但是一般填寫5-6個節(jié)點即可。在操作上,不管是主節(jié)點操作還是從節(jié)點操作都是可以進行一次操作的成功,因為就算在從節(jié)點進行寫入,他也會重定向到主節(jié)點上進行操作的。


六、集群常見操作命令

1、集群狀態(tài)

CLUSTER INFO????#打印集群的信息;

CLUSTER NODES????#列出集群當前已知的所有節(jié)點(node),以及這些節(jié)點的相關(guān)信息;

2、節(jié)點(nodes)

CLUSTER MEET? ? #將ip和port所指定的節(jié)點添加到集群當中,讓它成為集群的一份子;

CLUSTER FORGET? ? #從集群中移除指定的節(jié)點;

CLUSTER REPLICATE? ? #將當前節(jié)點設(shè)置為指定的節(jié)點的從節(jié)點;

CLUSTER SAVECONFIG????#將節(jié)點的配置文件保存到硬盤里面;

3、槽(slot)

CLUSTER ADDSLOTS [slot ...]????#將一個或多個槽(slot)指派(assign)給當前節(jié)點;

CLUSTER DELSLOTS [slot ...]????#移除一個或多個槽對當前節(jié)點的指派;

CLUSTER FLUSHSLOTS????#移除指派給當前節(jié)點的所有槽,讓當前節(jié)點變成一個沒有指派任何槽的節(jié)點;

CLUSTER SETSLOT NODE? ? #將槽指派給指定的節(jié)點,如果槽已經(jīng)指派給另一個節(jié)點,那么先讓另一個節(jié)點刪除該槽>,然后再進行指派;

CLUSTER SETSLOT MIGRATING???? #將本節(jié)點的槽遷移到指定的節(jié)點中;

CLUSTER SETSLOT IMPORTING???? #從指定的節(jié)點中導(dǎo)入槽到本節(jié)點中;??

CLUSTER SETSLOT STABLE????#取消對槽的導(dǎo)入(import)或者遷移(migrate);

4、鍵(key)

CLUSTER KEYSLOT? ? #計算鍵key應(yīng)該被放置在哪個槽上; ?

CLUSTER COUNTKEYSINSLOT? ? #返回槽slot目前包含的鍵值對數(shù)量;??

CLUSTER GETKEYSINSLOT? ? #返回count個slot槽中的鍵;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容