Redis的主從結(jié)構(gòu)與哨兵機(jī)制詳解
redis 主從結(jié)構(gòu)
前面的博客介紹了 Redis的持久化方式,,Redis 的持久化機(jī)制能夠保障服務(wù)重啟后數(shù)據(jù)不丟失,Redis 重啟時(shí)會(huì)自動(dòng)加載硬盤上的持久化文件,將數(shù)據(jù)恢復(fù)到內(nèi)存中。但持久化只能規(guī)避服務(wù)重啟的數(shù)據(jù)丟失問題,無法應(yīng)對(duì)服務(wù)器硬盤損壞、機(jī)器宕機(jī)等硬件故障,單節(jié)點(diǎn) Redis 存在嚴(yán)重單點(diǎn)故障風(fēng)險(xiǎn),一旦節(jié)點(diǎn)故障會(huì)直接造成數(shù)據(jù)丟失、服務(wù)不可用。
同時(shí),Redis 本身具備高性能高并發(fā)的特性,單臺(tái) Redis 服務(wù)器可以承載大量并發(fā)請(qǐng)求。但在電商、社交等超高并發(fā)業(yè)務(wù)場(chǎng)景下,海量的讀寫請(qǐng)求會(huì)集中施壓?jiǎn)喂?jié)點(diǎn),即便 Redis 讀寫性能優(yōu)異,也會(huì)出現(xiàn)請(qǐng)求阻塞、服務(wù)器 CPU 和內(nèi)存負(fù)載過高、性能瓶頸凸顯的問題。
為了解決單點(diǎn)數(shù)據(jù)故障和單節(jié)點(diǎn)讀寫壓力過大兩大問題,Redis 提供了主從復(fù)制(主從架構(gòu)) 機(jī)制。主從架構(gòu)采用一主多從的部署模式:主節(jié)點(diǎn)(Master) 同時(shí)支持讀、寫操作,負(fù)責(zé)處理業(yè)務(wù)新增、修改、刪除等寫請(qǐng)求;從節(jié)點(diǎn)(Slave) 僅提供只讀服務(wù),不參與寫業(yè)務(wù)。所有從節(jié)點(diǎn)會(huì)自動(dòng)異步同步主節(jié)點(diǎn)的數(shù)據(jù),保持與主節(jié)點(diǎn)數(shù)據(jù)最終一致性。
借助主從結(jié)構(gòu),一方面實(shí)現(xiàn)了讀寫分離,海量讀請(qǐng)求分流到從節(jié)點(diǎn),極大分擔(dān)主節(jié)點(diǎn)壓力,提升整體并發(fā)承載能力;另一方面從節(jié)點(diǎn)作為主節(jié)點(diǎn)的數(shù)據(jù)副本,實(shí)現(xiàn)了數(shù)據(jù)異地備份,主節(jié)點(diǎn)硬件故障或宕機(jī)時(shí),可快速依托從節(jié)點(diǎn)恢復(fù)服務(wù),徹底解決單節(jié)點(diǎn)的單點(diǎn)故障問題。
需要注意的是主從復(fù)制過程默認(rèn)非阻塞,主節(jié)點(diǎn)在進(jìn)行數(shù)據(jù)同步時(shí),仍可正常處理客戶端請(qǐng)求,不影響業(yè)務(wù)可用性。
如下圖:

