主頁 > 軟體設計 > Redis主從復制搭建及原理

Redis主從復制搭建及原理

2022-02-27 07:31:09 軟體設計

1 簡介

1.1 Redis在單機、單節點、單實體下存在的問題

  • 單機故障
  • 記憶體容量有限
  • 訪問壓力
    Redis主從架構主要解決的問題:單機故障和訪問壓力,通過主從架構可以將訪問流量分攤到多臺服務器上,加上哨兵機制實作主從架構的高可用,主從架構將主節點資料復制到從節點即資料的冗余備份原理,所以不能解決記憶體容量的問題,記憶體容量可以通過Redis集群解決

1.2 主從架構概述

主從復制,是指將一臺 Redis 服務器的資料(master 主節點),復制到其他的 Redis 服務器( slave 從節點),資料的復制是單向的,只能由主節點到從節點
默認情況下,每臺 redis 服務器都是主節點,且一個主節點可以有多個從節點,但一個從節點只能有一個主節點,

1.3 主從復制作用

  1. 資料冗余:主從復制實作了資料的熱備份,是持久化之外的一種資料冗余方式;
  2. 故障恢復:當主節點出現問題時,可以由從節點提供服務,實作快速的故障恢復;實際上是一種服務的冗余,
  3. 負載均衡:在主從復制的基礎上,配合讀寫分離,寫資料時應用連接主節點,讀資料時應用連接從節點,分擔服務器負載;尤其是在寫少讀多的場景下,通過多個從節點分擔讀負載,可以大大提高 Redis 服務器的并發量,
  4. 高可用:主從復制是哨兵模式和集群能夠實施的基礎,

2 主從復制實作

2.1 環境準備

  1. CentOS7 3臺
  • 192.168.88.110 埠6379 主機名q110(下面統一簡稱為主機名)
  • 192.168.88.111 埠6379 主機名q111(下面統一簡稱為主機名)
  • 192.168.88.112 埠6379 主機名q112(下面統一簡稱為主機名)
  1. Redis-6.2.6

2.2 網路拓撲圖

2.3 Redis安裝

3臺服務器安裝Redis6.2.6
官網
中文
Redis安裝包解壓完成后,詳細安裝目錄可以查看README.md

# 1. 安裝gcc
yum install gcc
# 2. 下載安裝包
wget https://download.redis.io/releases/redis-6.2.6.tar.gz
tar -xf redis-6.2.6.tar.gz
# 3. 編譯 
cd redis-6.2.6 && make
cd src && make install PREFIX=/usr/local/redis
# 4. 配置環境變數
vi /etc/profile
# 添加環境變數
export REDIS_HOME=/usr/local/redis
export PATH=$PATH:$REDIS_HOME/bin

source /etc/profile
# 5. 根據Redis官方提供的腳本一鍵安裝
cd ../../redis-6.2.6/utils
./install_server.sh

運行第5步報錯,錯誤資訊如下:

注釋掉install_server.sh 中報錯部分后重新執行install_server.sh

# 可執行多次,物理機中可以有多個Redis實體,通過port區分
./install_server.sh
# 根據提示內容按需修改,不修改直接回車確認

執行完成后redis實體默認已啟動,配置及日志檔案路徑上圖也有輸出,

2.4 配置主從復制

從節點開啟主從配置,有 3 種方式:

  1. 組態檔:在組態檔加入 slave < masterip > < masterport >
  2. 啟動命令:redis-server 啟動命令后加入 --slave < masterip > < masterport >
  3. 客戶端命令:Redis 服務器啟動后,直接通過客戶端執行命令:slave < masterip > < masterport >

本文通過常用的組態檔加入,
Master節點修改配置:
修改/etc/redis/6379.conf 中的bind,默認只能本機訪問,需添加2臺salve 節點ip,
Slave節點修改:
修改q111和q112兩臺都需要修改

  1. 修改/etc/redis/6379.conf 中的bind,默認只能本機訪問,需添加2臺salve 節點ip,
    bind 192.168.88.100
  2. 配置主節點IP和埠
vi /etc/redis/6379.conf 
# 修改,如果主節點存在用戶名和密碼也需要配置上
replicaof 192.168.88.110 6379

重啟3臺從redis服務

systemctl restart redis_6379

驗證
通過查看Master Redis日志可以看到已經將RDB同步到磁盤并發送給Salve節點,

查看Slave Redis日志可以看到已經從Master節點將RDB同步到磁盤

注意: Slave在同步Master節點RDB資料時會先洗掉自己的RDB檔案,
通過客戶端連接后在Master節點set 一個key 后 在Slave節點get 該key可以看到資料已經同步,
q112

q111

至此,主從復制已配置完畢,目前主從配置存在疑問:
當Slave down掉后,重新啟動,是從Master從新拉全全量RDB還是增量資料?

3 主從資料同步原理

3.1 測驗資料同步

3.1.1 Slave與Master首次建立主從

首次建立主從會全量同步,可查看2.4日志,

3.1.2 建立主從后Slave斷開一段時間后重新啟動

從上面2.4測驗可以看到當Slave跟隨Master時,會將RDB檔案同步并清除自己所有資料,重新加載Master的RDB資料,我們可以在Slave已經與Master建立好主從關系后(資料已經同步)再將Slave關掉,在Slave關閉期間,往Master中添加資料,然后再重新啟動Slave,
查看Slave啟動日志:

查看RDB源檔案

從Slave RDB源檔案中可以看到,已經有保存repla-id 即MasterID,從日志中可以看到,當Slave在與Master已經建立主從關系情況下,宕機重啟后并不會將Master資料全量同步,這與首次建立主從關系有不同,

