Redis高可用架構

概述

?Redis作為常用的緩存中間件,因其高性能,豐富的數據結構,使用簡單等,常被用在需要一定高性能的To C業務場景中,如「秒殺場景」「用戶信息中心」「帖子」「群聊」等等大家常見的業務場景中,以提高服務的響應速度,降低接口RT,同時也可以降低對DB層的壓力,以提高整個服務集群的可靠性與穩定性等,提升用戶體驗。當然,Redis還有很多的應用場景,如分布式鎖,限流等等的應用場景,后續會逐一進行討論分析。
?To C的高流量場景往往反映著該服務所對應的業務域具有較高的重要性,對服務集群的高性能與高可靠性都具有較高的要求,Redis作為常用的緩存中間件嵌入在服務中來抗大流量,其自生就應該具備一定的高可用性。
?從Redis誕生至今,其高可用架構也在不斷的演進中,以滿足不同業務體量下服務的性能與可用性需求。從最初的主從架構,到基于Sentinel(哨兵模式)的高可用架構,再到目前被廣泛使用的集群架構,Redis都在不斷發展演進。每一種結構都存在其對應的優缺點,也對應著應用場景,本文將著重介紹Redis不同的高可用架構,對應的優缺點,以及每種架構的實現原理,應用場景等,其高性能的實現原理不在本文的討論范圍內(想必大家也都了解Redis為何性能好的原因)。
?希望本文對想了解Redis高可用架構的同學有一定的幫助,最后也歡迎大家指出其中的問題,一起討論。

?內容說明
? 1. 本文將按照Redis演進的時間線,逐一的介紹不同的架構。分別為:「基本的主從架構」「改進的主從架構」「基于Sentinel(哨兵模式)的高可用架構」「集群模式」。
? 2. 因整體內容較多,本文將分階段進行完善。

?閱讀說明:中間涉及到一些分布式相關知識,有一定分布式基礎的可更好理解相關內容。

主從架構

基本的主從架構

whiteboard_exported_image.png

??主從架構模式:部署多臺redis節點,其中只有一臺節點是主節點(master),其他的節點都是從節點(slave),也叫備份節點(replica)。只有master節點提供數據的事務性操作(增刪改),slave節點只提供讀操作。所有slave節點的數據都是從master節點同步過來的。

問題與缺點

??上圖只是最簡單的一種主從結構方式,所有的slave節點都掛在master節點上,這樣做的好處是slave節點與master節點的數據延遲較小;缺點是如果slave節點數量很多,master同步一次數據的耗時就很長,影響master節點的性能。

改進的主從架構

主從從架構

??當slave過多時,可以將主從架構調整為主從從的拓撲結構,以減少過多的slave節點數據同步(全量同步/增加同步)帶來的cpu/網絡等的開銷,降低master節點的壓力;
whiteboard_exported_image (1).png

問題與缺點

??一主多從變為樹樁結構,由于層級深度,導致深度越高的slave與最頂層master間數據同步延遲較大,數據一致性變差,所以最多不要超過三層。

主要使用場景

  • 讀多寫少 - 讀寫分離 - 有一定的并發量

主從同步機制

全量同步(快照同步)

觸發場景
  1. 集群中加入新的節點
  2. 主從節點偏移量差距超過一定的閾值
    1. 潛在的原因:
      1. 網絡問題
      2. 從節點離線較長后再次連上集群,導致主從數據偏移量相差過大
      3. 主節點寫入數據的速度大于主從同步的數據等場景
    2. 閾值:由redis buffer 緩沖區的大小決定
同步原理
  1. 從節點啟動之后會與主節點建立socket長連接,然后向主節點發送psync指令
  2. 主節點收到從節點的psync指令之后,會執行BGsave命令生成新的rbd持久化文件,在生成過程中處理的客戶端寫操作命令會放在repl緩沖區。
  3. 主節點將生成的rbd文件發送給從節點,從節點清空老數據,加載新的rbd文件
  4. 主節點將生成的repl緩沖區的指令發送給從節點,從節點將執行該命令,將數據寫入到內存
  5. 主節點通過socket長連接把修改命令發送給從節點,保證主從一致
