主頁 > 軟體設計 > redis(19):集群之復制原理

redis(19):集群之復制原理

2021-03-03 16:58:21 軟體設計

作為一個小型專案,使用一臺 Redis 服務器已經非常足夠了,然而現實中的 專案通常需要若干臺Redis服務器的支持:

  1. 從結構上,單個 Redis 服務器會發生單點故障,同時一臺服務器需要承受所有的請求負載,這就需要為資料生成多個副本并分配在不同的服務器上;
  2. 從容量上,單個 Redis 服務器的記憶體非常容易成為存盤瓶頸,所以需要進行資料分 片,

同時擁有多個 Redis 服務器后就會面臨如何管理集群的問題,包括如何增加節點、故障 恢復等操作, 為此,本章將依次詳細介紹 Redis 中的復制、哨兵(sentinel)和集群(cluster)的使用 和原理,

一、概述

通過持久化功能,Redis保證了即使在服務器重啟的情況下也不會損失(或少量損失)數 據,但是由于資料是存盤在一臺服務器上的,如果這臺服務器出現硬碟故障等問題,也會導 致資料丟失,為了避免單點故障,通常的做法是將資料庫復制多個副本以部署在不同的服務 器上,這樣即使有一臺服務器出現故障,其他服務器依然可以繼續提供服務,

為此, Redis 提供了復制(replication)功能,可以實作當一臺資料庫中的資料更新后,自動將更新的資料 同步到其他資料庫上,


二、配置

在復制的概念中,資料庫分為兩類,一類是主資料庫(master),另一類是從資料庫(slave)

主資料庫可以進行讀寫操作,當寫操作導致資料變化時會自動將資料同步給從數 據庫,

而從資料庫一般是只讀的,并接受主資料庫同步過來的資料,一個主資料庫可以擁有 多個從資料庫,而一個從資料庫只能擁有一個主資料庫

在這里插入圖片描述
在 Redis 中使用復制功能非常容易,只需要在從資料庫的組態檔中加入“slaveof 主數 據庫地址 主資料庫埠”即可,主資料庫無需進行任何配置,


三、原理

Redis實作復制的程序:
當一個從資料庫啟動后,會向主資料庫發sync命令,主資料庫收到sync命令開始在后臺保存快照(即RDB持久化的程序)并將保存快照期間收到的命令快取起來,當快照完成后,redis會將快照檔案和所有的快取命令發送給從資料庫,從資料庫收到后,會載入快照檔案并執行收到的快取的命令,

在這里插入圖片描述

上面程序稱為復制初始化,,復制初始化結束 后,主資料庫每當收到寫命令時就會將命令同步給從資料庫,從而保證主從資料庫資料一 致,

當主從資料庫之間的連接斷開重連后,Redis 2.6以及之前的版本會重新進行復制初始化 (即主資料庫重新保存快照并傳送給從資料庫),即使從資料庫可以僅有幾條命令沒有收到,主資料庫也必須要將資料庫里的所有資料重新傳送給從資料庫,這使得主從資料庫斷線 重連后的資料恢復程序效率很低下,在網路環境不好的時候這一問題尤其明顯,Redis 2.8版 的一個重要改進就是斷線重連能夠支持有條件的增量資料傳輸,當從資料庫重新連接上主數 據庫后,主資料庫只需要將斷線期間執行的命令傳送給從資料庫,從而大大提高Redis復制的 實用性,


四、圖結構

從資料庫不僅可以接收主資料庫的同步資料,自己也可以同時作為主資料庫存在,形成 類似圖的結構,如圖所示,資料庫A的資料會同步到B和C中,而B中的資料會同步到D和E 中,向B中寫入資料不會同步到A或C中,只會同步到D和E中,

在這里插入圖片描述


五、讀寫分離與一致性

通過復制可以實作讀寫分離,以提高服務器的負載能力,在常見的場景中(如電子商務 網站),讀的頻率大于寫,當單機的Redis無法應付大量的讀請求時(尤其是較耗資源的請
求,如 SORT 命令等)可以通過復制功能建立多個從資料庫節點,主資料庫只進行寫操作, 而從資料庫負責讀操作,這種一主多從的結構很適合讀多寫少的場景,而當單個的主資料庫 不能夠滿足需求時,就需要使用Redis 3.0 推出的集群功能,后續介紹;


六、從資料庫持久化

另一個相對耗時的操作是持久化,為了提高性能,可以通過復制功能建立一個(或若干個)從資料庫,并在從資料庫中啟用持久化,同時在主資料庫禁用持久化,當從資料庫崩潰重啟后主資料庫會自動將資料同步過來,所以無需擔心資料丟失,

然而當主資料庫崩潰時,情況就稍顯復雜了,手工通過從資料庫資料恢復主資料庫資料 時,需要嚴格按照以下兩步進行:

  1. 從資料庫中使用 SLAVEOF NO ONE命令將從資料庫提升成主資料庫繼續服務,
  2. 啟動之前崩潰的主資料庫,然后使用SLAVEOF命令將其設定成新的主資料庫的從 資料庫,即可將資料同步回來,

注意 當開啟復制且主資料庫關閉持久化功能時,一定不要使用 Supervisor 以及類似的行程管理工具令主資料庫崩潰后自動重啟,同樣當主資料庫所在的服務器因故關閉時,也要避免直接重新啟動,這是因為當主資料庫重新啟動后,因為沒有開啟持久化功能,所以資料庫 中所有資料都被清空,這時從資料庫依然會從主資料庫中接收資料,使得所有從資料庫也被 清空,導致從資料庫的持久化失去意義,
無論哪種情況,手工維護從資料庫或主資料庫的重啟以及資料恢復都相對麻煩,好在 Redis提供了一種自動化方案哨兵來實作這一程序,避免了手工維護的麻煩和容易出錯的問 題,


