Redis集群
一、Redis集群相關(guān)概念
1.Redis集群介紹
Redis 集群是一個(gè)提供在多個(gè)Redis間節(jié)點(diǎn)間共享數(shù)據(jù)的程序集。
Redis集群并不支持處理多個(gè)keys的命令,因?yàn)檫@需要在不同的節(jié)點(diǎn)間移動(dòng)數(shù)據(jù),從而達(dá)不到像Redis那樣的性能,在高負(fù)載的情況下可能會(huì)導(dǎo)致不可預(yù)料的錯(cuò)誤.
Redis 集群通過(guò)分區(qū)來(lái)提供一定程度的可用性,在實(shí)際環(huán)境中當(dāng)某個(gè)節(jié)點(diǎn)宕機(jī)或者不可達(dá)的情況下繼續(xù)處理命令. Redis 集群的優(yōu)勢(shì):
1.自動(dòng)分割數(shù)據(jù)到不同的節(jié)點(diǎn)上。
>2.整個(gè)集群的部分節(jié)點(diǎn)失敗或者不可達(dá)的情況下能夠繼續(xù)處理命令。
2.Redis分片策略
Redis 集群沒(méi)有使用一致性hash, 而是引入了 哈希槽的概念.
Redis 集群有==16384==個(gè)哈希槽,每個(gè)key通過(guò)CRC16校驗(yàn)后對(duì)16384取模來(lái)決定放置哪個(gè)槽.集群的每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分hash槽,舉個(gè)例子,比如當(dāng)前集群有3個(gè)節(jié)點(diǎn),那么:
節(jié)點(diǎn) A 包含 0 到 5500號(hào)哈希槽.
節(jié)點(diǎn) B 包含5501 到 11000 號(hào)哈希槽.
節(jié)點(diǎn) C 包含11001 到 16384號(hào)哈希槽.
這種結(jié)構(gòu)很容易添加或者刪除節(jié)點(diǎn). 比如如果我想新添加個(gè)節(jié)點(diǎn)D, 我需要從節(jié)點(diǎn) A, B, C中得部分槽到D上. 如果我想移除節(jié)點(diǎn)A,需要將A中的槽移到B和C節(jié)點(diǎn)上,然后將沒(méi)有任何槽的A節(jié)點(diǎn)從集群中移除即可. 由于從一個(gè)節(jié)點(diǎn)將哈希槽移動(dòng)到另一個(gè)節(jié)點(diǎn)并不會(huì)停止服務(wù),所以無(wú)論添加刪除或者改變某個(gè)節(jié)點(diǎn)的哈希槽的數(shù)量都不會(huì)造成集群不可用的狀態(tài).
3.Redis的主從復(fù)制模型
為了使在部分節(jié)點(diǎn)失敗或者大部分節(jié)點(diǎn)無(wú)法通信的情況下集群仍然可用,所以集群使用了主從復(fù)制模型,每個(gè)節(jié)點(diǎn)都會(huì)有N-1個(gè)復(fù)制品.
在我們例子中具有A,B,C三個(gè)節(jié)點(diǎn)的集群,在沒(méi)有復(fù)制模型的情況下,如果節(jié)點(diǎn)B失敗了,那么整個(gè)集群就會(huì)以為缺少5501-11000這個(gè)范圍的槽而不可用.
然而如果在集群創(chuàng)建的時(shí)候(或者過(guò)一段時(shí)間)我們?yōu)槊總€(gè)節(jié)點(diǎn)添加一個(gè)從節(jié)點(diǎn)A1,B1,C1,那么整個(gè)集群便有三個(gè)master節(jié)點(diǎn)和三個(gè)slave節(jié)點(diǎn)組成,這樣在節(jié)點(diǎn)B失敗后,集群便會(huì)選舉B1為新的主節(jié)點(diǎn)繼續(xù)服務(wù),整個(gè)集群便不會(huì)因?yàn)椴壅也坏蕉豢捎昧?/p>
不過(guò)當(dāng)B和B1 都失敗后,集群是不可用的.
二、Redis集群搭建
1.集群的結(jié)構(gòu)
根據(jù)官網(wǎng)描述要讓redis集群環(huán)境正常運(yùn)行我們必須準(zhǔn)備至少3個(gè)主節(jié)點(diǎn),所以在本文中的集群環(huán)境我們準(zhǔn)備3個(gè)主節(jié)點(diǎn)實(shí)例及對(duì)應(yīng)的給每個(gè)主節(jié)點(diǎn)準(zhǔn)備一個(gè)從節(jié)點(diǎn)實(shí)例,一共6個(gè)redis實(shí)例。正常需要6個(gè)虛擬機(jī)節(jié)點(diǎn),本文我們?cè)谝粋€(gè)虛擬機(jī)上模擬。
2.集群的環(huán)境準(zhǔn)備
搭建集群需要使用到官方提供的ruby腳本。
需要安裝ruby的環(huán)境。
安裝ruby
yum -yinstallrubyyum -yinstallrubygemsgeminstallredis
錯(cuò)誤處理
[root@hadoop-node01 src]# gem install redisERROR:? Error installing redis:? ? redis requires Ruby version >=2.2.2.
解決方式參考此鏈接:https://blog.csdn.net/qq_38526573/article/details/87220510
解決完成后再次執(zhí)行g(shù)em install redis命令
[root@hadoop-node01 ~]#geminstallredisFetching:redis-4.1.0.gem(100%)Successfullyinstalledredis-4.1.0Parsingdocumentationforredis-4.1.0Installingridocumentationforredis-4.1.0Doneinstallingdocumentationforredisafter1seconds1geminstalled
注意ruby對(duì)應(yīng)的redis版本是4.1.0
各版本下載地址
http://download.redis.io/releases/
3.搭建集群環(huán)境
3.1創(chuàng)建實(shí)例
在/opt目錄下創(chuàng)建redis-cluster目錄,并在該目錄下創(chuàng)建6個(gè)redis實(shí)例