全量同步開銷

??主節點:生成RDB文件會占用內存、硬盤資源,網絡傳輸RDB的時候會占用一定的網絡帶寬資源
從節點:清空數據,若數據量大,需要消耗一定的時間,加載RDB也需要一定的時間

命令傳播(增量同步)

??在master節點和slave節點同步完成后,主服務器的每次更新都會發送相應的命令到從服務器。從服務器執行對應操作,將數據庫狀態更新到主服務器一致的狀態。

1.支持斷點續傳 - 通過 master的redis buffer緩沖區 / master節點offset / slave節點的offset實現

無盤復制

??通常,全量復制需要在磁盤上創建RDB文件,然后加載到內存中,Redis支持無盤復制,生成的RDB文件不保存到磁盤而是直接通過網絡發送給從節點。無盤復制適用于主節點所在機器磁盤性能較差但網絡寬帶較充裕的場景。需要注意的是,無盤復制目前依然處于實驗階段。(類似零拷貝)

問題與缺點

  • 主從架構的問題在于所有的寫入操作都在master節點上,實際上是一個具有單點問題的架構;若master節點出現異常(節點下線等導致的不可用等),則整個集群將不可用
  • 主從切換需要人工干預(無選舉機制),同時需要變更客戶端連接地址

基于Sentinel(哨兵模式)的高可用架構

出現背景

Sentinel架構解決redis主從架構人工干預的問題。

Redis官方文檔
https://redis.io/docs/latest/operate/oss_and_stack/management/sentinel/

簡介

??Redis Sentinel 是 Redis 的高可用實現方案。Sentinel不是一個單獨的進程,而是有多個哨兵服務組成的分布式系統。Sentinel集群獨立于 Redis 集群,哨兵之間彼此建立連接,共同監控、管理所有的 Redis 節點。哨兵間使用流言協議(gossip protocols)進行消息傳播,使用投票協議(agreement protocols)決定是否執行自動故障遷移和選擇新的主節點。

作用

  1. 監  控:監控所有 Redis 節點的狀態。
  2. 故障轉移:當哨兵發現主節點下線時,會在所有從節點中選擇一個作為新的主節點,并將所有其他節點的 Master 指向新的主節點。同時已下線的原主節點也會被降級為從節點,并修改配置將 原Master 指向新的主節點,等到它重新上線時就會自動以從節點進行工作。
  3. 通  知:當哨兵選舉了新的主節點之后,可以通過 API 向客戶端進行通知。

基本原理

??Sentinel服務負責持續監控主從節點的健康狀況,當主節點掛掉時,自動選擇一個最優的從節點切換為主節點。客戶端來連接集群時,會首先連接 sentinel,通過 sentinel 來查詢主節點的地址,然后再去連接主節點進行數據交互。當主節點發生故障時,客戶端會重新向 sentinel 要地址,sentinel 會將最新的主節點地址告訴客戶端。如此應用程序將無需重啟即可自動完成節點切換。

從庫發現

??對于哨兵的配置,我們只需要配置主庫的信息,哨兵在連接主庫之后,會調用 INFO 命令獲取主庫的信息,再從中解析出連接主庫的從庫信息,再以此和其他從庫建立連接進行監控。

??哨兵對所有節點都會每隔 10s 發送一次 INFO 命令,從各節點獲取 Redis 集群實時的拓撲圖信息。如果新節點加入,哨兵就會去監控新的節點。

**INFO**命令信息

# Replication
role:master
connected_slaves:2
slave0:ip=172.25.0.102,port=6379,state=online,offset=258369,lag=1
slave1:ip=172.25.0.103,port=6379,state=online,offset=258508,lag=0
master_failover_state:no-failover
master_replid:a4a6a7f3b2e15d9a43c01d4ba6c842539e582d6a
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:258508
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:258508

發布/訂閱機制

