一、為什么要使用redis cluster集群
1.主從復(fù)制不能實(shí)現(xiàn)高可用
2.隨著公司發(fā)展,用戶數(shù)量增多,并發(fā)越來(lái)越多,業(yè)務(wù)需要更高的QPS,而主從復(fù)制中單機(jī)的QPS可能無(wú)法滿足業(yè)務(wù)需求
3.數(shù)據(jù)量的考慮,現(xiàn)有服務(wù)器內(nèi)存不能滿足業(yè)務(wù)數(shù)據(jù)的需要時(shí),單純向服務(wù)器添加內(nèi)存不能達(dá)到要求,此時(shí)需要考慮分布式需求,把數(shù)據(jù)分布到不同服務(wù)器上
4.網(wǎng)絡(luò)流量需求:業(yè)務(wù)的流量已經(jīng)超過(guò)服務(wù)器的網(wǎng)卡的上限值,可以考慮使用分布式來(lái)進(jìn)行分流
5.離線計(jì)算,需要中間環(huán)節(jié)緩沖等別的需求
二、什么數(shù)據(jù)分布式
通俗易懂就是將不同信息根據(jù)規(guī)則,存放在到不同的地方。
我們常見(jiàn)的數(shù)據(jù)分布式有 順序分布、節(jié)點(diǎn)取余分布、一致性哈希分布、
順序分布
比如:1到100個(gè)數(shù)字,要保存在3個(gè)節(jié)點(diǎn)上,按照順序分區(qū),把數(shù)據(jù)平均分配三個(gè)節(jié)點(diǎn)上
1號(hào)到33號(hào)數(shù)據(jù)保存到節(jié)點(diǎn)1上,34號(hào)到66號(hào)數(shù)據(jù)保存到節(jié)點(diǎn)2上,67號(hào)到100號(hào)數(shù)據(jù)保存到節(jié)點(diǎn)3上
image.png
節(jié)點(diǎn)取余分布
比如有100個(gè)數(shù)據(jù),對(duì)每個(gè)數(shù)據(jù)進(jìn)行hash運(yùn)算之后,與節(jié)點(diǎn)數(shù)進(jìn)行取余運(yùn)算,根據(jù)余數(shù)不同保存在不同的節(jié)點(diǎn)上
image.png
致性哈希分區(qū)
一致性哈希原理:
將所有的數(shù)據(jù)當(dāng)做一個(gè)token環(huán),token環(huán)中的數(shù)據(jù)范圍是0到2的32次方。然后為每一個(gè)數(shù)據(jù)節(jié)點(diǎn)分配一個(gè)token范圍值,這個(gè)節(jié)點(diǎn)就負(fù)責(zé)保存這個(gè)范圍內(nèi)的數(shù)據(jù)。
image.png
三、redis cluster的基本架構(gòu)
節(jié)點(diǎn)
Redis Cluster是分布式架構(gòu):即Redis Cluster中有多個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都負(fù)責(zé)進(jìn)行數(shù)據(jù)讀寫(xiě)操作,每個(gè)節(jié)點(diǎn)之間會(huì)進(jìn)行通信。
meet操作
meet操作是節(jié)點(diǎn)之間完成相互通信的基礎(chǔ),meet操作有一定的頻率和規(guī)則
image.png
分配槽
把16384個(gè)槽平均分配給節(jié)點(diǎn)進(jìn)行管理,每個(gè)節(jié)點(diǎn)只能對(duì)自己負(fù)責(zé)的槽進(jìn)行讀寫(xiě)操作。
由于每個(gè)節(jié)點(diǎn)之間都彼此通信,每個(gè)節(jié)點(diǎn)都知道另外節(jié)點(diǎn)負(fù)責(zé)管理的槽范圍
image.png
復(fù)制
保證高可用,每個(gè)主節(jié)點(diǎn)都有一個(gè)從節(jié)點(diǎn),當(dāng)主節(jié)點(diǎn)故障,Cluster會(huì)按照規(guī)則實(shí)現(xiàn)主備的高可用性
restart cluster存放數(shù)據(jù)
1.把16384槽按照節(jié)點(diǎn)數(shù)量進(jìn)行平均分配,由節(jié)點(diǎn)進(jìn)行管理
2.對(duì)每個(gè)key按照CRC16規(guī)則進(jìn)行hash運(yùn)算
3.把hash結(jié)果對(duì)16383進(jìn)行取余
4.把余數(shù)發(fā)送給Redis節(jié)點(diǎn)
5.節(jié)點(diǎn)接收到數(shù)據(jù),驗(yàn)證是否在自己管理的槽編號(hào)的范圍
如果在自己管理的槽編號(hào)范圍內(nèi),則把數(shù)據(jù)保存到數(shù)據(jù)槽中,然后返回執(zhí)行結(jié)果
如果在自己管理的槽編號(hào)范圍外,則會(huì)把數(shù)據(jù)發(fā)送給正確的節(jié)點(diǎn),由正確的節(jié)點(diǎn)來(lái)把數(shù)據(jù)保存在對(duì)應(yīng)的槽中
四、redis cluster部署
準(zhǔn)備環(huán)境:兩臺(tái)centos 7的服務(wù)器
redis1 192.168.1.91(安裝redis-4.0.9)
redis2 192.168.1.92(安裝redis-4.0.9)
1、安裝redis 兩臺(tái)服務(wù)器都執(zhí)行
[root@redis1]$ yum -y install gcc make
[root@redis1]$ tar xzf redis-4.0.9.tar.gz
[root@redis1 ]$ cd redis-4.0.9/
[root@redis1 redis-4.0.9]$ make && make install
2、創(chuàng)建redis節(jié)點(diǎn)
首先在 192.168.1.91 服務(wù)器上 /root/redis-4.0.9 目錄下創(chuàng)建 redis_cluster 目錄;
[root@redis1 redis-4.0.9]$ mkdir redis_cluster
在 redis_cluster 目錄下,創(chuàng)建名為7000、7001、7002的目錄,并將 redis.conf 拷貝到這三個(gè)目錄中
[root@redis1 redis-4.0.9]$ cd redis_cluster/
[root@redis1 redis_cluster]$ mkdir 7001 7002 7003
[root@redis1 redis_cluster]$ cd ..
[root@redis1 redis-4.0.9]$ cp redis.conf redis_cluster/7001/
[root@redis1 redis-4.0.9]$ cp redis.conf redis_cluster/7002/
[root@redis1 redis-4.0.9]$ cp redis.conf redis_cluster/7003/
修改redis_cluster中的三個(gè)配置文件,修改如下內(nèi)容
port 7000 //端口7000,7002,7003
bind 0.0.0.0 //默認(rèn)ip為127.0.0.1 需要改為其他節(jié)點(diǎn)機(jī)器可訪問(wèn)的ip 否則創(chuàng)建集群時(shí)無(wú)法訪問(wèn)對(duì)應(yīng)的端口,無(wú)法創(chuàng)建集群.這里直接0.0.0.0
daemonize yes //redis后臺(tái)運(yùn)行
pidfile /var/run/redis_7001.pid //pidfile文件對(duì)應(yīng)7000,7001,7002
logfile "/var/log/redis7001.log" //日志的存放路徑
cluster-enabled yes //開(kāi)啟集群 把注釋#去掉
cluster-config-file nodes_7001.conf //集群的配置 配置文件首次啟動(dòng)自動(dòng)生成 7001,7002,7003
cluster-node-timeout 15000 //請(qǐng)求超時(shí) 默認(rèn)15秒,可自行設(shè)置
appendonly yes //aof日志開(kāi)啟 有需要就開(kāi)啟,它會(huì)每次寫(xiě)操作都記錄一條日志
3、啟動(dòng)各個(gè)節(jié)點(diǎn)
[root@redis1 redis-4.0.9]$ src/redis-server redis_cluster/7001/redis.conf
[root@redis1 redis-4.0.9]$ src/redis-server redis_cluster/7002/redis.conf
[root@redis1 redis-4.0.9]$ src/redis-server redis_cluster/7003/redis.conf
4、檢查 redis 啟動(dòng)情況
[root@redis1 redis-4.0.9]$ ss -lntp |grep redis
LISTEN 0 128 *:7001 *:* users:(("redis-server",pid=14261,fd=6))
LISTEN 0 128 *:7002 *:* users:(("redis-server",pid=14266,fd=6))
LISTEN 0 128 *:7003 *:* users:(("redis-server",pid=14271,fd=6))
LISTEN 0 128 *:17001 *:* users:(("redis-server",pid=14261,fd=9))
LISTEN 0 128 *:17002 *:* users:(("redis-server",pid=14266,fd=9))
LISTEN 0 128 *:17003 *:* users:(("redis-server",pid=14271,fd=9))
[root@redis1 redis-4.0.9]$ ps aux |grep redis
root 14251 0.0 0.5 147360 9656 ? Ssl 22:46 0:02 src/redis-server 0.0.0.0:7001 [cluster]
root 14256 0.0 0.5 147360 9652 ? Ssl 22:46 0:02 src/redis-server 0.0.0.0:7002 [cluster]
root 14261 0.0 0.5 147360 9652 ? Ssl 22:46 0:02 src/redis-server 0.0.0.0:7003 [cluster]
root 14295 0.0 0.0 112712 964 pts/0 S+ 23:33 0:00 grep --color=auto redis
在另外一臺(tái)一臺(tái)服務(wù)器做出相同的操作,端口為7004、7005、7006
5、創(chuàng)建集群
Redis 官方提供了 redis-trib.rb 這個(gè)工具,就在解壓目錄的 src 目錄中,需要將它復(fù)制到 /usr/local/bin 目錄中,然后就可以直接在命令行中使用了。使用下面這個(gè)命令即可完成安裝。
[root@redis1 redis-4.0.9]$ cp src/redis-trib.rb /usr/local/bin/
在創(chuàng)建集群之前需要下載ruby
[root@redis1 ~]$ yum makecache fast
[root@redis1 ~]$ yum -y install ruby ruby-devel rubygems rpm-build #yum安裝的rubygems的版本是2.0.0
[root@redis1 ~]$ gem sources --remove http://rubygems.org #刪除rubygems系統(tǒng)自帶的源
[root@redis1 ~]$ gem sources -a http://mirrors.aliyun.com/rubygems/ #安裝aliyun的源
[root@redis1 ~]$ gem install redis -v 3.3.5
我試過(guò)了執(zhí)行gem install redis 后面一定要加版本。也只能下3.3.5和之前的版本(但是3.3.4不行,因?yàn)槲铱戳斯俜轿臋n,3.3.4已經(jīng)被遺棄)。后面的版本下了也沒(méi)用。因?yàn)槲覀兿螺d的rubygems是2.0.0版本的。之后版本至少要rubygems2.2.2。
執(zhí)行創(chuàng)建集群命令
[root@redis1 ~]$ redis-trib.rb create --replicas 1 192.168.1.91:7001 192.168.1.91:7002 192.168.1.91:7003 192.168.1.92:7004 192.168.1.92:7005 192.168.1.92:7006
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.1.91:7001
192.168.1.92:7004
192.168.1.91:7002
Adding replica 192.168.1.92:7006 to 192.168.1.91:7001
Adding replica 192.168.1.91:7003 to 192.168.1.92:7004
Adding replica 192.168.1.92:7005 to 192.168.1.91:7002
M: cf11cf78ff2198b3aff78edfbb0238bf8c811cf2 192.168.1.91:7001
slots:0-5460 (5461 slots) master
M: c9d332c7f05e36f956b815e390feab01ba3847e6 192.168.1.91:7002
slots:10923-16383 (5461 slots) master
S: 2fbbc8d39be0efac0004f88506d3944ef444e838 192.168.1.91:7003
replicates ca5f1252a7e34c9d9402a57aa5bfba3a85c26c98
M: ca5f1252a7e34c9d9402a57aa5bfba3a85c26c98 192.168.1.92:7004
slots:5461-10922 (5462 slots) master
S: 6af8a54987cb3e1960accb9e76cf2430df38ad4f 192.168.1.92:7005
replicates c9d332c7f05e36f956b815e390feab01ba3847e6
S: 1eba53a0b423841f250c489ee54de63c1c7336a3 192.168.1.92:7006
replicates cf11cf78ff2198b3aff78edfbb0238bf8c811cf2
Can I set the above configuration? (type 'yes' to accept):
輸入yes
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.1.91:7001)
M: cf11cf78ff2198b3aff78edfbb0238bf8c811cf2 192.168.1.91:7001
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: 1eba53a0b423841f250c489ee54de63c1c7336a3 192.168.1.92:7006
slots: (0 slots) slave
replicates cf11cf78ff2198b3aff78edfbb0238bf8c811cf2
S: 2fbbc8d39be0efac0004f88506d3944ef444e838 192.168.1.91:7003
slots: (0 slots) slave
replicates ca5f1252a7e34c9d9402a57aa5bfba3a85c26c98
S: 6af8a54987cb3e1960accb9e76cf2430df38ad4f 192.168.1.92:7005
slots: (0 slots) slave
replicates c9d332c7f05e36f956b815e390feab01ba3847e6
M: ca5f1252a7e34c9d9402a57aa5bfba3a85c26c98 192.168.1.92:7004
slots:5461-10922 (5462 slots) master
1 additional replica(s)
M: c9d332c7f05e36f956b815e390feab01ba3847e6 192.168.1.91:7002
slots:10923-16383 (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
redis-trib.rb其實(shí)就是一個(gè)redis自帶的腳本,它可以幫你自動(dòng)挑選master和對(duì)應(yīng)的slave,還會(huì)自動(dòng)幫你分配槽位。(隨機(jī))