3.1.3 測驗AOF開啟

上面的測驗3.1.2 可以看出可能是因為RDB中已經存在了Master repla-id所有再次啟動時不會全量同步,我們再測下將Slave開啟AOF開啟后,同樣在關閉Slave期間Master增加資料后再啟動Slave,

  1. 主機q112中執行
# 關閉Redis
systemctl stop redis_6379
# 修改配置
vi /etc/redis/6379.conf
# 開啟AOF,組態檔中修改以下內容
appendonly yes

  1. Master中增加一些資料
  2. 重啟Slave查看啟動日志

通過日志中可以看在,在已經與Master建立了主從情況下并且開啟AOF后,重新啟動也會將全量資料同步到本地及記憶體,為了確實是否是第一次開啟AOF才會全量同步,可以將此2.5.2實驗再重試一次,得到的結論是一樣的即:Redis主從中Slave開啟AOF后每次重啟會加載Master全量資料,里面具體原理是什么呢?

3.2 主從復制原理

3.2.1 資料同步原理

從節點通過發送psync命令請求同步資料,此時根據主從節點當前狀態的不同,同步方式可能是全量復制或部分復制,

  • 全量復制:用于初次復制或其他無法進行部分復制的情況,將主節點中的所有資料都發送給從節點,是一個非常重型的操作,如果從節點開啟了AOF,則會觸發bgrewriteaof的執行,從而保證AOF檔案更新至主節點的最新狀態;
  • 部分復制:用于網路中斷等情況后的復制,只將中斷期間主節點執行的寫命令發送給從節點,與全量復制相比更加高效,需要注意的是,如果網路中斷時間過長,導致主節點沒有能夠完整地保存中斷期間執行的寫命令,則無法進行部分復制,仍使用全量復制,

Redis使用一對Replicaion ID, offset來唯一識別Master節點資料集的版本,要理解這個“版本“的概念需要認識Redis的以下三個概念:

  • Replication ID(復制ID):每個Redis的主節點都用一個隨機生成的字串來表示在某一時刻其內部存盤資料的狀態,“某一時刻”可以理解為其成為master角色的那一刻,由原始碼可知在第一個從節點加入時,Redis初始化了復制ID,
  • offset(復制偏移量):主從模式下,主節點會持續不斷的向從節點傳播引起資料集更改的命令,offset所表示的是主節點向從節點傳遞命令位元組總數,它不是孤立存在的,需要配合復制積壓緩沖區才能作業,
  • backlog(復制積壓緩沖區):它是一個環形緩沖區,用來存盤主節點向從節點傳遞的命令,它的大小是固定的,可存盤的命令有限,超出部分將會被洗掉,它即可用于部分同步,也可用于命令傳播階段的命令重推,

上圖說明:

  • 圖示Redis角色為Master,其復制ID(replid)為xxxx,當前的復制偏移量(offset)為1010;
  • 它有一個復制積壓緩沖區(backlog),容量(backlog_size)為100,backlog起點相對于offset的偏移量(backlog_off)為1000,當前backlog存盤的命令位元組數(backlog_hislen)為11個,對應了backlog中【1000,1010】偏移量范圍內的位元組;
  • offset始終與backlog中最后一個位元組的偏移量相同,
    上圖分析:
  • Redis-1:replid和offset為默認值,說明它從未與主節點進行過同步操作,所以是進行全量同步;
  • Redis-2:replid主從節點一致,slave_offset>=backlog_off并且slave_offset<offset,說明該從節點丟失的資料可以通過復制積壓緩沖區找回,所以可以進行部分同步;
  • Redis-3:replid主從節點一致,slave_offset<backlog_off,說明該節點丟失的資料過多,通過復制積壓緩沖區無法找回,所以是進行全量同步;
  • Redis-4:replid主從節點一致,之前不是與當前節點進行主從復制,所以是進行全量同步;
    總結:部分同步其實是以全量同步為基礎(得到復制ID),用復制積壓緩沖區中的快取命令做命令重放的增量同步邏輯,不過受制于復制積壓緩沖區的容量,它可容忍的范圍是有限的,這與持久化機制的AOF混合持久化如出一轍,也與mysql中主從復制的Binlog思路不謀而合,

3.2.2 命令的執行

Master-Slave建立主從關系后,當Master執行完寫操作命令后,會通過psync把寫命令追加至復制積壓緩沖區,然后異步地發送給slave,slave接收命令并執行,同時更新slave維護的復制偏移量offset,

復制積壓緩沖區是由主節點維護的、固定長度的、先進先出(FIFO)佇列,默認大小1MB(通過配置repl-backlog-size),例如如果網路中斷的平均時間是60s,而主節點平均每秒產生的寫命令(特定協議格式)所占的位元組數為100KB,則復制積壓緩沖區的平均需求為6MB,保險起見,可以設定為12MB,來保證絕大多數斷線情況都可以使用部分復制,
從節點將offset發送給主節點后,主節點根據offset和緩沖區大小決定能否執行部分復制:

  • 如果offset偏移量之后的資料,仍然都在復制積壓緩沖區里,則執行部分復制;
  • 如果offset偏移量之后的資料已不在復制積壓緩沖區中(資料已被擠出),則執行全量復制,

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

標籤:其他

上一篇:Docker搭建Redis Cluster集群及擴容和收容

下一篇:Redis集群原理及搭建(Twemproxy、Predixy代理搭建、Redis Cluster集群)

標籤雲
其他(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