深入解析 Redis Cluster 架構與實現(一)

#作者:stackofumbrella

文章目錄

  • Redis Cluster特點
  • Redis Cluster與其它集群模式的區別
    • 集群目標
    • 性能
    • hash tags
    • Mutli-key操作
    • Cluster Bus
    • 安全寫入(write safety)
    • 集群節點的屬性
    • 集群拓撲
    • 節點間handshake
    • 重定向與resharding
      • MOVED重定向
      • ASK重定向
      • 客戶端首次鏈接以及重定向處理

Redis Cluster特點

多主多從,去中心化:從節點作為備用,復制主節點,不做讀寫操作,不提供服務
不支持處理多個key:因為數據分散在多個節點,在數據量大高并發的情況下會影響性能

支持動態擴容節點:這算是Redis Cluster最大的優點之一
節點之間相互通信,相互選舉,不再依賴sentinel:準確來說是主節點之間相互監督,保證及時故障轉移

Redis Cluster與其它集群模式的區別

相比較sentinel模式,多個master節點保證主要業務(比如master節點主要負責寫)穩定性,不需要搭建多個sentinel實例監控一個master節點
,相比較一主多從的模式,具有自我故障檢測,故障轉移的特點
,相比較其他兩個模式而言,對數據進行分片(sharding),不同節點存儲的數據是不一樣的。從某種程度上來說,Sentinel模式主要針對高可用(HA),而Cluster模式是不僅針對大數據量,高并發,同時也支持HA。
Redis Cluster的實現機制和原理

集群目標

1)高性能和線性擴展,最大可以支撐到1000個節點,Cluster架構中無Proxy層,Master與slave之間使用異步replication,且不存在操作的merge(即操作不能跨多個nodes,不存在merge層)。

2)一定程度上保證writes的安全性,需要客戶端容忍一定程度的數據丟失。集群將會盡可能(best-effort)保存客戶端write操作的數據,通常在failover期間,會有短暫時間內的數據丟失(因為異步replication引起),當客戶端與少數節點處于網絡分區時(network partition),丟失數據的可能性會更高,因節點有效性檢測,failover需要更長的時間。

3)只要集群中大多數master可達、且失效的master至少有一個slave可達時,集群都可以繼續提供服務。同時replicas migration可以將那些擁有多個slaves的master的某個slave,遷移到沒有slave的master下,即將slaves的分布在整個集群相對平衡,盡力確保每個master都有一定數量的slave備份。Redis Cluster集群由多個shard組成,每個shard可以有一個master和多個slaves構成,數據根據hash slots配額分布在多個shard節點上,節點之間建立雙向TCP鏈接用于有效性檢測、Failover等,Client直接與shard節點進行通訊,集群暫不提供動態reblance策略。

性能

Redis Cluster并沒有提供Proxy層,而是告知客戶端將key的請求轉發給合適的node。Client保存集群中nodes與keys的映射關系(slots),并保持此數據的更新,所以通常Client總能夠將請求直接發送到正確的node上。因為采用異步replication,所以master不會等待slaves保存成功后才向客戶端反饋結果,除非顯式的指定了WAIT指令。multi-key指令僅限于單個節點內,除了resharding操作外,節點的數據不會在節點間遷移。每個操作只會在特定的一個節點上執行,所以集群的性能為master節點的線性擴展。同時Clients與每個node保持鏈接,所以請求的延遲等同于單個節點,即請求的延遲并不會因為Cluster的規模增大而受到影響。高性能和擴展性,同時保持合理的數據安全性,是Redis Cluster的設計目標。

hash tags

在計算hash slots時有一個意外的情況,用于支持“hash tags”,hash tags用于確保多個keys能夠被分配在同一個hash slot中,每個key都可以包含一個自定義的“tags”,那么在存儲時將根據tags計算此key應該分布在哪個node上(而不是使用key計算,但是存儲層面仍然是key)。此特性可以強制某些keys被保存在同一個節點上,用于支持multi-key操作。hash tags的實現比較簡單,key中“{}”之間的字符串就是當前key的hash tags,如果存在多個“{}”,首個符合規則的字符串作為hash tags,如果“{}”存在多級嵌套,那最內層首個完整的字符串作為hash tags,比如“{foo}.student”,那么“foo”是hash tags。如果key中存在合法的hash tags,那么在計算hash slots時,將使用hash tags,而不再使用原始的key,即“foo”與“{foo}.student”將得到相同的slot值,不過“{foo}.student”仍作為key來保存數據,即redis中數據的key仍為“{foo}.student”。

Mutli-key操作