3.2修改配置文件
分別修改6個(gè)實(shí)例的配置文件
1.修改端口號(hào)

2.打開cluster-enable前面的注釋

3.注釋掉綁定ip
4.保護(hù)模式修改為no
5.設(shè)置日志存儲(chǔ)路徑

注意重復(fù)修改6次。
3.3復(fù)制ruby腳本
3.4啟動(dòng)6個(gè)實(shí)例
啟動(dòng)實(shí)例時(shí)可能報(bào)錯(cuò)
Ps:[ERR]Node172.168.63.202:7001isnotempty.Eitherthenodealreadyknowsothernodes(checkwithCLUSTERNODES)orcontainssome
解決辦法:
將每個(gè)節(jié)點(diǎn)下aof、rdb、nodes.conf本地備份文件刪除;
編寫簡(jiǎn)單腳本啟動(dòng)
start-all.sh
cd/opt/redis-cluster/redis7001rm -rf dump.rdb nodes.conf appendonly.aofsrc/redis-server redis.confcd/opt/redis-cluster/redis7002rm -rf dump.rdb nodes.conf appendonly.aofsrc/redis-server redis.confcd/opt/redis-cluster/redis7003rm -rf dump.rdb nodes.conf appendonly.aofsrc/redis-server redis.confcd/opt/redis-cluster/redis7004rm -rf dump.rdb nodes.conf appendonly.aofsrc/redis-server redis.confcd/opt/redis-cluster/redis7005rm -rf dump.rdb nodes.conf appendonly.aofsrc/redis-server redis.confcd/opt/redis-cluster/redis7006rm -rf dump.rdb nodes.conf appendonly.aofsrc/redis-server redis.conf
改變文件腳本權(quán)限模式:
chmod 777 start-all.sh
然后再啟動(dòng):
./start-all.sh
3.5創(chuàng)建集群
現(xiàn)在我們已經(jīng)有了六個(gè)正在運(yùn)行中的 Redis 實(shí)例, 接下來(lái)我們需要使用這些實(shí)例來(lái)創(chuàng)建集群, 并為每個(gè)節(jié)點(diǎn)編寫配置文件。
通過(guò)使用 Redis 集群命令行工具 redis-trib , 編寫節(jié)點(diǎn)配置文件的工作可以非常容易地完成: redis-trib 位于 Redis 源碼的 src 文件夾中, 它是一個(gè) Ruby 程序, 這個(gè)程序通過(guò)向?qū)嵗l(fā)送特殊命令來(lái)完成創(chuàng)建新集群, 檢查集群, 或者對(duì)集群進(jìn)行重新分片(reshared)等工作
./redis-trib.rbcreate--replicas 1 192.168.88.121:7001 192.168.88.121:7002 192.168.88.121:7003 192.168.88.121:7004 192.168.88.121:7005 192.168.88.121:7006
命令說(shuō)明
選項(xiàng)–replicas 1 表示我們希望為集群中的每個(gè)主節(jié)點(diǎn)創(chuàng)建一個(gè)從節(jié)點(diǎn)
之后跟著的其他參數(shù)則是這個(gè)集群實(shí)例的地址列表,3個(gè)master3個(gè)slave
redis-trib 會(huì)打印出一份預(yù)想中的配置給你看, 如果你覺(jué)得沒(méi)問(wèn)題的話, 就可以輸入 ==yes==, redis-trib 就會(huì)將這份配置應(yīng)用到集群當(dāng)中,讓各個(gè)節(jié)點(diǎn)開始互相通訊,最后可以得到如下信息:
[root@hadoop-node01 redis-cluster]# ./redis-trib.rb create --replicas 1 192.168.88.121:7001192.168.88.121:7002192.168.88.121:7003192.168.88.121:7004192.168.88.121:7005192.168>>> Creating clusterInvalid IPorPort (given as192.168) - useIP:Port format[root@hadoop-node01 redis-cluster]# ./redis-trib.rb create --replicas 1 192.168.88.121:7001192.168.88.121:7002192.168.88.121:7003192.168.88.121:7004192.168.88.121:7005192.168.88.121:7006>>> Creating cluster>>> Performing hash slots allocation on6nodes...Using3masters:192.168.88.121:7001
192.168.88.121:7002
192.168.88.121:7003
Adding replica 192.168.88.121:7005 to 192.168.88.121:7001
Adding replica 192.168.88.121:7006 to 192.168.88.121:7002
Adding replica 192.168.88.121:7004 to 192.168.88.121:7003
>>> Trying to optimize slaves allocation for anti-affinity[WARNING] Some slaves areinthe same host as their masterM:f97aa0b15e5a7f51c69f26543e7b785d52479afe192.168.88.121:7001slots:0-5460(5461slots) masterM:8e4a66caac1f738e9d951d212a5ba2a00e675acd192.168.88.121:7002slots:5461-10922(5462slots) masterM:1528779486cb926b11cb996c5682c6b749d26bc1192.168.88.121:7003slots:10923-16383(5461slots) masterS:ea08ca738d621c5161a0ecfe838ed8fd89f5c0c5192.168.88.121:7004replicates8e4a66caac1f738e9d951d212a5ba2a00e675acdS:0ac234a10f28e24173ffc4e686073fa7710dd264192.168.88.121:7005replicates1528779486cb926b11cb996c5682c6b749d26bc1S:d560e0e3da9a715fb4aae5910cf5533cec2f815f192.168.88.121:7006replicates f97aa0b15e5a7f51c69f26543e7b785d52479afeCan 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 clusterWaitingforthe cluster to join......>>> Performing Cluster Check (using node192.168.88.121:7001)M:f97aa0b15e5a7f51c69f26543e7b785d52479afe192.168.88.121:7001slots:0-5460(5461slots) master1additional replica(s)S:d560e0e3da9a715fb4aae5910cf5533cec2f815f192.168.88.121:7006slots:(0slots) slave? replicates f97aa0b15e5a7f51c69f26543e7b785d52479afeM:1528779486cb926b11cb996c5682c6b749d26bc1192.168.88.121:7003slots:10923-16383(5461slots) master1additional replica(s)M:8e4a66caac1f738e9d951d212a5ba2a00e675acd192.168.88.121:7002slots:5461-10922(5462slots) master1additional replica(s)S:0ac234a10f28e24173ffc4e686073fa7710dd264192.168.88.121:7005slots:(0slots) slave? replicates1528779486cb926b11cb996c5682c6b749d26bc1S:ea08ca738d621c5161a0ecfe838ed8fd89f5c0c5192.168.88.121:7004slots:(0slots) slave? replicates8e4a66caac1f738e9d951d212a5ba2a00e675acd[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All16384slots covered.
這表示集群中的 16384 個(gè)槽都有至少一個(gè)主節(jié)點(diǎn)在處理, 集群運(yùn)作正常。
4.測(cè)試集群
登錄命令
redis7001/src/redis-cli -h 192.168.88.121 -p 7001 -c
添加一個(gè)key被分配到7002節(jié)點(diǎn)上,注意連接的端口變?yōu)榱?002。
5.查看集群環(huán)境
命令說(shuō)明
cluster info打印集群的信息
cluster nodes列出集群當(dāng)前已知的所有節(jié)點(diǎn)( node),以及這些節(jié)點(diǎn)的相關(guān)信息。節(jié)點(diǎn)
cluster meet <ip> <port>將 ip 和 port 所指定的節(jié)點(diǎn)添加到集群當(dāng)中,讓它成為集群的一份子。
cluster forget從集群中移除 node_id 指定的節(jié)點(diǎn)。
cluster replicate將當(dāng)前節(jié)點(diǎn)設(shè)置為 node_id 指定的節(jié)點(diǎn)的從節(jié)點(diǎn)。
cluster saveconfig將節(jié)點(diǎn)的配置文件保存到硬盤里面。槽(slot)
cluster addslots
[slot ...]
將一個(gè)或多個(gè)槽( slot)指派( assign)給當(dāng)前節(jié)點(diǎn)。
cluster delslots
[slot ...]
移除一個(gè)或多個(gè)槽對(duì)當(dāng)前節(jié)點(diǎn)的指派。
cluster flushslots移除指派給當(dāng)前節(jié)點(diǎn)的所有槽,讓當(dāng)前節(jié)點(diǎn)變成一個(gè)沒(méi)有指派任何槽的節(jié)點(diǎn)。
cluster setslot
node
將槽 slot 指派給 node_id 指定的節(jié)點(diǎn),如果槽已經(jīng)指派給另一個(gè)節(jié)點(diǎn),那么先讓另一個(gè)節(jié)點(diǎn)刪除該槽>,然后再進(jìn)行指派。
cluster setslot
migrating
將本節(jié)點(diǎn)的槽 slot 遷移到 node_id 指定的節(jié)點(diǎn)中。
cluster setslot
importing
從 node_id 指定的節(jié)點(diǎn)中導(dǎo)入槽 slot 到本節(jié)點(diǎn)。
cluster setslot <slot> stable取消對(duì)槽 slot 的導(dǎo)入( import)或者遷移( migrate)。鍵
cluster keyslot <key>計(jì)算鍵 key 應(yīng)該被放置在哪個(gè)槽上。
cluster countkeysinslot
返回槽 slot 目前包含的鍵值對(duì)數(shù)量。
cluster getkeysinslot
返回 count 個(gè) slot 槽中的鍵
cluster info命令
cluster nodes
6.增加節(jié)點(diǎn)
添加新的節(jié)點(diǎn)的基本過(guò)程就是添加一個(gè)空的節(jié)點(diǎn)然后移動(dòng)一些數(shù)據(jù)給它,有兩種情況,添加一個(gè)主節(jié)點(diǎn)和添加一個(gè)從節(jié)點(diǎn)(添加從節(jié)點(diǎn)時(shí)需要將這個(gè)新的節(jié)點(diǎn)設(shè)置為集群中某個(gè)節(jié)點(diǎn)的復(fù)制)
添加一個(gè)新的實(shí)例
啟動(dòng)新的7007節(jié)點(diǎn),使用的配置文件和以前的一樣,只要把端口號(hào)改一下即可,過(guò)程如下:
在終端打開一個(gè)新的標(biāo)簽頁(yè).
進(jìn)入redis-cluster 目錄.
復(fù)制并進(jìn)入redis7007文件夾.
和其他節(jié)點(diǎn)一樣,創(chuàng)建redis.conf文件,需要將端口號(hào)改成7007.
最后啟動(dòng)節(jié)點(diǎn) ../redis-server ./redis.conf
如果正常的話,節(jié)點(diǎn)會(huì)正確的啟動(dòng).