七、無硬碟復制

前面介紹Redis復制的作業原理時介紹了復制是基于RDB方式的持久化實作的,即主數 據庫端在后臺保存 RDB 快照,從資料庫端則接收并載入快照檔案,這樣的實作優點是可以 顯著地簡化邏輯,復用已有的代碼,但是缺點也很明顯,

  1. 當主資料庫禁用RDB快照時(即洗掉了所有的組態檔中的save陳述句),如果執行 了復制初始化操作,Redis依然會生成RDB快照,所以下次啟動后主資料庫會以該快斬訓復數 據,因為復制發生的時間不能確定,這使得恢復的資料可能是任何時間點的,
  2. 因為復制初始化時需要在硬碟中創建RDB快照檔案,所以如果硬碟性能很慢(如 網路硬碟)時這一程序會對性能產生影響,舉例來說,當使用 Redis 做快取系統時,因為不 需要持久化,所以服務器的硬碟讀寫速度可能較差,但是當該快取系統使用一主多從的集群 架構時,每次和從資料庫同步,Redis都會執行一次快照,同時對硬碟進行讀寫,導致性能降 低,

因此從2.8.18版本開始,Redis引入了無硬碟復制選項,開啟該選項時,Redis在與從資料 庫進行復制初始化時將不會將快照內容存盤到硬碟上,而是直接通過網路發送給從資料庫, 避免了硬碟的性能瓶頸,

目前無硬碟復制的功能還在試驗階段,可以在組態檔中使用如下配置來開啟該功能: repl-diskless-sync yes


八、增量復制

前面在介紹復制的原理時提到當主從資料庫連接斷開后,從資料庫會發送SYNC命令 來重新進行一次完整復制操作,這樣即使斷開期間資料庫的變化很小(甚至沒有),也需要 將資料庫中的所有資料重新快照并傳送一次,在正常的網路應用環境中,這種實作方式顯然 不太理想,Redis 2.8版相對2.6版的最重要的更新之一就是實作了主從斷線重連的情況下的增量復制,

增量復制是基于如下3點實作的.

  1. 從資料庫會存盤主資料庫的運行ID(run id),每個Redis 運行實體均會擁有一個 唯一的運行ID,每當實體重啟后,就會自動生成一個新的運行ID,
  2. 在復制同步階段,主資料庫每將一個命令傳送給從資料庫時,都會同時把該命令 存放到一個積壓佇列(backlog)中,并記錄下當前積壓佇列中存放的命令的偏移量范圍,
  3. 同時,從資料庫接收到主資料庫傳來的命令時,會記錄下該命令的偏移量,

這3點是實作增量復制的基礎,回到之前的主從通信流程,可以看到,當主從連接準 備就緒后,從資料庫會發送一條 SYNC 命令來告訴主資料庫可以開始把所有資料同步過來 了,而 2.8 版之后,不再發送 SYNC命令,取而代之的是發送 PSYNC,格式為“PSYNC主數 據庫的運行 ID 斷開前最新的命令偏移量”,主資料庫收到 PSYNC命令后,會執行以下判斷 來決定此次重連是否可以執行增量復制,

  1. 首先主資料庫會判斷從資料庫傳送來的運行ID是否和自己的運行ID相同,這一步 驟的意義在于確保從資料庫之前確實是和自己同步的,以免從資料庫拿到錯誤的資料(比如 主資料庫在斷線期間重啟過,會造成資料的不一致),
  2. 然后判斷從資料庫最后同步成功的命令偏移量是否在積壓佇列中,如果在則可以 執行增量復制,并將積壓佇列中相應的命令發送給從資料庫,

如果此次重連不滿足增量復制的條件,主資料庫會進行一次全部同步(即與Redis 2.6的 程序相同),
大部分情況下,增量復制的程序對開發者來說是完全透明的,開發者不需要關心增量復 制的具體細節,2.8 版本的主資料庫也可以正常地和舊版本的從資料庫同步(通過接收SYNC 命令),同樣 2.8 版本的從資料庫也可以與舊版本的主資料庫同步(通過發送 SYNC命 令),唯一需要開發者設定的就是積壓佇列的大小了,

積壓佇列在本質上是一個固定長度的回圈佇列,默認情況下積壓佇列的大小為 1 MB, 可以通過組態檔的repl-backlog-size選項來調整,很容易理解的是,積壓佇列越大,其允許 的主從資料庫斷線的時間就越長,根據主從資料庫之間的網路狀態,設定一個合理的積壓隊 列很重要,因為積壓佇列存盤的內容是命令本身,如 SET foo bar,所以估算積壓佇列的大小 只需要估計主從資料庫斷線的時間中主資料庫可能執行的命令的大小即可,
與積壓佇列相關的另一個配置選項是repl-backlog-ttl,即當所有從資料庫與主資料庫斷開 連接后,經過多久時間可以釋放積壓佇列的記憶體空間,默認時間是1小時,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/265448.html

標籤:其他

上一篇:【天工Godwork精品教程】任務二:匯入控制點、POS權重設定、連接點分布檢查、自由空三

下一篇:Linux執行緒的創建與回收

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more