0x02.Redis 集群的實現原理是什么?

回答重點

Redis 集群(Redis cluster)是通過多個 Redis 實例組成的,每個主節點實例負責存儲部分的數據,并且可以有一個或多個從節點作為備份

具體是采用哈希槽(Hash Slot)機制來分配數據,將整個鍵空間劃分為 16384 個槽(slots)。每個 Redis 主節點實例負責一定范圍的哈希槽,數據的 key 經過 CRC16-CCITT 哈希算法計算后對 16384 取余即可定位到對應的節點。

客戶端在發送請求時,會通過集群的任意節點進行連接,如果該節點存儲了對應的數據則直接返回,反之該節點會根據請求的鍵值計算哈希槽并路由到正確的節點。現代 Redis 客戶端通常會緩存槽位映射信息,避免頻繁重定向。

簡單來說,集群就是通過多臺機器分擔單臺機器上的壓力,同時通過主從復制提供高可用性。

擴展知識

Redis 集群中節點之間的信息如何同步?

Redis 集群內每個節點都會保存集群的完整拓撲信息,包括每個節點的 ID、IP 地址、端口、負責的哈希槽范圍等。

節點之間使用 Gossip 協議進行狀態交換,以保持集群的一致性和故障檢測。每個節點會周期性地發送 PING 和 PONG 消息,交換集群信息,使得集群信息得以同步。

Gossip 的優點

  • 最終一致性:Gossip 協議能夠在一段時間后使集群信息達成一致,雖然傳播速度不如中心化方案快,但網絡開銷更小。
  • 降低網絡負擔:由于信息是以隨機節點間的對話方式傳播,避免了集中式的狀態查詢,從而降低了網絡流量。

Gossip 協議

Gossip 主要特點

  1. 分布式信息傳播:每個節點定期向其他節點發送其狀態信息,確保所有節點對集群的狀態有一致的視圖。
  2. 低延遲和高效率:Gossip 協議設計為輕量級的通信方式,能夠快速傳播信息,減少單點故障帶來的風險。
  3. 去中心化:沒有中心節點,所有節點平等地參與信息傳播,提高了系統的魯棒性。

工作原理

  1. 狀態報告:每個節點在特定的時間間隔內,向隨機選擇的其他節點發送其自身的狀態信息,包括節點的主從關系、槽位分布等。
  2. 信息更新:接收到狀態信息的節點會根據所接收到的數據更新自己的狀態,并將更新后的狀態繼續傳播給其他節點。
  3. 節點檢測:通過周期性交換狀態信息,節點可以檢測到其他節點的存活狀態。如果某個節點未能在預定時間內響應,則該節點會被標記為故障節點。
  4. 容錯處理:在檢測到節點故障后,集群中的其他節點可以采取措施(如重新分配槽位)以保持系統的高可用性。

Redis 集群分片原理圖示

Redis 集群會將數據分散到 16384(2^14)個哈希槽中,集群中的每個主節點負責一定范圍的哈希槽,在 Redis 集群中,使用 CRC16-CCITT 哈希算法計算鍵的哈希槽,以確定該鍵應存儲在哪個節點。

集群哈希槽分片如下圖所示:

在這里插入圖片描述

每個節點會擁有一部分的槽位,然后對應的鍵值會根據其本身的 key,映射到一個哈希槽中,其主要流程如下:

  • 根據鍵值的 key,按照 CRC16-CCITT 算法計算一個 16 bit 的值,然后將 16 bit 的值對 16384 進行取余運算,最后得到一個對應的哈希槽編號。
  • 值得注意的是,Redis 支持哈希標簽(Hash Tags)機制,即如果鍵名中包含 “{…}” 格式的內容,那么只有花括號內的內容會被用來計算哈希槽,這樣可以確保相關聯的鍵被分配到同一個槽中。
  • 根據每個節點分配的哈希槽區間,對應編號的數據落在對應的區間上,就能找到對應的分片實例。

為了方便大家理解,我這里畫一個對應的關系圖,以三個節點為例:

Redis 哈希槽映射圖


CRC16(Key1) % 16384 = 123
CRC16(Key2) % 16384 = 8275
CRC16(Key3) % 16384 = 12319
Redis實例 1(0 ~ 5460)
Redis實例 2(5461 ~ 10922)
Redis實例 3(10923 ~ 16383)

這里還有一點需要強調下,Redis 客戶端可以訪問集群中任意一臺實例,正常情況下這個實例包含這個數據
但如果槽被轉移了,客戶端還未來得及更新槽的信息,當前實例沒有這個數據,則返回 MOVED 響應給客戶端,將其重定向到對應的實例(因 Gossip 協議確保集群內每個節點都會保存集群的完整拓撲信息)。

