沈陽(yáng)微信網(wǎng)站建設(shè)上海做推廣的引流公司
一、哨兵模式
?
在 redis3.0之前,redis使用的哨兵架構(gòu),它借助 sentinel 工具來(lái)監(jiān)控 master 節(jié)點(diǎn)的狀態(tài);如果 master 節(jié)點(diǎn)異常,則會(huì)做主從切換,將一臺(tái) slave 作為 master。
?
哨兵模式的缺點(diǎn):
?
(1)當(dāng)master掛掉的時(shí)候,sentinel 會(huì)選舉出來(lái)一個(gè) master,選舉的時(shí)候是沒(méi)有辦法去訪問(wèn)Redis的,會(huì)存在訪問(wèn)瞬斷的情況;若是在電商網(wǎng)站大促的時(shí)候master給掛掉了,幾秒鐘損失好多訂單數(shù)據(jù);
?
(2)哨兵模式,對(duì)外只有master節(jié)點(diǎn)可以寫,slave節(jié)點(diǎn)只能用于讀。盡管Redis單節(jié)點(diǎn)最多支持10W的QPS,但是在電商大促的時(shí)候,寫數(shù)據(jù)的壓力全部在master上。
?
(3)Redis的單節(jié)點(diǎn)內(nèi)存不能設(shè)置過(guò)大,若數(shù)據(jù)過(guò)大在主從同步將會(huì)很慢;在節(jié)點(diǎn)啟動(dòng)的時(shí)候,時(shí)間特別長(zhǎng);(從節(jié)點(diǎn)上有主節(jié)點(diǎn)的所有數(shù)據(jù))
?
二、Redis集群
1、Redis集群的介紹
?
?
? Redis集群是一個(gè)由多個(gè)主從節(jié)點(diǎn)群組成的分布式服務(wù)集群,它具有復(fù)制、高可用和分片特性。Redis集群不需要sentinel哨兵也能完成節(jié)點(diǎn)移除和故障轉(zhuǎn)移的功能。需要將每個(gè)節(jié)點(diǎn)設(shè)置成集群模式,這種集群模式?jīng)]有中心節(jié)點(diǎn),可水平擴(kuò)展,據(jù)官方文檔稱可以線性擴(kuò)展到上萬(wàn)個(gè)節(jié)點(diǎn)(官方推薦不超過(guò)1000個(gè)節(jié)點(diǎn))。redis集群的性能和高可用性均優(yōu)于之前版本的哨兵模式,且集群配置非常簡(jiǎn)單。
?
2、Redis集群的優(yōu)點(diǎn):
(1)Redis集群有多個(gè)master,可以減小訪問(wèn)瞬斷問(wèn)題的影響;
?
若集群中有一個(gè)master掛了,正好需要向這個(gè)master寫數(shù)據(jù),這個(gè)操作需要等待一下;但是向其他master節(jié)點(diǎn)寫數(shù)據(jù)是不受影響的。
?
(2)Redis集群有多個(gè)master,可以提供更高的并發(fā)量;
?
(3)Redis集群可以分片存儲(chǔ),這樣就可以存儲(chǔ)更多的數(shù)據(jù);
?
3、Redis集群的搭建
Redis的集群搭建最少需要3個(gè)master節(jié)點(diǎn),我們這里搭建3個(gè)master,每個(gè)下面掛一個(gè)slave節(jié)點(diǎn),總共6個(gè)Redis節(jié)點(diǎn);(3臺(tái)機(jī)器,每臺(tái)機(jī)器一主一從)
?
第1臺(tái)機(jī)器: 192.168.1.1 8001端口 8002端口
?
第2臺(tái)機(jī)器: 192.168.1.2 8001端口 8002端口
?
第3臺(tái)機(jī)器: 192.168.1.3 8001端口 8002端口
?
第一步:創(chuàng)建文件夾
?
mkdir -p /usr1/redis/redis-cluster/8001 /usr1/redis/redis-cluster/8002
第二步:將redis安裝目錄下的 redis.conf 文件分別拷貝到8001目錄下
?
cp /usr1/redis-5.0.3/redis.conf /usr1/redis/redis-cluster/8001
第三步:修改redis.conf文件以下內(nèi)容
?
復(fù)制代碼
port 8001
daemonize yes
pidfile "/var/run/redis_8001.pid"
?
#指定數(shù)據(jù)文件存放位置,必須要指定不同的目錄位置,不然會(huì)丟失數(shù)據(jù)
dir /usr1/redis/redis-cluster/8001/
?
#啟動(dòng)集群模式
cluster-enabled yes
?
#集群節(jié)點(diǎn)信息文件,這里800x最好和port對(duì)應(yīng)上
cluster-config-file nodes-8001.conf
?
# 節(jié)點(diǎn)離線的超時(shí)時(shí)間
cluster-node-timeout 5000
?
#去掉bind綁定訪問(wèn)ip信息
#bind 127.0.0.1
?
#關(guān)閉保護(hù)模式
protected-mode no?
?
#啟動(dòng)AOF文件
appendonly yes
?
#如果要設(shè)置密碼需要增加如下配置:
#設(shè)置redis訪問(wèn)密碼
requirepass redis-pw
?
#設(shè)置集群節(jié)點(diǎn)間訪問(wèn)密碼,跟上面一致
masterauth redis-pw
復(fù)制代碼
第四步,把上面修改好的配置文件拷貝到8002文件夾下,并將8001修改為8002:
?
復(fù)制代碼
cp /usr1/redis/redis-cluster/8001/redis.conf /usr1/redis/redis-cluster/8002
cd /usr1/redis/redis-cluster/8002/
vim redis.conf
?
#批量修改字符串
:%s/8001/8002/g
復(fù)制代碼
第五步,將本機(jī)(192.168.1.1)機(jī)器上的文件拷貝到另外兩臺(tái)機(jī)器上
?
scp /usr1/redis/redis-cluster/8001/redis.conf root@192.168.1.2:/usr1/redis/redis-cluster/8001/
scp /usr1/redis/redis-cluster/8002/redis.conf root@192.168.1.2:/usr1/redis/redis-cluster/8002/
?
scp /usr1/redis/redis-cluster/8001/redis.conf root@192.168.1.3:/usr1/redis/redis-cluster/8001/
scp /usr1/redis/redis-cluster/8002/redis.conf root@192.168.1.3:/usr1/redis/redis-cluster/8002/
第六步,分別啟動(dòng)這6個(gè)redis實(shí)例,然后檢查是否啟動(dòng)成功
?
/usr1/redis/redis-5.0.3/src/redis-server /usr1/redis/redis-cluster/8001/redis.conf?
/usr1/redis/redis-5.0.3/src/redis-server /usr1/redis/redis-cluster/8002/redis.conf?
ps -ef | grep redis
?
?
?第七步,使用 redis-cli 創(chuàng)建整個(gè) redis 集群(redis5.0版本之前使用的ruby腳本 redis-trib.rb)
?
運(yùn)行以上命令,完成搭建
?
/usr1/redis/redis-5.0.3/src/redis-cli -a redis-pw --cluster create --cluster-replicas 1 192.168.1.1:8001 192.168.1.1:8002 192.168.1.2:8001 192.168.1.2:8002 192.168.1.3:8001 192.168.1.3:8002
?
?
說(shuō)明:?
?
-a :密碼;
?
--cluster-replicas 1:表示1個(gè)master下掛1個(gè)slave; --cluster-replicas 2:表示1個(gè)master下掛2個(gè)slave。
?
擴(kuò)展:
?
查看幫助命令: src/redis‐cli --cluster help?
?
復(fù)制代碼
create:創(chuàng)建一個(gè)集群環(huán)境host1:port1 ... hostN:portN
call:可以執(zhí)行redis命令
add-node:將一個(gè)節(jié)點(diǎn)添加到集群里,第一個(gè)參數(shù)為新節(jié)點(diǎn)的ip:port,第二個(gè)參數(shù)為集群中任意一個(gè)已經(jīng)存在的節(jié)點(diǎn)的ip:port
del-node:移除一個(gè)節(jié)點(diǎn)
reshard:重新分片
check:檢查集群狀態(tài)
復(fù)制代碼
?第八步,驗(yàn)證集群
?
(1)連接任意一個(gè)客戶端
?
/usr1/redis/redis-5.0.3/src/redis-cli -a redis-pw -c -h 192.168.1.1 -p 8001
說(shuō)明:‐a表示服務(wù)端密碼;‐c表示集群模式;-h指定ip地址;-p表示端口號(hào)
?
(2)查看集群的信息: cluster info? ?
?
?
?
(3) 查看節(jié)點(diǎn)列表: cluster nodes slave 對(duì)應(yīng)的 master 從上面也可以看到;
?
從上面可以看到 slave掛在哪個(gè) master 下面;
?
?
?
?在 /usr1/redis/redis-cluster/8001/nodes-8001.conf 文件中存儲(chǔ)了節(jié)點(diǎn)信息;
?
(4)進(jìn)行數(shù)據(jù)操作驗(yàn)證;
?
(5)關(guān)閉集群則需要逐個(gè)進(jìn)行關(guān)閉,使用命令:
?
/usr/local/redis‐5.0.3/src/redis‐cli ‐a redis-pw ‐c ‐h 192.168.1.1 ‐p 8001 shutdown
/usr/local/redis‐5.0.3/src/redis‐cli ‐a redis-pw ‐c ‐h 192.168.1.1 ‐p 8002 shutdown
......
注意:在創(chuàng)建集群的時(shí)候,需要把所有節(jié)點(diǎn)機(jī)器上的防火關(guān)閉,保證 Redis的服務(wù)端口和集群節(jié)點(diǎn)通信的 gossip 端口能通;
?
systemctl stop firewalld # 臨時(shí)關(guān)閉防火墻
?
systemctl disable firewalld # 禁止開機(jī)啟動(dòng)
?
?4、Redis集群原理分析
? Redis Cluster 將所有數(shù)據(jù)劃分為 16384 個(gè) slots(槽位),每個(gè)節(jié)點(diǎn)負(fù)責(zé)其中一部分槽位。槽位的信息存儲(chǔ)于每個(gè)節(jié)點(diǎn)中。只有master節(jié)點(diǎn)會(huì)被分配槽位,slave節(jié)點(diǎn)不會(huì)分配槽位。
?
當(dāng)Redis Cluster 的客戶端來(lái)連接集群時(shí),它也會(huì)得到一份集群的槽位配置信息,并將其緩存在客戶端本地。這樣當(dāng)客戶端要查找某個(gè) key 時(shí),可以直接定位到目標(biāo)節(jié)點(diǎn)。同時(shí)因?yàn)椴畚坏男畔⒖赡軙?huì)存在客戶端與服務(wù)器不一致的情況,還需要糾正機(jī)制來(lái)實(shí)現(xiàn)槽位信息的校驗(yàn)調(diào)整。
?
槽位定位算法
?
?
?
?Cluster 默認(rèn)會(huì)對(duì) key 值使用 crc16 算法進(jìn)行 hash 得到一個(gè)整數(shù)值,然后用這個(gè)整數(shù)值對(duì) 16384 進(jìn)行取模來(lái)得到具體槽位。
?
HASH_SLOT = CRC16(key) % 16384?
?
跳轉(zhuǎn)重定位
?
? 當(dāng)客戶端向一個(gè)節(jié)點(diǎn)發(fā)出了指令,首先當(dāng)前節(jié)點(diǎn)會(huì)計(jì)算指令的 key 得到槽位信息,判斷計(jì)算的槽位是否歸當(dāng)前節(jié)點(diǎn)所管理;若槽位不歸當(dāng)前節(jié)點(diǎn)管理,這時(shí)它會(huì)向客戶端發(fā)送一個(gè)特殊的跳轉(zhuǎn)指令攜帶目標(biāo)操作的節(jié)點(diǎn)地址,告訴客戶端去連這個(gè)節(jié)點(diǎn)去獲取數(shù)據(jù)??蛻舳耸盏街噶詈蟪颂D(zhuǎn)到正確的節(jié)點(diǎn)上去操作,還會(huì)同步更新糾正本地的槽位映射表緩存,后續(xù)所有 key 將使用新的槽位映射表。
?
?
?
?Redis集群節(jié)點(diǎn)之間的通信機(jī)制
?
維護(hù)集群的元數(shù)據(jù)有集中式和 gossip兩種方式,Redis 的集群節(jié)點(diǎn)之間的通信采取 gossip 協(xié)議進(jìn)行通信
?
(1)集中式:
?
優(yōu)點(diǎn):元數(shù)據(jù)的更新和讀取,時(shí)效性非常好,一旦元數(shù)據(jù)出現(xiàn)變更立即就會(huì)更新到集中式的存儲(chǔ)中,其他節(jié)點(diǎn)讀取的時(shí)候立即就可以立即感知到;
?
缺點(diǎn):所有的元數(shù)據(jù)的更新壓力全部集中在一個(gè)地方,可能導(dǎo)致元數(shù)據(jù)的存儲(chǔ)壓力。zookeeper使用該方式
?
(2)gossip:
?
gossip協(xié)議包含多種消息,包括ping,pong,meet,fail等等。。
?
優(yōu)點(diǎn):元數(shù)據(jù)的更新比較分散,不是集中在一個(gè)地方,更新請(qǐng)求會(huì)陸陸續(xù)續(xù),打到所有節(jié)點(diǎn)上去更新,有一定的延時(shí),降低了壓力;
?
缺點(diǎn):元數(shù)據(jù)更新有延時(shí)可能導(dǎo)致集群的一些操作會(huì)有一些滯后。
?
每個(gè)節(jié)點(diǎn)都有一個(gè)專門用于節(jié)點(diǎn)間通信的端口,就是自己提供服務(wù)的端口號(hào)+10000,比如7001,那么用于節(jié)點(diǎn)間通信的就是17001端口。 每個(gè)節(jié)點(diǎn)每隔一段時(shí)間都會(huì)往另外幾個(gè)節(jié)點(diǎn)發(fā)送ping消息,同時(shí)其他幾點(diǎn)接收到ping消息之后返回pong消息。
?
網(wǎng)絡(luò)抖動(dòng)
?
網(wǎng)絡(luò)抖動(dòng)就是非常常見的一種現(xiàn)象,突然之間部分連接變得不可訪問(wèn),然后很快又恢復(fù)正常。
為解決這種問(wèn)題,Redis Cluster 提供了一種選項(xiàng) cluster--node--timeout ,表示當(dāng)某個(gè)節(jié)點(diǎn)失聯(lián)的時(shí)間超過(guò)了配置的 timeout時(shí),才可