??哨兵們在連接同一個主庫之后,是通過發布/訂閱(pub/sub)模式來發現彼此的存在的。

發布/訂閱(pub/sub)是一種消息通信模式,主要的目的是解耦消息發布者和消息訂閱者之間的耦合。Redis 作為一個 pub/sub server,在訂閱者和發布者之間起到了消息路由的功能。訂閱者可以通過 subscribe 和 psubscribe 命令從 Redis 訂閱自己感興趣的消息類型,Redis 將消息類型稱為頻道(channel)。當發布者通過 publish 命令向 Redis 發送特定類型的消息時,該頻道的全部訂閱者都會收到此消息。這里消息的傳遞是多對多的。一個 client 可以訂閱多個 channel,也可以向多個 channel 發送消息

??在哨兵模式下,哨兵們會在每個 Redis 服務上創建并訂閱一個名為 sentinel:hello 的頻道,哨兵們就是通過它來相互發現,實現相互通信的。
??訂閱后,每個哨兵每隔 2 秒都會向 hello 頻道發布一條攜帶自身信息的 hello 信息,這樣哨兵就能知道其他哨兵的狀態、監控的主節點和是否有新的哨兵加入:

//Hello頻道消息
127.0.0.1:6371> subscribe __sentinel__:hello
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "__sentinel__:hello"
3) (integer) 1
1) "message"
2) "__sentinel__:hello"
3) "172.25.0.202,26379,5134e342cc62ac76494c140b66b7fda80340e3a8,0,mymaster,172.25.0.101,6379,0"
1) "message"
2) "__sentinel__:hello"
3) "172.25.0.203,26379,5f5ce54a6f22f71c7d273cfb9eb14377b103d4ad,0,mymaster,172.25.0.101,6379,0"
1) "message"
2) "__sentinel__:hello"
3) "172.25.0.201,26379,4fa3486dfbaca9abc62b2976e821d18e697ab2db,0,mymaster,172.25.0.101,6379,0"

whiteboard_exported_image (2).png

監控

??哨兵在對 Redis 節點建立 TCP 連接之后,會周期性地發送 PING 命令給節點(默認是 1s),以此判斷節點是否正常。如果在 down-after-millisenconds 時間內沒有收到節點的響應,它就認為這個節點掉線了。

主觀下線

??當哨兵發現與自己連接的其他節點斷開連接,它就會將該節點標記為主觀下線+sdown),包括主節點、從節點或者其他哨兵都可以標記為 sdown 狀態。

//從節點主觀下線
1:X 19 Mar 2024 13:26:29.837 # +sdown slave 172.25.0.103:6379 172.25.0.103 6379 @ mymaster 172.25.0.101 6379# 
//哨兵主觀下線
1:X 19 Mar 2024 13:19:19.799 # +sdown sentinel 5134e342cc62ac76494c140b66b7fda80340e3a8 172.25.0.202 26379 @ mymaster 172.25.0.101 6379# 
//主節點主觀下線
1:X 19 Mar 2024 13:24:06.612 # +sdown master mymaster 172.25.0.101 6379

??當該節點重新連接之后,哨兵會取消對它的主觀下線標記,操作是 -sdown

1:X 19 Mar 2024 13:20:04.811 # -sdown sentinel 5134e342cc62ac76494c140b66b7fda80340e3a8 172.25.0.202 26379 @ mymaster 172.25.0.101 6379

??如果哨兵判斷從節點或者其他哨兵節點主觀下線,哨兵并不會執行其他操作。如果是主節點主觀下線,哨兵就要采取措施,確定主節點是否真的宕機,并執行故障轉移。

客觀下線

??哨兵確認主節點是否真的宕機這一步成為客觀下線確認,如果主節點真的宕機了,哨兵就會將主節點標記為客觀下線+odown)狀態。

1:X 19 Mar 2024 13:24:06.612 # +sdown master mymaster 172.25.0.101 6379
1:X 19 Mar 2024 13:24:06.685 # +odown master mymaster 172.25.0.101 6379 #quorum 2/2

