真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

干貨:一文詳解Redis集群原理核心內(nèi)容-創(chuàng)新互聯(lián)

集群原理

一個(gè)系統(tǒng)建立集群主要需要解決兩個(gè)問題:數(shù)據(jù)同步問題和集群容錯(cuò)問題。

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括平山網(wǎng)站建設(shè)、平山網(wǎng)站制作、平山網(wǎng)頁制作以及平山網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,平山網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到平山省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

Naive方案

一個(gè)簡(jiǎn)單粗暴的方案是部署多臺(tái)一模一樣的Redis服務(wù),再用負(fù)載均衡來分?jǐn)倝毫σ约氨O(jiān)控服務(wù)狀態(tài)。這種方案的優(yōu)勢(shì)在于容錯(cuò)簡(jiǎn)單,只要有一臺(tái)存活,整個(gè)集群就仍然可用。但是它的問題在于保證這些Redis服務(wù)的數(shù)據(jù)一致時(shí),會(huì)導(dǎo)致大量數(shù)據(jù)同步操作,反而影響性能和穩(wěn)定性。

Redis集群方案

Redis集群方案基于分而治之的思想。Redis中數(shù)據(jù)都是以Key-Value形式存儲(chǔ)的,而不同Key的數(shù)據(jù)之間是相互獨(dú)立的。因此可以將Key按照某種規(guī)則劃分成多個(gè)分區(qū),將不同分區(qū)的數(shù)據(jù)存放在不同的節(jié)點(diǎn)上。這個(gè)方案類似數(shù)據(jù)結(jié)構(gòu)中哈希表的結(jié)構(gòu)。在Redis集群的實(shí)現(xiàn)中,使用哈希算法(公式是CRC16(Key) mod 16383)將Key映射到0~16383范圍的整數(shù)。這樣每個(gè)整數(shù)對(duì)應(yīng)存儲(chǔ)了若干個(gè)Key-Value數(shù)據(jù),這樣一個(gè)整數(shù)對(duì)應(yīng)的抽象存儲(chǔ)稱為一個(gè)槽(slot)。每個(gè)Redis Cluster的節(jié)點(diǎn)——準(zhǔn)確講是master節(jié)點(diǎn)——負(fù)責(zé)一定范圍的槽,所有節(jié)點(diǎn)組成的集群覆蓋了0~16383整個(gè)范圍的槽。

據(jù)說任何計(jì)算機(jī)問題都可以通過增加一個(gè)中間層來解決。槽的概念也是這么一層。它介于數(shù)據(jù)和節(jié)點(diǎn)之間,簡(jiǎn)化了擴(kuò)容和收縮操作的難度。數(shù)據(jù)和槽的映射關(guān)系由固定算法完成,不需要維護(hù),節(jié)點(diǎn)只需維護(hù)自身和槽的映射關(guān)系。

干貨:一文詳解Redis集群原理核心內(nèi)容

Slave

上面的方案只是解決了性能擴(kuò)展的問題,集群的故障容錯(cuò)能力并沒有提升。提高容錯(cuò)能力的方法一般為使用某種備份/冗余手段。負(fù)責(zé)一定數(shù)量的槽的節(jié)點(diǎn)被稱為master節(jié)點(diǎn)。為了增加集群穩(wěn)定性,每個(gè)master節(jié)點(diǎn)可以配置若干個(gè)備份節(jié)點(diǎn)——稱為slave節(jié)點(diǎn)。Slave節(jié)點(diǎn)一般作為冷備份保存master節(jié)點(diǎn)的數(shù)據(jù),在master節(jié)點(diǎn)宕機(jī)時(shí)替換master節(jié)點(diǎn)。在一些數(shù)據(jù)訪問壓力比較大的情況下,slave節(jié)點(diǎn)也可以提供讀取數(shù)據(jù)的功能,不過slave節(jié)點(diǎn)的數(shù)據(jù)實(shí)時(shí)性會(huì)略差一下。而寫數(shù)據(jù)的操作則只能通過master節(jié)點(diǎn)進(jìn)行。

請(qǐng)求重定向

當(dāng)Redis節(jié)點(diǎn)接收到對(duì)某個(gè)key的命令時(shí),如果這個(gè)key對(duì)應(yīng)的槽不在自己的負(fù)責(zé)范圍內(nèi),則返回MOVED重定向錯(cuò)誤,通知客戶端到正確的節(jié)點(diǎn)去訪問數(shù)據(jù)。

如果頻繁出現(xiàn)重定向錯(cuò)誤,勢(shì)必會(huì)影響訪問的性能。由于從key映射到槽的算法是固定公開的,客戶端可以在內(nèi)部維護(hù)槽到節(jié)點(diǎn)的映射關(guān)系,訪問數(shù)據(jù)時(shí)可以自己通過key計(jì)算出槽,然后找到正確的節(jié)點(diǎn),減少重定向錯(cuò)誤。目前大部分開發(fā)語言的Redis客戶端都會(huì)實(shí)現(xiàn)這個(gè)策略。這個(gè)地址https://redis.io/clients可以查看主流語言的Redis客戶端。

節(jié)點(diǎn)通信

