前言
因為之前線上redis集群主從切換荧缘,client端未感知积锅,導(dǎo)致往從庫寫數(shù)據(jù)報錯,所以學(xué)習(xí)并整理了redis集群相關(guān)知識點剩胁。
主從復(fù)制
主從復(fù)制,是只從一臺redis服務(wù)器的數(shù)據(jù)祥国,復(fù)制到其他的一臺或者多臺redis服務(wù)器上昵观。
前者為主節(jié)點(master),后者為從節(jié)點(slave)舌稀。
數(shù)據(jù)的復(fù)制只能從主節(jié)點到從節(jié)點啊犬。
主從復(fù)制主要起到以下幾個作用:
- 數(shù)據(jù)冗余:實現(xiàn)了數(shù)據(jù)的熱備份
- 故障恢復(fù):當(dāng)主節(jié)點出現(xiàn)問題時,可以由從節(jié)點提供服務(wù)壁查,實現(xiàn)快速恢復(fù)觉至。
- 負(fù)載均衡:主節(jié)點提供寫服務(wù),從節(jié)點提供讀服務(wù)睡腿,從而達到負(fù)載均衡的作用语御,常用于讀多寫少的功能,能有效提高服務(wù)器的并發(fā)量席怪。
- 高可用基礎(chǔ):作為哨兵和集群的基礎(chǔ)应闯,為redis的高可用提供基礎(chǔ)。
如下圖何恶,即為主從復(fù)制的整個過程:
主從復(fù)制的注意點:
- 1.延遲與不一致:repl-disable-tcp-nodelay no/yes ,當(dāng)配置為yes時嚼黔,TCP會對包進行合并從而減少帶寬并降低頻率细层,從節(jié)點數(shù)據(jù)延遲增加,一致性變差唬涧。
- 2.數(shù)據(jù)過期問題:在redis 3.2之前疫赎,從節(jié)點過期數(shù)據(jù)需要主節(jié)點來進行刪除,當(dāng)處于惰性刪除時碎节,從節(jié)點會獲取到已經(jīng)過期的數(shù)據(jù)捧搞,將redis升級到3.2之后即可解決。
- 3.故障轉(zhuǎn)移:由于沒有哨兵等機制,主從節(jié)點如果出現(xiàn)問題而發(fā)生更改時胎撇,需要修改程序或者另外寫程序進行自動切換介粘。
- 4.因為主從復(fù)制需要從節(jié)點發(fā)送指令到master,如果從節(jié)點過多晚树,會導(dǎo)致主節(jié)點繁忙從而影響正常業(yè)務(wù)姻采。
哨兵模式
在主從復(fù)制的基礎(chǔ)上,引入了哨兵模式爵憎,提供了高可用解決方案慨亲,可以在沒有人工干預(yù)的情況下實現(xiàn)故障恢復(fù)能力。
哨兵是一個獨立的進程宝鼓,監(jiān)控各個節(jié)點的監(jiān)控狀態(tài)刑棵。
客戶端通過連接sentinel來獲取對應(yīng)redis的主從節(jié)點。
哨兵模式主要起到以下幾個作用:
- 1.監(jiān)控:哨兵會不斷檢查主節(jié)點和從節(jié)點是否運作正常愚铡。
- 2.自動故障轉(zhuǎn)移:當(dāng)主節(jié)點無法正常工作時蛉签,哨兵會開始自動故障轉(zhuǎn)移操作,將從節(jié)點選舉為主節(jié)點茂附,并讓其他從節(jié)點改為復(fù)制新的主節(jié)點正蛙。
- 3.配置提供者:客戶端初始化時,通過連接哨兵來獲取當(dāng)前redis服務(wù)的主節(jié)點地址营曼。
- 4.通知:哨兵可以將各節(jié)點的狀態(tài)發(fā)送給客戶端乒验。
擴展:我們公司通過對redis的擴展,一組sentinel里面連接了多個master蒂阱,對key通過一致性hash來獲取對應(yīng)的分片锻全,從而實現(xiàn)負(fù)載均衡。
sentinel常用配置:
- sentinel down-after-milliseconds <master-name> <milliseconds>
指定主節(jié)點應(yīng)答哨兵sentinel的最大時間間隔录煤,超過這個時間鳄厌,哨兵主觀上認(rèn)為主節(jié)點下線(即主觀下線
),默認(rèn)30秒 - sentinel monitor <master-name> <ip> <redis-port> <quorum>
哨兵sentinel監(jiān)控的redis主節(jié)點妈踊,其中quorum
指指定個數(shù)的sentinel認(rèn)為master不可達了嚎,則認(rèn)為主節(jié)點客觀下線
。 - sentinel parallel-syncs <master-name> <numslaves>
指定了在發(fā)生failover主備切換時廊营,最多可以有多少個slave同時對新的master進行同步歪泳。這個數(shù)字越小,完成failover所需的時間就越長露筒;反之呐伞,但是如果這個數(shù)字越大,就意味著越多的slave因為replication而不可用慎式×媲猓可以通過將這個值設(shè)為1趟径,來保證每次只有一個slave,處于不能處理命令請求的狀態(tài)癣防。 - sentinel known-sentinel
指定主節(jié)點所連接的sentinel節(jié)點信息
sentinel常見命令:
- sentinel is-master-down-by-addr
當(dāng)主節(jié)點主觀下線
時蜗巧,向其他sentinel節(jié)點詢問對該節(jié)點的狀態(tài)判斷,如果超過quorum
個數(shù)的節(jié)點判定不可達劣砍,則判斷該主節(jié)點為客觀下線
- SENTINEL masters / SENTINEL master <master_name>/SENTINEL slaves <master_name>
顯示所有主節(jié)點 / 顯示指定主節(jié)點 / 顯示主節(jié)點的所有從節(jié)點狀態(tài) - SENTINEL get-master-addr-by-name <master_name>
返回主節(jié)點的IP和端口號(如果在進行failover
或者已經(jīng)完成惧蛹,則顯示被提升為主節(jié)點的從節(jié)點信息) - SENTINEL reset <pattern>
重置名字匹配該 正則表達式 的所有的 主節(jié)點 的狀態(tài)信息,清除它之前的 狀態(tài)信息刑枝,以及 從節(jié)點 的信息香嗓,并自動重新發(fā)現(xiàn)。 - SENTINEL failover <master_name>
強制當(dāng)前 Sentinel 節(jié)點執(zhí)行 failover装畅,并且不需要得到其他 Sentinel 節(jié)點的同意靠娱。但是 failover 后會將 最新的配置 發(fā)送給其他 Sentinel 節(jié)點。 - info
info信息下會有當(dāng)前sentinel的各種信息:- 1.master:當(dāng)前sentinel監(jiān)聽的主節(jié)點的狀態(tài)
- SENTINEL REMOVE <name>
用來移除指定的主節(jié)點:主節(jié)點不再被監(jiān)控掠兄,并且將被從Sentinel的內(nèi)部狀態(tài)中被完全移除像云,所以不會被SENTINEL masters列出。
發(fā)布/訂閱消息列表
- +reset-master <instance details> --- 主節(jié)點被重置蚂夕。
- +slave <instance details> --- 一個新的從節(jié)點被發(fā)現(xiàn)和關(guān)聯(lián)迅诬。
- +failover-state-reconf-slaves <instance details> --- 故障轉(zhuǎn)移狀態(tài)被轉(zhuǎn)換為reconf-slaves狀態(tài)。
- +failover-detected <instance details> --- 另一個Sentinel開始了故障轉(zhuǎn)移或者其他的外部實體被發(fā)現(xiàn)(一個關(guān)聯(lián)的從節(jié)點變?yōu)橹鞴?jié)點)婿牍。
- +slave-reconf-sent <instance details> --- 為了給新的從節(jié)點重新配置侈贷,sentinel 中的leader發(fā)送SLAVEOF命令到這個實例。
- +slave-reconf-inprog <instance details> --從節(jié)點被重新配置展示一個主節(jié)點的從節(jié)點等脂,但是同步過程尚未完成俏蛮。
- +slave-reconf-done <instance details> --- 從節(jié)點現(xiàn)在和主節(jié)點是同步的。
-dup-sentinel <instance details> --指定的主節(jié)點上遥,一個或者多個sentinels被 移除搏屑,因為是重復(fù)的。 - +sentinel <instance details> --- 這個主節(jié)點的一個新的sentinel被發(fā)現(xiàn)和關(guān)聯(lián)粉楚。
- +sdown <instance details> --- 指定的實例現(xiàn)在處于主觀下線狀態(tài)辣恋。
- -sdown <instance details> --- 指定的實例不再處于主觀下線狀態(tài)蹦疑。
- +odown <instance details> --- 指定的實例現(xiàn)在處于客觀下線狀態(tài)甘邀。
- -odown <instance details> --- 指定的實例現(xiàn)在不處于客觀下線狀態(tài)。
- +new-epoch <instance details> --- 當(dāng)前時間被更新撬碟。
- +try-failover <instance details> --- 準(zhǔn)備新的故障轉(zhuǎn)移撵摆,等待大多數(shù)的選舉底靠。
- +elected-leader <instance details> --- 贏得了選舉害晦,開始故障轉(zhuǎn)移特铝。
- +failover-state-select-slave <instance details> --- 新的故障轉(zhuǎn)移狀態(tài)是select-- slave:我們 正在尋找合適提升為主節(jié)點的從節(jié)點暑中。
- no-good-slave <instance details> --- 沒有合適進行提升的從節(jié)點。一般會在稍后重試鲫剿,但是這或許會改變并且終止故障轉(zhuǎn)移鳄逾。
- selected-slave <instance details> --- 我們找到了指定的從節(jié)點來進行提升。
- failover-state-send-slaveof-noone <instance details> --- 我們嘗試重新配置這個提升后的主節(jié)點灵莲,等待它切換雕凹。
- failover-end-for-timeout <instance details> --- 故障轉(zhuǎn)移由于超時而停止,無論如何從節(jié)點最后被配置為復(fù)制新的主節(jié)點政冻。
- failover-end <instance details> --- 故障轉(zhuǎn)移由于成功而停止枚抵,所有的從節(jié)點被配置為復(fù)制新的主節(jié)點。
- switch-master <master name> <oldip> <oldport> <newip> <newport> --- 配置改變后明场,主節(jié)點新的IP和地址都是指定的汽摹。這是大多數(shù)外部用戶感興趣的消息。
- +tilt --- 進入Tilt模式苦锨。
- -tilt --- 退出Tilt模式逼泣。
呼應(yīng)前言,之前線上出現(xiàn)舟舒,手動failover的時候拉庶,客戶端沒有感知主從切換,導(dǎo)致始終往老的主節(jié)點寫數(shù)據(jù)秃励,此時老的主節(jié)點已經(jīng)變成從節(jié)點氏仗,寫入報錯。
經(jīng)排查莺治,是因為線上redis配置了7個sentinel廓鞠,其中4個不可用,而quorum為2谣旁,這導(dǎo)致床佳,當(dāng)2個sentinel節(jié)點同意主節(jié)點不可用,嘗試開始故障轉(zhuǎn)移榄审,但是沒有至少4個sentinel節(jié)點授權(quán)并開始砌们,所以sentinel就不會開始故障轉(zhuǎn)移,也就不會publish相關(guān)消息搁进,導(dǎo)致客戶端不感知浪感。
集群模式
待完善