??要判斷主節點是否客觀下線,需要與其他哨兵達成共識,如果大多數哨兵認為主節點主觀下線了,哨兵才能確認主節點客觀下線。達成共識的方式就是發起一輪投票,如果票數超過哨兵節點數的一半,并且大于等于 quorum 設置的數量,就是投票成功。否則哨兵就不能說主節點客觀下線了。
quorum 是法定人數的意思,該信息在哨兵配置信息中進行配置:

# sentinel.conf
sentinel monitor <master-name> <ip> <redis-port> <quorum>

客觀下線投票過程

  1. 當哨兵發現主節點下線,標記主節點為 sdown 狀態。
  2. 哨兵向其他哨兵發送 SENTINEL is-master-down-by-addr 命令,詢問其他哨兵該主節點是否已下線。
  3. 其他哨兵在收到投票請求之后,會檢查本地主緩存中主節點的狀態并進行回復(1 表示下線,0 表示正常)。
  4. 發起的詢問的哨兵在接收到回復之后,會累加“下線”的得票數。
  5. 當下線的票數大于一半哨兵數量并且不小于 quorum 時,就會將主節點標記為 odown 狀態。并開始準備故障轉移。
  6. 發起投票的哨兵有一個投票倒計時,倒計時結束如果票數仍然不夠的話,則放棄本次客觀線下投票。并嘗試繼續與主節點建立連接。
【注意】
1.當哨兵把主節點標記為 odown 時,并不會通知其他哨兵,因為這樣自己才更有機會進行故障轉移。2.如果多個哨兵在同一段時間內發現主節點下線,那么每個發現的哨兵都會發起投票,投票的結果只是讓發起投票的哨兵能夠確認主節點是否下線,并不會與其他哨兵共享。因此這個下線確認的動作是多個節點同時發起進行的。

故障轉移

??哨兵在將主節點標記為 odown 狀態之后,就會馬上開始嘗試故障轉移了。

??故障轉移主要由 sentinelFailoverStateMachineZ(sentinelRedisInstance) 函數負責。該函數由一個狀態機組成,共有五個狀態,標志著故障轉移共分為五個大步驟:

| SENTINEL_FAILOVER_STATE | desc           | invoke                                                  
|:------------------------|:---------------|:-------------------------------------------------------|
| `WAIT_START`            | Leader 選舉    | sentinelFailoverWaitStart(sentinelRedisInstance)        |
| `SELECT_SLAVE`          | Master 選取    | sentinelFailoverSelectSlave(sentinelRedisInstance)      |
| `SEND_SLAVEOF_NOONE`    | Slave 身份去除 | sentinelFailoverSendSlaveOfNoOne(sentinelRedisInstance)  |
| `WAIT_PROMOTION`        | 提升 Master    | sentinelFailoverWaitPromotion(sentinelRedisInstance)    |
| `RECONF_SLAVES`         | 配置從節點     | sentinelFailoverReconfNextSlave(sentinelRedisInstance)   |

詳見:https://www.jianshu.com/p/178d0b10809c

整體架構

whiteboard_exported_image (3).png

集群模式(Redis Cluster)

節點負載均衡

一致性哈希

數據分布算法

虛擬節點機制

集群請求重定向

MOVED 錯誤

ASK 錯誤

Goosip協議

說明:集群節點通信機制

集群可以設置多大?

動態縮擴容

故障轉移

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/83983.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/83983.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/83983.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用WPF的Microsoft.Xaml.Behaviors.Wpf中通用 UI 元素事件

Nuget下載之后記得要先引用下面的 xmlns:i"http://schemas.microsoft.com/xaml/behaviors" <!-- 鼠標事件 --> <i:EventTrigger EventName"MouseEnter"/> <!-- 鼠標進入 --> <i:EventTrigger EventName"MouseLeave"/&g…

敏捷開發中如何避免過度加班