Redis單實例支持的命令,Cluster也都支持,但是對于“multi-key”操作(即一次RPC調用需要進行多個key的操作)比如Set類型的交集、并集等,則要求這些key必須屬于同一個node。Cluster不能進行跨Node操作,也沒有node提供merge層代理。在人工對slots進行resharding期間,multi-key操作可能不可用。比如這些keys不存在于同一個slot(遷移會導致keys被分離)。比如Multikeys邏輯上屬于同一個slot,但是因為resharding,它們可能暫時不處于同一個node,有些可能在遷移的目標節點上(比如Multikeys包含a、b、c三個keys,邏輯上它們都屬于slot 8,但是其中c在遷移期間創建,它被存儲在節點B上,a、b仍然在節點A),此時將會向客戶端返回“-
TRYAGAIN”錯誤,那么客戶端此后將需要重試一次,或者直接返回錯誤(如果遷移操作被中斷),無論如何最終Multikeys的訪問邏輯是一致的,slots的狀態也是最終確定的。

Cluster Bus

集群中node負責存儲數據,保持集群的狀態,包括keys與node的對應關系(內部其實為slots與node對應關系)。node也能夠自動發現其他的node,檢測失效的節點,當某個master失效時還能將合適的slave提升為master。為了達成這些行為,集群中的每個節點都通過TCP與其他所有node建立連接,它們之間的通信協議和方式稱為“Redis Cluster Bus”。 每個Node都有一個特定的TCP端口,用來接收其他nodes的鏈接,此端口號為面向Client的端口號+10000,比如客戶端端口號為6379,那么node的Bus端口號為16379,客戶端端口號可以在配置文件中聲明。由此可見,node之間的交互通訊是通過Bus端口進行,使用gossip協議向其他node傳播集群信息,以達到自動發現的特性,通過發送ping來確認其他node工作正常,也會在合適的時機發送集群信息。當然在Failover時(包括人為failover)也會使用Bus來傳播消息。

gossip最終一致性,分布式服務數據同步算法,node首先需要知道(可以讀取配置)集群中至少一個seed node,此node向seed發送ping請求,此時seed節點pong返回自己已知的所有node列表,然后node解析列表并與它們都建立tcp連接,同時也會向每個node發送ping,并從它們的pong結果中merge出全局node列表,并逐步與所有的node建立連接,數據傳輸的方式也是類似,網絡拓撲結構為full mesh。

安全寫入(write safety)

在Master-slaves之間使用異步replication機制,在failover之后,新的Master將會最終替代舊的master。在出現網絡分區時(network partition),總會有個窗口期(node timeout)可能會導致數據丟失。不過,Client與多數派Master、少數派Master處于一個分區(網絡分區,因為網絡阻斷問題,導致Clients與Nodes被隔離成兩部分)時,這兩種情況下影響并不相同。

1)write提交到master,master執行完畢后向Client反饋“OK”,不過此時可能數據還沒有傳播給slaves(異步replication),如果此時master不可達的時間超過閥值(node timeout),那么將觸發slave被選舉為新的Master(即Failover),這意味著那些沒有replication到slaves的writes將永遠丟失了。

2)還有一種情況導致數據丟失:

A)因為網絡分區,此時master不可達,且Master與Client處于一個分區,且是少數派分區;

B)Failover機制,將其中一個slave提升為新Master;

C)此后網絡分區消除,舊的Master再次可達,此時它將被切換成slave;

D)那么在網絡分區期間,處于少數派分區的Client仍然將write提交到舊的Master,因為它們覺得Master仍然有效,當舊的Master再次加入集群,切換成slave之后,這些數據將永遠丟失。

在第二種情況下,如果Master無法與其他大多數Masters通訊的時間超過閥值后,此Master也將不再接收Writes,自動切換為readonly狀態。當網絡分區消除后,仍然會有一小段時間,客戶端的write請求被拒絕,因為此時舊的Master需要更新本地的集群狀態、與其他節點建立連接、角色切換為slave等等,同時Client端的路由信息也需要更新。只有當此master與大多數其他master不可達的時間達到閥值時,才會觸發Failover,這個時間稱為NODE_TIMEOUT,可以通過配置設定。所以當網絡分區在此時間內被消除的話,writes不會有任何丟失。反之,如果網絡分區持續時間超過此值,處于“小分區”(minority)端的Master將會切換為readonly狀態,拒絕客戶端繼續提交writes請求,那么“大分區”端將會進行failover,這意味著NODE_TIMEOUT期間發生在“小分區”端的writes操作將丟失。

集群節點的屬性