盡管不同節(jié)點(diǎn)存儲(chǔ)的數(shù)據(jù)相互獨(dú)立,這些節(jié)點(diǎn)仍然需要相互通信以同步節(jié)點(diǎn)狀態(tài)信息。Redis集群采用P2P的Gossip協(xié)議,節(jié)點(diǎn)之間不斷地通信交換信息,最終所有節(jié)點(diǎn)的狀態(tài)都會(huì)達(dá)成一致。常用的Gossip消息有下面幾種:

  • ping消息:每個(gè)節(jié)點(diǎn)不斷地向其他節(jié)點(diǎn)發(fā)起ping消息,用于檢測(cè)節(jié)點(diǎn)是否在線和交換節(jié)點(diǎn)狀態(tài)信息。
  • pong消息:收到ping、meet消息時(shí)的響應(yīng)消息。
  • meet消息:新節(jié)點(diǎn)加入消息。
  • fail消息:節(jié)點(diǎn)下線消息。
  • forget消息:忘記節(jié)點(diǎn)消息,使一個(gè)節(jié)點(diǎn)下線。這個(gè)命令必須在60秒內(nèi)在所有節(jié)點(diǎn)執(zhí)行,否則超過60秒后該節(jié)點(diǎn)重新參與消息交換。實(shí)踐中不建議直接使用forget命令來操作節(jié)點(diǎn)下線。

節(jié)點(diǎn)下線

當(dāng)某個(gè)節(jié)點(diǎn)出現(xiàn)問題時(shí),需要一定的傳播時(shí)間讓多數(shù)master節(jié)點(diǎn)認(rèn)為該節(jié)點(diǎn)確實(shí)不可用,才能標(biāo)記標(biāo)記該節(jié)點(diǎn)真正下線。Redis集群的節(jié)點(diǎn)下線包括兩個(gè)環(huán)節(jié):主觀下線(pfail)和客觀下線(fail)。

  • 主觀下線:當(dāng)節(jié)點(diǎn)A在cluster-node-timeout時(shí)間內(nèi)和節(jié)點(diǎn)B通信(ping-pong消息)一直失敗,則節(jié)點(diǎn)A認(rèn)為節(jié)點(diǎn)B不可用,標(biāo)記為主觀下線,并將狀態(tài)消息傳播給其他節(jié)點(diǎn)。
  • 客觀下線:當(dāng)一個(gè)節(jié)點(diǎn)被集群內(nèi)多數(shù)master節(jié)點(diǎn)標(biāo)記為主觀下線后,則觸發(fā)客觀下線流程,標(biāo)記該節(jié)點(diǎn)真正下線。

故障恢復(fù)

一個(gè)持有槽的master節(jié)點(diǎn)客觀下線后,集群會(huì)從slave節(jié)點(diǎn)中選出一個(gè)提升為master節(jié)點(diǎn)來替換它。Redis集群使用選舉-投票的算法來挑選slave節(jié)點(diǎn)。一個(gè)slave節(jié)點(diǎn)必須獲得包括故障的master節(jié)點(diǎn)在內(nèi)的多數(shù)master節(jié)點(diǎn)的投票后才能被提升為master節(jié)點(diǎn)。假設(shè)集群規(guī)模為3主3從,則必須至少有2個(gè)主節(jié)點(diǎn)存活才能執(zhí)行故障恢復(fù)。如果部署時(shí)將2個(gè)主節(jié)點(diǎn)部署到同一臺(tái)服務(wù)器上,則該服務(wù)器不幸宕機(jī)后集群無法執(zhí)行故障恢復(fù)。

默認(rèn)情況下,Redis集群如果有master節(jié)點(diǎn)不可用,即有一些槽沒有負(fù)責(zé)的節(jié)點(diǎn),則整個(gè)集群不可用。也就是說當(dāng)一個(gè)master節(jié)點(diǎn)故障,到故障恢復(fù)的這段時(shí)間,整個(gè)集群都處于不可用的狀態(tài)。這對(duì)于一些業(yè)務(wù)來說是不可忍受的??梢?strong>在配置中將cluster-require-full-coverage配置為no,那么master節(jié)點(diǎn)故障時(shí)只會(huì)影響訪問它負(fù)責(zé)的相關(guān)槽的數(shù)據(jù),不影響對(duì)其他節(jié)點(diǎn)的訪問。

搭建集群

啟動(dòng)新節(jié)點(diǎn)

修改Redis配置文件以啟動(dòng)集群模式:

# 開啟集群模式
cluster-enabled yes
# 節(jié)點(diǎn)超時(shí)時(shí)間,單位毫秒
cluster-node-timeout 15000
# 集群節(jié)點(diǎn)信息文件
cluster-config-file "nodes-6379.conf"

然后啟動(dòng)新節(jié)點(diǎn)。

發(fā)送meet消息將節(jié)點(diǎn)組成集群

使用客戶端發(fā)起命令cluster <ip> <port>,節(jié)點(diǎn)會(huì)發(fā)送meet消息將指定IP和端口的新節(jié)點(diǎn)加入集群。

干貨:一文詳解Redis集群原理核心內(nèi)容