Redis 集群中存儲 key 示例

假設我們有一個 Redis 集群,包含三個主節點(Node1、Node2、Node3),它們分別負責以下哈希槽:

  • Node1: 哈希槽 0-5460
  • Node2: 哈希槽 5461-10922
  • Node3: 哈希槽 10923-16383

現在要存儲一個鍵為 user:1001 的數據。

計算哈希槽
  1. 使用 CRC16-CCITT 哈希算法計算 user:1001 的 CRC16 值。
  2. 假設計算結果為 12345。
  3. 然后,計算該值對應的哈希槽:
    • 哈希槽 = 12345 % 16384 = 12345。
確定目標節點
  • 12345 落在 Node3 的負責范圍(10923-16383),因此,user:1001 會被存儲在 Node3 中。

Redis 集群中請求 key 示例(客戶端直接連接的并不是對應 key 的節點)

如果客戶端連接的是集群的 Node1,但需要訪問存儲在 Node3 的鍵 user:1001,查詢過程如下:

查詢過程

1)計算哈希槽

  • 客戶端使用 CRC16-CCITT 算法計算 user:1001 的哈希值(假設為 12345)。
  • 計算哈希槽:12345 % 16384 = 12345。

2)查詢請求

  • 因為客戶端連接的是集群中的 Node1,所以客戶端發送查詢命令 GET user:1001 到 Node1。

3)Node1 響應

  • Node1 檢測到請求的鍵 user:1001 屬于 Node3,返回一個 MOVED 錯誤,指示客戶端請求的鍵在另一個節點上。MOVED 錯誤中會返回目標節點的信息(例如,Node3 的 IP 和端口)。

4)客戶端處理

  • 現代 Redis 客戶端會緩存此槽位映射信息,后續對該槽的請求會直接發送到正確的節點,避免重定向。
  • 第一次收到 MOVED 錯誤時,客戶端會連接到目標節點并更新槽位映射緩存。

5)發送查詢請求到正確節點

  • 客戶端向 Node3 發送 GET user:1001

6)獲取結果

  • Node3 查詢到 user:1001 的值(假設為 {"name": "stormsha", "age": 16}),并返回結果。

為什么 Redis 哈希槽節點的數目是 16384 呢?

1)首先是消息大小的考慮

正常的心跳包需要帶上節點完整配置數據,心跳還是比較頻繁的,所以需要考慮數據包的大小,如果使用 16384 數據包只要約 2KB,如果用了 65536 則需要約 8KB。

實際上槽位信息使用一個長度為 16384 位的位圖(bitmap)來表示,節點擁有哪個槽位,就將對應位置的位設置為 1,否則為 0。

Redis 心跳消息(CLUSTERMSG)數據結構如下所示:

typedef struct {char sig[4];              /* 信息標識 */uint32_t totlen;          /* 消息總長度 */uint16_t ver;             /* 協議版本 */uint16_t type;            /* 消息類型, 用于區分meet,ping,pong等消息 */uint16_t count;           /* 消息體包含的節點數量, 僅用于meet,ping,pong消息類型*/uint64_t currentEpoch;    /* 當前發送節點的配置紀元 */uint64_t configEpoch;     /* 主節點/從節點的主的配置紀元 */char sender[CLUSTER_NAMELEN]; /* 發送節點的nodeId */unsigned char myslots[CLUSTER_SLOTS/8]; /* 發送節點負責的槽信息 */char slaveOf[CLUSTER_NAMELEN]; /* 如果是從節點,記錄主節點的nodeId */uint16_t port;            /* 端口號 */uint16_t flags;           /* 發送節點標識,區分主從角色,是否下線等 */unsigned char state;      /* 發送節點的集群狀態 */unsigned char mflags[3];  /* 消息標識 */union clusterMsgData data /* 消息正文 */;
} clusterMsg;

這里我們看到一個重點,即在消息頭中最占空間的是 myslots[CLUSTER_SLOTS/8]

  • 當槽位為 65536 時,這部分大小: 65536÷8=8192 字節 ≈8KB
  • 當槽位為 16384 時,這部分大小: 16384÷8=2048 字節 ≈2KB

如果槽位為 65536,這個心跳消息的頭部就太大了,在高頻率通信的集群環境中會顯著增加網絡負擔。

2)集群規模的考慮

根據 Redis 作者的說明,集群不太可能會擴展超過 1000 個節點,而每個主節點應該管理相當數量的哈希槽。如果使用 16384 個槽位:

  • 100 個節點集群:平均每個節點管理約 164 個槽位
  • 1000 個節點集群:平均每個節點管理約 16 個槽位