在敏捷開發過程中避免過度加班&#xff0c;需要明確敏捷原則、合理規劃迭代任務、加強團隊溝通、優化流程效率、設定合理的工作負荷、注重團隊士氣和成員健康。明確敏捷原則&#xff0c;即保證可持續發展的步調&#xff0c;避免頻繁地變更需求、過度承諾任務量。合理規劃迭代任…

JSON解析崩潰原因及解決方案

問題記錄&#xff1a; /************************************************| * 描述: 將ID124執行NFC操作-JSON解析為結構體* 函數名: cJSON_ID124_to_struct* 參數[ I]: *json_string 待解析的指針* 參數[II]: *wireless_rxd 結構體指針* 返回: 成功返回0 失…

業務系統對接大模型的基礎方案:架構設計與關鍵步驟

業務系統對接大模型&#xff1a;架構設計與關鍵步驟 在當今數字化轉型的浪潮中&#xff0c;大語言模型&#xff08;LLM&#xff09;已成為企業提升業務效率和創新能力的關鍵技術之一。將大模型集成到業務系統中&#xff0c;不僅可以優化用戶體驗&#xff0c;還能為業務決策提供…

Edge(Bing)自動領積分腳本部署——基于python和Selenium(附源碼)

微軟的 Microsoft Rewards 計劃可以通過 Bing 搜索賺取積分&#xff0c;積分可以兌換禮品卡、游戲等。每天的搜索任務不多&#xff0c;我們可以用腳本自動完成&#xff0c;提高效率&#xff0c;解放雙手。 本文將手把手教你如何部署一個自動刷積分腳本&#xff0c;并解釋其背…

前端基礎之《Vue(19)—狀態管理》

一、什么是狀態管理 1、Vue版本問題 Vue2 Vuex3 Vue3 Vuex4 / Pinia2 在使用任何技術的時候&#xff0c;都先要去搜索一下版本&#xff0c;你的版本和腳手架環境是否兼容。 2、安裝Vuex yarn add vuex3.6.2 3、狀態管理 狀態&#xff0c;在應用程序中表示數據&#xff0c…

【圖像處理基石】如何進行圖像畸變校正?

圖像畸變校正常用于計算機視覺、攝影測量學和機器人導航等領域&#xff0c;能夠修正因鏡頭光學特性或傳感器排列問題導致的圖像失真。下面我將介紹幾種常用的圖像畸變校正算法&#xff0c;并提供Python實現和測試用例。 常用算法及Python實現 1. 徑向畸變校正 徑向畸變是最常…

藍橋杯_DS18B20溫度傳感器---新手入門級別超級詳細解析

目錄 一、引言 DS18B20的原理圖 單總線簡介&#xff1a; ?編輯暫存器簡介&#xff1a; DS18B20的溫度轉換與讀取流程 二、代碼配置 maic文件 疑問 關于不同格式化輸出符號的使用 為什么要rd_temperature()/16.0&#xff1f; onewire.h文件 這個配置為什么要先讀lo…

MySQL的并發事務問題及事務隔離級別

一、并發事務問題 1). 贓讀&#xff1a;一個事務讀到另外一個事務還沒有提交的數據。 比如 B 讀取到了 A 未提交的數據。 2). 不可重復讀&#xff1a;一個事務先后讀取同一條記錄&#xff0c;但兩次讀取的數據不同&#xff0c;稱之為不可重復讀。 事務 A 兩次讀取同一條記錄&…

密碼學基礎——SM4算法

博客主頁&#xff1a;christine-rr-CSDN博客 ????專欄主頁&#xff1a;密碼學 &#x1f4cc; 【今日更新】&#x1f4cc; 對稱密碼算法——SM4 目錄 一、國密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特點 2.3 基本部件 2.3.1 S盒 2.3.2 非線性變換 ?編輯…

練習:對象數組 4

定義數組存儲 4 個女朋友的對象。女朋友的屬性&#xff1a;姓名、年齡、性別、愛好&#xff1b;要求1&#xff1a;計算出四個女朋友的平均年齡&#xff1b;要求2&#xff1a;統計年齡比平均值低的女朋友有幾個&#xff1f;并把他們的所有信息打印出來。 代碼&#xff1a; //對…