分配槽

上一步執(zhí)行完后我們得到的是一個(gè)還沒有負(fù)責(zé)任何槽的“空”集群。為了使集群可用,我們需要將16384個(gè)槽都分配到master節(jié)點(diǎn)數(shù)。

在客戶端執(zhí)行cluster add addslots {<a>...<b>}命令,將<a>~<b>范圍的槽都分配給當(dāng)前客戶端所連接的節(jié)點(diǎn)。將所有的槽都分配給master節(jié)點(diǎn)后,執(zhí)行cluster nodes命令,查看各個(gè)節(jié)點(diǎn)負(fù)責(zé)的槽,以及節(jié)點(diǎn)的ID。

接下來還需要分配slave節(jié)點(diǎn)。使用客戶端連接待分配的slave節(jié)點(diǎn),執(zhí)行cluster replicate <nodeId>命令,將該節(jié)點(diǎn)分配為<nodeId>指定的master節(jié)點(diǎn)的備份。

使用命令直接創(chuàng)建集群

在Redis 5版本中redis-cli客戶端新增了集群操作命令。

如下所示,直接使用命令創(chuàng)建一個(gè)3主3從的集群:

redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1

如果你用的是舊版本的Redis,可以使用官方提供的redis-trib.rb腳本來創(chuàng)建集群:

./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

集群伸縮

擴(kuò)容

擴(kuò)容操作與創(chuàng)建集群操作類似,不同的在于最后一步是將槽從已有的節(jié)點(diǎn)遷移到新節(jié)點(diǎn)。

  1. 啟動(dòng)新節(jié)點(diǎn):同創(chuàng)建集群。
  2. 將新節(jié)點(diǎn)加入到集群:使用redis-cli --cluster add-node命令將新節(jié)點(diǎn)加入集群(內(nèi)部使用meet消息實(shí)現(xiàn))。
  3. 遷移槽和數(shù)據(jù):添加新節(jié)點(diǎn)后,需要將一些槽和數(shù)據(jù)從舊節(jié)點(diǎn)遷移到新節(jié)點(diǎn)。使用命令redis-cli --cluster reshard進(jìn)行槽遷移操作。

收縮

為了安全刪除節(jié)點(diǎn),Redis集群只能下線沒有負(fù)責(zé)槽的節(jié)點(diǎn)。因此如果要下線有負(fù)責(zé)槽的master節(jié)點(diǎn),則需要先將它負(fù)責(zé)的槽遷移到其他節(jié)點(diǎn)。

  1. 遷移槽。使用命令redis-cli --cluster reshard將待刪除節(jié)點(diǎn)的槽都遷移到其他節(jié)點(diǎn)。
  2. 忘記節(jié)點(diǎn)。使用命令redis-cli --cluster del-node刪除節(jié)點(diǎn)(內(nèi)部使用forget消息實(shí)現(xiàn))。

集群配置工具

如果你的redis-cli版本低于5,那么可以使用redis-trib.rb腳本來完成上面的命令。點(diǎn)擊這里查看redis-cliredis-trib.rb操作集群的命令。

持久化

Redis有RDB和AOF兩種持久化策略。

一個(gè)RDB持久化的坑

RDB持久化神坑:

  • 即使設(shè)置了save ""試圖關(guān)閉RDB,然而RDB持久化仍然有可能會(huì)觸發(fā)。
  • 從節(jié)點(diǎn)全量復(fù)制(比如新增從節(jié)點(diǎn)時(shí)),主節(jié)點(diǎn)觸發(fā)RDB持久化產(chǎn)生RDB文件。然后發(fā)送RDB文件給從節(jié)點(diǎn)。最后該從節(jié)點(diǎn)和對(duì)應(yīng)的主節(jié)點(diǎn)都會(huì)有RDB文件。
  • 執(zhí)行shutdown時(shí),如果沒有開啟AOF,也會(huì)觸發(fā)RDB持久化。
  • 不管save如何設(shè)置,只要RDB文件存在,redis啟動(dòng)時(shí)就會(huì)去加載該文件。

后果:

  • 如果關(guān)閉了RDB持久化(以及AOF持久化),那么當(dāng)Redis重啟時(shí),則會(huì)加載上一次從節(jié)點(diǎn)全量復(fù)制或者執(zhí)行shutdown時(shí)保存的RDB文件。而這個(gè)RDB文件很可能是一份過時(shí)已久的數(shù)據(jù)。
  • Cluster模式下,Redis重啟并從RDB文件恢復(fù)數(shù)據(jù)后,如果沒有讀取到cluster-config-file中nodes的配置,則標(biāo)記自己為單獨(dú)的master并占用從RDB中恢復(fù)的數(shù)據(jù)的Key對(duì)應(yīng)的槽,導(dǎo)致此節(jié)點(diǎn)無法再加入其它集群。

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開啟,新人活動(dòng)云服務(wù)器買多久送多久。


名稱欄目:干貨:一文詳解Redis集群原理核心內(nèi)容-創(chuàng)新互聯(lián)
當(dāng)前網(wǎng)址:http://weahome.cn/article/dcighd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部