主從復(fù)制的原理
Redis 主從復(fù)制分為建立連接、全量同步、增量同步三個(gè)核心階段,整體采用異步復(fù)制機(jī)制:
5. 從節(jié)點(diǎn)啟動(dòng)后,主動(dòng)與主節(jié)點(diǎn)建立網(wǎng)絡(luò)通信連接,成功握手后,向主節(jié)點(diǎn)發(fā)起數(shù)據(jù)同步請(qǐng)求。
6. 主節(jié)點(diǎn)接收到從節(jié)點(diǎn)的同步請(qǐng)求后,觸發(fā)bgsave后臺(tái)持久化,生成 RDB 快照文件;同時(shí)將生成 RDB 期間新產(chǎn)生的寫命令暫存到緩沖區(qū)。隨后主節(jié)點(diǎn)把完整的 RDB 文件傳輸給從節(jié)點(diǎn)。
7. 從節(jié)點(diǎn)接收 RDB 文件后,清空自身原有數(shù)據(jù),加載 RDB 文件完成全量數(shù)據(jù)同步,復(fù)刻主節(jié)點(diǎn)當(dāng)前全量數(shù)據(jù)。
8. 全量同步完成后進(jìn)入增量同步階段:主節(jié)點(diǎn)每執(zhí)行一次寫操作(增、刪、改),都會(huì)將對(duì)應(yīng)的命令異步復(fù)制發(fā)送給所有從節(jié)點(diǎn);從節(jié)點(diǎn)持續(xù)執(zhí)行同步過來的命令,始終保持與主節(jié)點(diǎn)數(shù)據(jù)一致。
補(bǔ)充:Redis 2.8 及以上版本采用PSync替代舊版SYNC,支持部分重同步,網(wǎng)絡(luò)短暫斷開重連后無需重新全量同步,僅同步斷開期間缺失的數(shù)據(jù),效率更高。
主從復(fù)制的核心作用
- 數(shù)據(jù)冗余備份
主從復(fù)制實(shí)現(xiàn)了跨節(jié)點(diǎn)熱數(shù)據(jù)備份,屬于持久化之外的另一種數(shù)據(jù)冗余方案。持久化僅做本地磁盤數(shù)據(jù)保存,無法應(yīng)對(duì)服務(wù)器硬盤損壞、整機(jī)宕機(jī);而主從節(jié)點(diǎn)分布在不同服務(wù)器,可有效規(guī)避單節(jié)點(diǎn)硬件故障導(dǎo)致的數(shù)據(jù)丟失。 - 故障快速
恢復(fù)當(dāng)主節(jié)點(diǎn)發(fā)生宕機(jī)、硬件故障等異常時(shí),從節(jié)點(diǎn)具備完整數(shù)據(jù),可臨時(shí)接管對(duì)外提供服務(wù),快速恢復(fù)業(yè)務(wù)訪問,實(shí)現(xiàn)服務(wù)級(jí)別的容災(zāi)恢復(fù),降低業(yè)務(wù)停機(jī)時(shí)長(zhǎng)。 - 讀寫分離,負(fù)載均衡
基于主從架構(gòu)天然支持讀寫分離:主節(jié)點(diǎn)負(fù)責(zé)處理所有寫請(qǐng)求,從節(jié)點(diǎn)專門承載讀請(qǐng)求。在互聯(lián)網(wǎng)多讀少寫的業(yè)務(wù)場(chǎng)景下,可部署多個(gè)從節(jié)點(diǎn)分?jǐn)傋x壓力,有效降低單節(jié)點(diǎn)負(fù)載,大幅提升系統(tǒng)整體并發(fā)訪問能力。 - 高可用架構(gòu)的基石
主從復(fù)制是 Redis哨兵機(jī)制和Redis 集群的底層基礎(chǔ)。哨兵實(shí)現(xiàn)自動(dòng)故障轉(zhuǎn)移、集群實(shí)現(xiàn)數(shù)據(jù)分片與橫向擴(kuò)容,都依賴主從復(fù)制的數(shù)據(jù)同步能力,無主從復(fù)制則無法搭建高可用、分布式架構(gòu)。
主從配置
主節(jié)點(diǎn)默認(rèn)無需特殊配置,從節(jié)點(diǎn)修改配置文件,如下:

指定主節(jié)點(diǎn)地址和端口,Redis5.0+用replicaof,5.0前用slaveof
啟動(dòng)各節(jié)點(diǎn)
需要注意的是先啟動(dòng)主節(jié)點(diǎn)生效再啟動(dòng)從節(jié)點(diǎn)生效

演示:主節(jié)點(diǎn)寫,從節(jié)點(diǎn)同步主節(jié)點(diǎn)數(shù)據(jù)

演示:從節(jié)點(diǎn)只能讀不能寫

redis 哨兵機(jī)制
Redis 哨兵是 Redis 官方提供的高可用監(jiān)控與自動(dòng)故障轉(zhuǎn)移組件,專門解決主從架構(gòu)中主節(jié)點(diǎn)故障后需手動(dòng)切換的問題。它本質(zhì)是一個(gè)獨(dú)立的 Redis 進(jìn)程(非主從節(jié)點(diǎn)),通常以集群形式部署,實(shí)現(xiàn)主節(jié)點(diǎn)故障的自動(dòng)化恢復(fù)。
哨兵的核心工作原理
- 階段 1:故障監(jiān)測(cè)
所有哨兵節(jié)點(diǎn)會(huì)持續(xù)向 Redis 主從節(jié)點(diǎn)發(fā)送 PING 心跳檢測(cè)。若某個(gè)主節(jié)點(diǎn)在配置時(shí)間內(nèi)未正常響應(yīng),當(dāng)前哨兵會(huì)先將其標(biāo)記為主觀下線(SDOWN),即單個(gè)哨兵的局部判斷,用于避免網(wǎng)絡(luò)抖動(dòng)造成的誤判。 - 階段 2:集群共識(shí)
當(dāng)前哨兵發(fā)現(xiàn)主節(jié)點(diǎn)主觀下線后,會(huì)向其他哨兵節(jié)點(diǎn)發(fā)送 “是否認(rèn)為該主節(jié)點(diǎn)故障” 的詢問請(qǐng)求。當(dāng)判定故障的哨兵數(shù)量達(dá)到配置的法定票數(shù)(quorum)時(shí),哨兵集群會(huì)將該主節(jié)點(diǎn)標(biāo)記為客觀下線(ODOWN),這是集群層面的全局共識(shí),標(biāo)志著主節(jié)點(diǎn)真正失效。 - 階段 3:領(lǐng)導(dǎo)者選舉
主節(jié)點(diǎn)客觀下線后,哨兵集群會(huì)通過選舉算法選出一個(gè)領(lǐng)導(dǎo)者哨兵,由其統(tǒng)一執(zhí)行后續(xù)故障轉(zhuǎn)移,避免多個(gè)哨兵同時(shí)操作引發(fā)沖突。領(lǐng)導(dǎo)者會(huì)按照節(jié)點(diǎn)優(yōu)先級(jí)、數(shù)據(jù)同步進(jìn)度、運(yùn)行 ID 的策略,在健康的從節(jié)點(diǎn)中選出數(shù)據(jù)最完整、最合適的節(jié)點(diǎn)作為新主節(jié)點(diǎn)。 - 階段 5:故障轉(zhuǎn)移
領(lǐng)導(dǎo)者哨兵將選中的從節(jié)點(diǎn)升級(jí)為新主節(jié)點(diǎn),并讓其他從節(jié)點(diǎn)重新復(fù)制新主節(jié)點(diǎn)的數(shù)據(jù),同時(shí)更新整個(gè)集群的拓?fù)湫畔?。若舊主節(jié)點(diǎn)后續(xù)重新上線,會(huì)被自動(dòng)配置為新主節(jié)點(diǎn)的從節(jié)點(diǎn),保證架構(gòu)最終一致。