集群中每個節點都有唯一的名字,稱之為node ID,一個160位隨機數字的16進制表示,在每個節點首次啟動時創建。每個節點都將各自的ID保存在實例的配置文件中,此后將一直使用此ID,或者說只要配置文件不被刪除,或者沒有使用“CLUSTER RESET”指令重置集群,那么此ID將永不會修改。集群通過node ID來標識節點,而不是使用IP + port,因為node可以修改它的IP和port,如果ID不變,仍然認定它是集群中合法一員。集群可以在
cluster bus中通過gossip協議來探測IP、Port的變更,并重新配置。

node ID并不是與node相關的唯一信息,不過是唯一一個全局一致的。每個node還持有如下相關的信息,有些信息是關系集群配置的,其他的信息比如最后ping時間等。每個node也保存其他節點的IP、Port、flags(比如flags表示它是master還是slave)、最近ping的時間、最近pong接收時間、當前配置的epoch、鏈接的狀態,最重要的是還包含此node上持有的hash slots。這些信息均可通過“CLUSTER NODES”指令開查看。

集群拓撲

Redis Cluster中每個node都與其他node的Bus端口建立TCP鏈接(full mesh,全網)。比如在有N個節點的集群中,每個node有N-1個向外發出的TCP鏈接,以及N-1個其他node發過來的TCP鏈接。這些TCP鏈接總是keepalive,不是按需創建的。如果ping發出之后,node在足夠長的時間內仍然沒有pong響應,那么此node將會被標記為“不可達”,那么與此node的鏈接將會被刷新或者重建。Nodes之間通過gossip協議和配置更新的機制,來避免每次都交互大量的消息,最終確保在nodes之間的信息傳送量是可控的。

節點間handshake

Nodes通過Bus端口發送ping、pong,如果一個節點不屬于集群,那么它的消息將會被其他node全部丟棄。一個節點被認為是集群成員的方式有2種:

1)如果此node在“Cluster meet”指令中引入,此命令的主要意義就是將指定node加入集群。那么對于當前節點,將認為指定的node為“可信任的”(此后將會通過gossip協議傳播給其他node)。

2)當其他node通過gossip引入了新的node,這些node也是被認為是“可信任的”。

只要將一個節點加入集群,最終此節點將會與其他節點建立鏈接,即cluster可以通過信息交換來自動發現新的節點,鏈接拓撲仍然是full mesh。

重定向與resharding

MOVED重定向

因為redis并不提供Proxy機制,當Client將請求發給錯誤的node時(此node上不存在此key所屬的slot),node將會反饋“MOVED”或“ASK”錯誤信息,以便Client重新定向到合適的node。理論上,Client可以將請求隨意發給任何一個node,包括slaves,此node解析query,如果可以執行(比如語法正確,multiple keys都應該在一個node slots上),它會查看key應該屬于哪個slot、以及此slot所在的node,如果當前node持有此slot,那么query直接執行即可,否則當前node將會向Client反饋“MOVED”錯誤。錯誤信息中包括此key對應的slot(3999),以及此slot所在node的ip和port,對于Client 而言,收到MOVED信息后,它需要將請求重新發給指定的node。不過,當node向Client返回MOVED之前,集群的配置也在變更(節點調整、resharding、failover等,可能會導致slot的位置發生變更),此時Client可能需要等待更長的時間,不過最終node會反饋MOVED信息,且信息中包含指定的新的node位置。雖然Cluster使用ID標識node,但是在MOVED信息中盡可能的暴露給客戶端便于使用的ip + port。

當Client遇到“MOVED”錯誤時,將會使用“CLUSTER NODES”或“CLUSTER SLOTS”指令獲取集群的最新信息,主要是nodes與slots的映射關系。因為遇到MOVED,一般也不會僅僅一個slot發生的變更,通常是一個或者多個節點的slots發生了變化,所以進行一次全局刷新是有必要的。Client將會把集群的這些信息緩存,以便提高query的性能。還有一個錯誤信息“ASK”,它與“MOVED”都屬于重定向錯誤,客戶端的處理機制基本相同,只是ASK不會觸發Client刷新本地的集群信息。

ASK重定向

MOVED重定向與ASK非常相似。在resharding期間,為什么不能用MOVED?MOVED意思為hash slots已經永久被另一個node接管,接下來相應的查詢應該與它交互,ASK的意思是當前query暫時與指定的node交互。在遷移期間,slot 8的keys有可能仍在A上,所以Client的請求仍然需要首先經由A,對于A上不存在的,才需要到B上進行嘗試。遷移期間,Redis Cluster并沒有粗暴的將slot 8的請求全部阻塞直到遷移結束,這種方式盡管不再需要ASK,但是會影響集群的可用性。