這個數量既能滿足大多數集群規模需求,又不會因為槽位過少而影響數據分布均衡性。

3)內存占用的平衡

Redis 作為內存數據庫,對內存使用的效率非常關注。16384 個槽位的設計在集群功能和資源消耗之間取得了很好的平衡:足夠多的槽位保證良好的數據分布,同時槽位映射的內存占用和網絡傳輸開銷都保持在合理范圍內。

好的,以下是測試題目解析部分分開的版本:


? Redis 集群選擇題(共 4 題)

1. Redis 集群采用什么機制來分配數據到不同的節點? ( )
A. 哈希槽機制
B. 主備機制
C. 哈希鏈機制
D. 分段機制

2. Redis 集群中有多少個哈希槽? ( )
A. 2048
B. 8192
C. 16384
D. 32768

3. Redis 集群中的節點之間使用什么協議進行狀態同步和故障檢測? ( )
A. TCP/IP 協議
B. HTTP 協議
C. UDP 協議
D. Gossip 協議

4. 在 Redis 集群中,當客戶端請求的鍵值對不在連接的節點上時,返回的錯誤類型是什么? ( )
A. ERROR
B. MOVED
C. NOT_FOUND
D. FORBIDDEN

📘 答案與解析

1. 正確答案:A
解析:Redis 集群通過哈希槽機制進行數據分配,避免單點瓶頸,將鍵映射到 16384 個槽中,再分配到不同節點。


2. 正確答案:C
解析:Redis 集群采用固定的 16384 個哈希槽,這個值是 21?,設計用于在帶寬與靈活性之間做出平衡。


3. 正確答案:D
解析:Redis 集群使用 Gossip 協議實現去中心化狀態同步和故障檢測,各節點定期交換信息。


4. 正確答案:B
解析:當客戶端請求的 key 不在當前節點時,Redis 返回 MOVED 重定向錯誤,引導客戶端訪問正確節點。


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

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

相關文章

基本的DOS命令

一.打開CMD方式: winR 輸入cmd 開始系統命令提示符 在任意文件夾下,shift+鼠標右擊,在此處打開命令 資源管理器的地址欄前面輸入cmd 以管理員身份打開cmd:選擇以管理員方式運行 二.常用的Dos命令 #盤符切換 盤符…

深度剖析:架構評估的常用方法與應用

架構評估是確保系統架構滿足需求、性能和質量等方面要求的重要環節,以下是一些常見的架構評估方法的詳細介紹: 一、基于調查問卷或檢查表的評估方法 1.方法概述:該方法通過設計一系列針對性的問題或檢查項,形成問卷或檢查表&…

代碼隨想錄算法訓練營第十六天

LeetCode題目: 530. 二叉搜索樹的最小絕對差501. 二叉搜索樹中的眾數236. 二叉樹的最近公共祖先3272. 統計好整數的數目(每日一題) 其他: 今日總結 往期打卡 530. 二叉搜索樹的最小絕對差 跳轉: 530. 二叉搜索樹的最小絕對差 學習: 代碼隨想錄公開講解 問題: 給你一個二叉搜…

基于雙閉環PID控制器的永磁同步電機控制系統匝間故障Simulink仿真