React Hooks 基礎指南

React Hooks 是 React 16.8 引入的重要特性&#xff0c;它允許開發者在函數組件中使用狀態和其他 React 特性。本文將詳細介紹 6 個最常用的 React Hooks。 1. useState useState 是最常用的 Hook&#xff0c;用于在函數組件中添加 state。 import React, { useState } from…

【Python 算法零基礎 4.排序 ⑥ 快速排序】

既有錦繡前程可奔赴&#xff0c;亦有往日歲月可回首 —— 25.5.25 選擇排序回顧 ① 遍歷數組&#xff1a;從索引 0 到 n-1&#xff08;n 為數組長度&#xff09;。 ② 每輪確定最小值&#xff1a;假設當前索引 i 為最小值索引 min_index。從 i1 到 n-1 遍歷&#xff0c;若找到…

處理git沒做修改,但是文件顯示變更的情況

使用 TortoiseGit&#xff08;小烏龜 Git&#xff09; 時遇到 “文件內容沒改&#xff0c;但顯示為變更&#xff0c;提示有 n 行刪除、n 行添加”&#xff0c;你可以按照以下步驟操作來排查并解決問題&#xff1a; ? 一、定位問題根源&#xff08;是否為行尾差異&#xff09;…

智慧貨運飛船多維度可視化管控系統

圖撲搭建智慧貨運飛船可視化系統&#xff0c;借數字孿生技術&#xff0c;高精度復刻貨運飛船外觀、結構與運行場景。整合多維度數據&#xff0c;實時呈現飛行狀態、設備參數等信息&#xff0c;助力直觀洞察貨運飛船運行邏輯&#xff0c;為航天運維、任務推演及決策提供數字化支…

maven微服務${revision}依賴打包無法識別

1、場景描述 我現在又一個微服務項目&#xff0c;父pom的版本&#xff0c;使用<properties>定義好&#xff0c;如下所示&#xff1a; <name>ypsx-finance-center</name> <artifactId>ypsx-finance</artifactId> <packaging>pom</pack…

詳解代理型RAG與MCP服務器集成

檢索增強型生成(RAG)將語言模型與外部知識檢索相結合,讓模型的回答基于最新的事實,而不僅僅是其訓練數據呢。 RAG(高級別) 在 RAG 流程中,用戶查詢用于搜索知識庫(通常通過向量數據庫中的嵌入來實現),并將檢索到的最相關文檔“增強”到模型的提示中,以幫助生成事實…

智能倉儲的未來:自動化、AI與數據分析如何重塑物流中心

當倉庫學會“思考”&#xff0c;物流的終極形態正在誕生 想象這樣的場景&#xff1a; 凌晨3點&#xff0c;某物流中心燈火通明卻空無一人。AGV機器人集群根據實時訂單動態規劃路徑&#xff1b;AI視覺系統在0.1秒內掃描包裹信息&#xff1b;數字孿生平臺正模擬次日峰值流量壓力…

如何防止服務器被用于僵尸網絡(Botnet)攻擊 ?

防止服務器被用于僵尸網絡&#xff08;Botnet&#xff09;攻擊是關鍵的網絡安全措施之一。僵尸網絡是黑客利用大量被感染的計算機、服務器或物聯網設備來發起攻擊的網絡。以下是關于如何防止服務器被用于僵尸網絡攻擊的技術文章&#xff1a; 防止服務器被用于僵尸網絡&#xff…

貪心算法應用:硬幣找零問題詳解

貪心算法與硬幣找零問題詳解 貪心算法&#xff08;Greedy Algorithm&#xff09;在解決優化問題時表現出簡潔高效的特點&#xff0c;尤其適用于特定結構的組合優化問題。本文將用2萬字篇幅&#xff0c;深入探討貪心算法在硬幣找零問題中的應用&#xff0c;覆蓋算法原理、正確性…