1)當Client接收到ASK重定向,它僅僅將當前query重定向到指定的node,此后的請求仍然交付給舊的節點。

2)客戶端并不會更新本地的slots映射,仍然保持slot 8與A的映射,直到集群遷移完畢,且遇到MOVED重定向。一旦slot 8遷移完畢之后(集群的映射信息也已更新),如果Client再次在A上訪問slot 8時,將會得到MOVED重定向信息,此后客戶端也更新本地的集群映射信息。

客戶端首次鏈接以及重定向處理

可能有些Cluster客戶端的實現,不會在內存中保存slots映射關系(即node與slots的關系),每次請求都從聲明的、已知的node中,隨機訪問一個node,并根據重定向(MOVED)信息來尋找合適的node,這種訪問模式,通常是非常低效的。當然,Client應該盡可能的將slots配置信息緩存在本地,不過配置信息也不需要絕對的實時更新,因為在請求時偶爾出現“重定向”,Client也能兼容此次請求的正確轉發,此時再更新slots配置,所以Client通常不需要間歇性的檢測Cluster中配置信息是否已經更新,客戶端通常是全量更新slots配置:

1)首次鏈接到集群的某個節點;

2)當遇到MOVED重定向消息時。

遇到MOVED時,客戶端僅僅更新特定的slot是不夠的,因為集群中的reshard通常會影響到多個slots。客戶端通過向任意一個node發送“CLUSTER NODES”或“CLUSTER SLOTS”指令均可以獲得當前集群最新的slots映射信息,“CLUSTER SLOTS”指令返回的信息更易于Client解析。如果集群處于broken狀態,即某些slots尚未被任何nodes覆蓋,指令返回的結果可能是不完整的。

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

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

相關文章

linux centos 服務器性能排查 vmstat、top等常用指令

背景:項目上經常出現系統運行緩慢,由于數據庫服務器是linux服務器,記錄下linux服務器性能排查常用指令 vmstat vmstat介紹 vmstat 命令報告關于內核線程、虛擬內存、磁盤、陷阱和 CPU 活動的統計信息。由 vmstat 命令生成的報告可以用于平衡系統負載活動。系統范圍內的這…

在IIS上無法使用PUT等請求

錯誤來源: chat:1 Access to XMLHttpRequest at http://101.126.139.3:11000/api/receiver/message from origin http://101.126.139.3 has been blocked by CORS policy: No Access-Control-Allow-Origin header is present on the requested resource. 其實我的后…

Python訓練第四十一天

DAY 41 簡單CNN 知識回顧 數據增強卷積神經網絡定義的寫法batch歸一化:調整一個批次的分布,常用與圖像數據特征圖:只有卷積操作輸出的才叫特征圖調度器:直接修改基礎學習率 卷積操作常見流程如下: 1. 輸入 → 卷積層 →…

Linux線程同步實戰:多線程程序的同步與調度

個人主頁:chian-ocean 文章專欄-Linux Linux線程同步實戰:多線程程序的同步與調度 個人主頁:chian-ocean文章專欄-Linux 前言:為什么要實現線程同步線程饑餓(Thread Starvation)示例:搶票問題 …

5.2 初識Spark Streaming

在本節實戰中,我們初步探索了Spark Streaming,它是Spark的流式數據處理子框架,具備高吞吐量、可伸縮性和強容錯能力。我們了解了Spark Streaming的基本概念和運行原理,并通過兩個案例演示了如何利用Spark Streaming實現詞頻統計。…

Go 即時通訊系統:日志模塊重構,并從main函數開始