哨兵的部署與配置
創(chuàng)建哨兵節(jié)點(diǎn)
mkdir -p /usr/local/src/redis/sentinel-demo/data/{26379,26380,26381}編寫各個(gè)哨兵的核心配置文件(sentinel.conf)
vi sentinel_26379.conf cp sentinel_26379.conf sentinel_26380.conf cp sentinel_26379.conf sentinel_26381.conf
修改各個(gè)配置文件中的數(shù)據(jù)目錄和日志文件位置

daemonize yes port 26379 bind 0.0.0.0 protected-mode no dir "/usr/local/src/redis/sentinel-demo/data/26379" logfile "/usr/local/src/redis/sentinel-demo/data/26379/sentinel.log" sentinel monitor mymaster 127.0.0.1 6380 2 sentinel down-after-milliseconds mymaster 30000 sentinel deny-scripts-reconfig yes
daemonize yes:哨兵以守護(hù)進(jìn)程方式運(yùn)行(后臺(tái)運(yùn)行);
port 26379:哨兵進(jìn)程監(jiān)聽的端口;
bind 0.0.0.0:哨兵綁定所有網(wǎng)卡的 IP,允許任意地址訪問;
protected-mode no:關(guān)閉保護(hù)模式,保護(hù)模式下哨兵僅允許本地連接,需要注意的是若哨兵部署在不同服務(wù)器必須設(shè)為no,否則無法跨機(jī)器哨兵通信;
dir “/usr/local/src/redis/sentinel-demo/data/26379” 存儲(chǔ)哨兵的狀態(tài)文件,哨兵本身幾不持久化數(shù)據(jù),主要用于臨時(shí)文件;
logfile “/usr/local/src/redis/sentinel-demo/data/26379/sentinel.log”:哨兵的日志文件路徑;
sentinel monitor mymaster 127.0.0.1 6380 2:哨兵核心監(jiān)控規(guī)則,其中 mymaster 為監(jiān)控的主節(jié)點(diǎn)名稱,127.0.0.1 6380 為主節(jié)點(diǎn)的 IP 和端口,2 為 quorum(法定票數(shù));
sentinel deny-scripts-reconfig yes:禁止通過腳本修改哨兵的配置,防止惡意篡改。
啟動(dòng)各個(gè)哨兵,需要先啟動(dòng)主哨兵,再啟動(dòng)各個(gè)從哨兵
../redis-5.0.4/src/redis-sentinel sentinel_26379.conf

展示哨兵對(duì)主節(jié)點(diǎn) mymaster(127.0.0.1:6379)的監(jiān)控狀態(tài)
../redis-5.0.4/src/redis-cli -p 26379 127.0.0.1:26379> sentinel masters
演示:主節(jié)點(diǎn)關(guān)閉后開啟降為從節(jié)點(diǎn)

![]()
到此這篇關(guān)于Redis的主從結(jié)構(gòu)與哨兵機(jī)制詳解的文章就介紹到這了,更多相關(guān)Redis主從結(jié)構(gòu)與哨兵機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis 使用跳表實(shí)現(xiàn)有序集合的方法
Redis有序集合底層為什么使用跳表而非其他數(shù)據(jù)結(jié)構(gòu)如平衡樹、紅黑樹或B+樹的原因在于其特殊的設(shè)計(jì)和應(yīng)用場(chǎng)景,跳表提供了與平衡樹類似的效率,同時(shí)實(shí)現(xiàn)更簡(jiǎn)單,調(diào)試和修改也更加容易,感興趣的朋友一起看看吧2024-09-09
深入理解Redis內(nèi)存回收和內(nèi)存淘汰機(jī)制
Redis使用多種過期策略和內(nèi)存淘汰機(jī)制來管理內(nèi)存,本文主要介紹了深入理解Redis內(nèi)存回收和內(nèi)存淘汰機(jī)制, 具有一定的參考價(jià)值,感興趣的可以了解一下2024-06-06
Redis實(shí)現(xiàn)集群搭建+集群讀寫的示例
本文介紹了Redis集群的搭建和讀寫操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-02-02