歡迎微?關注“電擊小子程高興的MATLAB小屋”獲取巨額優惠 1.模型簡介 本仿真模型基于MATLAB/Simulink(版本MATLAB 2013Rb)軟件。建議采用matlab2013 Rb及以上版本打開。(若需要其他版本可聯系代為轉換,高于該版本的matlab均可正…

02-libVLC的視頻播放器:播放音視頻文件以及網絡流

libvlc_new(0, nullptr)功能:創建并初始化libVLC的核心實例,是使用所有libVLC功能的前提。 參數:第一個參數:參數數量(通常設為0)第二個參數:參數列表(通常為nullptr,表示使用默認配置)返回值:成功返回libvlc_instance_t*指針,失敗返回nullptr。注意事項:可通過參…

2025藍橋杯省賽C++B組解題思路

由于題面還沒出來,現在先口胡一下思路 填空題直接打表找規律或者亂搞一下就能出,從大題開始說。 1,題意: 給你一個數組,這個數組里有幾個數可以被一個連續遞增的數字區間求和得出 思路:詐騙題,顯…

防止郵件偽造的策略 SPF 介紹

SPF是Sender Policy Framework的縮寫,即發件人策略框架,是一種用于防止電子郵件偽造的技術,用來驗證發件人郵箱域名的真實性。以下是關于它的詳細說明: 1. 定義與作用 SPF是一種電子郵件驗證系統,它通過在域名的DNS記…

JavaScript Symbol與BigInt

目錄 Symbol類型 一、Symbol 的核心特性 1. 唯一性 2. 不可變性 3. 不可枚舉性 二、創建 Symbol 1. 基礎創建 2. 全局 Symbol 注冊表 三、Symbol 作為對象屬性 1. 定義 Symbol 屬性 2. 遍歷 Symbol 屬性 四、內置 Symbol 值 五、實際應用場景 1. 避免屬性名沖突 …

AI Agent工程師認證-學習筆記(3)——【多Agent】MetaGPT

學習鏈接:【多Agent】MetaGPT學習教程 源代碼鏈接(覺得很好,star一下):GitHub - 基于MetaGPT的多智能體入門與開發教程 MetaGPT鏈接:GitHub - MetaGPT 前期準備 1、獲取MetaGPT (1)使用pip獲取MetaGPT pip install metagpt==0.6.6#或者在國內加速安裝鏡像 #pip in…

【leetcode hot 100 416】分割等和子集

解法一:(動態規劃)①定義:dp[i]表示是否可以在nums找到元素之和為i,dp[sum/21] ②初始狀態:dp[0]true;dp[i]false ③狀態轉移方程:dp[i] dp[i] || dp[i - num]; class Solution {public boole…

高中數學聯賽模擬試題精選第2套幾何題(改編)

在 △ A B C \triangle ABC △ABC 中, 點 M M M 是邊 A C AC AC 的中點. 在線段 A M AM AM, C M CM CM 上分別取點 P P P, Q Q Q, 使得 P Q A C / 2 PQAC/2 PQAC/2. 設 △ A B Q \triangle ABQ △ABQ 的外接圓與邊 B C BC BC 相交于點 X X X, △ B C P \triangle …

UWB雙通道隧道人員定位方案

技術基礎:UWB(超寬帶技術) 定義:UWB(Ultra-Wideband)是一種通過納秒級窄脈沖傳輸數據的無線通信技術,占用500MHz以上的超寬頻段。 核心優勢: 高精度定位:時間分辨率極高&…

Linux 入門八:Linux 多進程

一、概述 1.1 什么是進程? 在 Linux 系統中,進程是程序的一次動態執行過程。程序是靜態的可執行文件,而進程是程序運行時的實例,系統會為其分配內存、CPU 時間片等資源。例如,輸入 ls 命令時,系統創建進程…

MTCNN 人臉識別

前言 此處介紹強大的 MTCNN 模塊,給出demo,展示MTCNN 的 OOP, 以及ROS利用 C 節點,命令行調用腳本執行實際工作的思路。 MTCNN Script import argparse import cv2 from mtcnn import MTCNN import osclass MTCNNProcessor:def…

01_核心系統下的技術原理解析

15年前,基本上國內的核心系統被C壟斷,基本上是IBM的那套東西,場景也是比價復雜,這里不再贅述,TPS太過于龐大,技術上確實比較復雜。為此我這里拋磚引玉,說下對應的支付系統: &#x…

Python 實現最小插件框架

文章目錄 Python 實現最小插件框架1. 基礎實現項目結構plugin_base.py - 插件基類plugins/hello.py - 示例插件1plugins/goodbye.py - 示例插件2main.py - 主程序 2. 更高級的特性擴展2.1 插件配置支持2.2 插件依賴管理2.3 插件熱加載 3. 使用 setuptools 的入口點發現插件3.1 …

電感詳解:定義、作用、分類與使用要點

一、電感的基本定義 電感(Inductor) 是由導線繞制而成的儲能元件,其核心特性是阻礙電流變化,將電能轉化為磁能存儲。 基本公式: 自感電動勢: E -L * (di/dt) (L:電感值&#xff0c…

運行一次性任務與定時任務

運行一次性任務與定時任務 文章目錄 運行一次性任務與定時任務[toc]一、使用Job運行一次性任務1.創建一次性任務2.測試一次性任務3.刪除Job 二、使用CronJob運行定時任務1.創建定時任務2.測試定時任務3.刪除CronJob 一、使用Job運行一次性任務 1.創建一次性任務 (…

對話記憶(Conversational Memory)

一、引言 在與大型語言模型(LLM)交互的場景中,對話記憶(Conversational Memory)指的是模型能夠在多輪對話中保留、檢索并利用先前上下文信息的能力。這一機制使得對話系統不再僅僅是“問答機”,而是能夠持…

【HD-RK3576-PI】VNC 遠程桌面連接

在當今數字化時代,高效便捷的操作方式是技術愛好者與專業人士的共同追求。對于使用 HD-RK3576-PI微型單板計算機的用戶而言,當面臨沒有顯示屏的場景時,如何實現遠程操作桌面系統呢?別擔心,VNC 遠程桌面連接將為你解決這…