重構logger 上次寫的logger.go過于繁瑣,有很多沒用到的功能;重構后只提供了簡潔的日志接口,支持日志輪轉、多級別日志記錄等功能,并采用單例模式確保全局只有一個日志實例 全局變量 var (once sync.Once // 用于實現…

「數據采集與網絡爬蟲(使用Python工具)」【數據分析全棧攻略:爬蟲+處理+可視化+報告】

- 第 103 篇 - Date: 2025 - 06 - 01 Author: 鄭龍浩/仟墨 文章目錄 「據采集與網絡爬蟲」【使用工具:Python】一 數據采集1 數據采集綜述(1)基本介紹(2)數據目標源(3)采集方式(4&am…

響應式系統與Spring Boot響應式應用開發

響應式系統概述 過去十年間,為應對移動和云計算的需求,軟件行業通過改進開發流程來構建更穩定、健壯且靈活的軟件系統。這種演進不僅服務于傳統用戶端(桌面/Web),還需支持多樣化設備(手機、傳感器等)。為應對這些挑戰,多個組織共同制定了《響應式宣言》(2014年發布)…

POJO、DTO和VO:Java應用中的三種關鍵對象詳解

在軟件開發特別是Java開發中,常常會遇到POJO、DTO和VO這三類對象。它們在不同場景下扮演著重要角色,有助于優化代碼結構、增強系統安全性和提升性能。本文將全面解析這三者的定義、區別及常見使用場景,幫助你更好地理解和應用。 1. POJO&…

leetcode付費題 353. 貪吃蛇游戲解題思路

貪吃蛇游戲試玩:https://patorjk.com/games/snake/ 問題描述 設計一個貪吃蛇游戲,要求實現以下功能: 初始化游戲:給定網格寬度、高度和食物位置序列移動操作:根據指令(上、下、左、右)移動蛇頭規則: 蛇頭碰到邊界或自身身體時游戲結束(返回-1)吃到食物時蛇身長度增加…

NLP學習路線圖(十三):正則表達式

在自然語言處理(NLP)的浩瀚宇宙中,原始文本數據如同未經雕琢的璞玉。而文本預處理,尤其是其中至關重要的正則表達式技術,正是將這塊璞玉轉化為精美玉器的核心工具集。本文將深入探討正則表達式在NLP文本預處理中的原理…

計算機網絡(4)——網絡層

1.概述 1.1 網絡層服務 (1) 網絡層為不同主機(Host)之間提供了一種邏輯通信機制 (2)每個主機和路由器都運行網絡層協議 發送方:將來自傳輸層的消息封裝到數據報(datagram)中接收方:向傳輸層交付數據段(segment) 1.2 網絡層核心功能 路由選擇(routing…

EMO2:基于末端執行器引導的音頻驅動虛擬形象視頻生成

今天帶來EMO2(全稱End-Effector Guided Audio-Driven Avatar Video Generation)是阿里巴巴智能計算研究院研發的創新型音頻驅動視頻生成技術。該技術通過結合音頻輸入和靜態人像照片,生成高度逼真且富有表現力的動態視頻內容,值得…

[Redis] Redis:高性能內存數據庫與分布式架構設計

標題:[Redis] 淺談分布式系統 水墨不寫bug 文章目錄 一、什么是Redis?一、核心定位二、核心優勢三、典型應用場景四、Redis vs 傳統數據庫 二、架構選擇與設計1、單機架構(應用程序 數據庫服務器)2、應用程序和數據庫服務器分離3…

HTML5 視頻播放器:從基礎到進階的實現指南

在現代Web開發中,視頻播放功能是許多網站的重要組成部分。無論是在線教育平臺、視頻分享網站,還是企業官網,HTML5視頻播放器都扮演著不可或缺的角色。本文將從基礎到進階,詳細介紹如何實現一個功能完善的HTML5視頻播放器&#xff…

牛客小白月賽117

前言:solveABCF相對簡單,D題思路簡單但是實現麻煩,F題郭老師神力b( ̄▽ ̄)。 A. 好字符串 題目大意:給定字符串s,里面的字母必須大小寫同時出現。 【解題】:沒什么好說的&#xff0…

特倫斯 S75 電鋼琴:重構演奏美學的極致表達

在數字音樂時代,電鋼琴正從功能性樂器升級為融合藝術、科技與生活的美學載體。特倫斯 S75 電鋼琴以極簡主義哲學重構產品設計,將專業級演奏體驗與現代家居美學深度融合,為音樂愛好者打造跨越技術邊界的沉浸式藝術空間。 一、極簡主義的視覺敘…

GpuGeek 618大促引爆AI開發新體驗

隨著生成式AI技術迅猛發展,高效可靠的算力資源已成為企業和開發者突破創新瓶頸的戰略支點。根據賽迪顧問最新發布的《2025中國AI Infra平臺市場發展研究報告》顯示,2025年中國生成式人工智能企業應用市場規模將達到629.0億元,作為AI企業級應用…

第二十章 文本處理

第二十章 文本處理 所有類UNIX系統都嚴重依賴于文本文件來存儲數據,所以存在大量文本操作工具也在情理之中。 相關命令: cat:拼接文件。sort:排序文本行。uniq:報告或忽略重復的行。cut:從每行中刪除部分內容。past…

Reactor 和 Preactor

Reactor 和 Preactor 是兩個在工業控制、生產調度和事件驅動系統中非常重要的設計模式或框架,不少人會用這兩個名詞來描述不同的編程思想或技術架構。 一、Reactor 模式(反應器模式) 1. 概述 Reactor 模式其實是一種I/O事件通知的設計思想…