1.添加主節(jié)點(diǎn)
./redis-trib.rbadd-node192.168.88.121:7007192.168.88.121:7001
第一個(gè)參數(shù)是新節(jié)點(diǎn)的地址,第二個(gè)參數(shù)是任意一個(gè)已經(jīng)存在的節(jié)點(diǎn)的IP和端口
新節(jié)點(diǎn)現(xiàn)在已經(jīng)連接上了集群, 成為集群的一份子, 并且可以對(duì)客戶端的命令請(qǐng)求進(jìn)行轉(zhuǎn)向了, 但是和其他主節(jié)點(diǎn)相比, 新節(jié)點(diǎn)還有兩點(diǎn)區(qū)別:
新節(jié)點(diǎn)沒(méi)有包含任何數(shù)據(jù), 因?yàn)樗鼪](méi)有包含任何哈希槽.
盡管新節(jié)點(diǎn)沒(méi)有包含任何哈希槽, 但它仍然是一個(gè)主節(jié)點(diǎn), 所以在集群需要將某個(gè)從節(jié)點(diǎn)升級(jí)為新的主節(jié)點(diǎn)時(shí), 這個(gè)新節(jié)點(diǎn)不會(huì)被選中。
接下來(lái), 只要使用 redis-trib 程序, 將集群中的某些哈希桶移動(dòng)到新節(jié)點(diǎn)里面, 新節(jié)點(diǎn)就會(huì)成為真正的主節(jié)點(diǎn)了。
重新分配slot
./redis-trib.rb reshard 192.168.88.121:7001
只需要指定集群中其中一個(gè)節(jié)點(diǎn)的地址, redis-trib 就會(huì)自動(dòng)找到集群中的其他節(jié)點(diǎn)
7007節(jié)點(diǎn)被分類slot,成了真正意義上的主節(jié)點(diǎn)
2.添加從節(jié)點(diǎn)
添加的從節(jié)點(diǎn)被隨機(jī)的配置任意的主節(jié)點(diǎn)
./redis-trib.rb add-node--slave 192.168.88.121:7008 192.168.88.121:7001
將從節(jié)點(diǎn)添加給指定的主節(jié)點(diǎn)
./redis-trib.rb add-node--slave --master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:7006 127.0.0.1:7000
7.刪除節(jié)點(diǎn)
使用del-node命令移除節(jié)點(diǎn)。
./redis-trib.rb del-node 192.168.2.11:7007
第一個(gè)參數(shù):任意集群中現(xiàn)有的地址192.168.88.121:7001
第二個(gè)參數(shù):你想移除的節(jié)點(diǎn)id ab853f5e95f1e32e0ee40543a9687d60fc3bd941 (該id可以在想要移除的節(jié)點(diǎn)nodes.conf文件中找到)
關(guān)閉redis
redis7001/redis-cli -p 7001 shutdown
./redis-cli shutdown
pkill -9 redis-server –關(guān)閉所有的redis服務(wù)
~好了redis的集群操作就介紹到此,