Redis主從復制:告別單身Redis!

在這里插入圖片描述

目錄

    • 一、 為什么需要主從復制?🤔
    • 二、 如何搭建主從架構?
      • 前提條件?
      • 步驟
        • 📁 創建工作目錄
        • 📜 創建 Docker Compose 配置文件
        • 🚀 啟動所有 Redis
        • 🔍 驗證主從狀態
      • 💡 重要提示和后續改進
    • 三、 主從復制的數據同步原理是什么?
    • 四、 主從復制的優缺點是什么?
    • 五、 總結

🌟我的其他文章也講解的比較有趣😁,如果喜歡博主的講解方式,可以多多支持一下,感謝🤗!

🌟了解 緩存雪崩、穿透、擊穿 請看 : 緩存雪崩、穿透、擊穿:別讓你的數據庫“壓力山大”!

其他優質專欄: 【🎇SpringBoot】【🎉多線程】【🎨Redis】【?設計模式專欄(已完結)】…等

如果喜歡作者的講解方式,可以點贊收藏加關注,你的支持就是我的動力
?更多文章請看個人主頁: 碼熔burning


Redis主從復制,可以把它想象成一個“跟班”系統

  • Master (主節點):就是“大哥” ,所有的事情(寫數據📝、改數據??)都由他說了算,他手里有最新的、最全的信息(數據)。
  • Slave (從節點):就是“小弟”或“跟班” ,他們不直接干活(默認不能寫數據),主要任務就是時刻盯著大哥 👀,大哥做了什么,他們就跟著學(復制數據🔄),保持和大哥信息同步。
    在這里插入圖片描述

一、 為什么需要主從復制?🤔

主要有這么幾個原因:

  • a. 數據備份與高可用 (大哥萬一出事了 💀,有人頂上 💪)

    • 備份:小弟手里有大哥數據的完整副本 📑。萬一大哥突然“掛了”(服務器宕機、硬盤壞了),數據不會完全丟失,至少小弟那里還有一份。
    • 高可用:如果大哥真的出事了,我們可以快速“提拔”一個小弟當新大哥(這個過程叫“故障轉移”,通常需要配合哨兵模式或集群模式自動完成 ?),保證服務能快速恢復,不會停太久。
  • b. 讀寫分離,提升性能 (大哥太忙 🥵,小弟分擔點任務 🤝)

    • 在一個系統中,“讀”數據的操作往往比“寫”數據的操作多得多。
    • 如果所有讀寫請求都壓在大哥一個人身上,他可能會累垮(性能瓶頸 🏺)。
    • 有了小弟后,可以讓大哥專門處理“寫”請求和少量的“讀”請求,而把大量的“讀”請求分流給各個小弟去處理。這樣大家分工合作,整個系統的處理能力就上去了 🚀,響應速度也更快 ?。這就像大哥負責決策和發布命令,小弟們負責對外宣傳和解答疑問。
  • c. 負載均衡 (分攤壓力 ??)

    • 和讀寫分離類似,多個小弟可以分攤讀請求的壓力,避免所有讀請求都集中在一臺服務器上。

二、 如何搭建主從架構?

下面是使用一臺 Linux 服務器和 Docker 技術搭建 Redis 一主二從(Master-Slave)復制結構的步驟。我們將使用 Docker Compose 來簡化管理。

前提條件?

  1. 擁有一臺 Linux 服務器 🖥?。
  2. 服務器上已安裝 Docker 和 Docker Compose 🐳(這里就不演示了,自行查找教程安裝)。
  3. 安裝完成之后,使用 docker pull redis 來拉去最新的redis的鏡像。

步驟

📁 創建工作目錄

在你的服務器上選擇一個合適的位置,創建一個用于存放配置文件的目錄。

 mkdir redis-clustercd redis-cluster
📜 創建 Docker Compose 配置文件

redis-cluster 目錄下創建一個名為 docker-compose.yml 的文件,并填入以下內容:

services:redis-master:image: redis:latest # 或者指定具體版本, 如 redis:7.2container_name: redis-masterports:- "6379:6379" # 將主節點的 6379 端口映射到宿主機的 6379 端口networks:- redis-net# 可以添加 volumes 實現數據持久化 (可選) 💾# volumes:#   - ./master-data:/data#   - ./master-redis.conf:/usr/local/etc/redis/redis.conf # 如果需要自定義配置# command: redis-server /usr/local/etc/redis/redis.conf # 如果使用了自定義配置redis-slave1:image: redis:latestcontainer_name: redis-slave1ports:- "6380:6379" # 將第一個從節點的 6379 端口映射到宿主機的 6380 端口networks:- redis-netcommand: redis-server --slaveof redis-master 6379 # 🔑 指定主節點地址和端口depends_on:- redis-master # 確保主節點先啟動# 可以添加 volumes 實現數據持久化 (可選) 💾# volumes:#   - ./slave1-data:/data#   - ./slave1-redis.conf:/usr/local/etc/redis/redis.conf# command: redis-server /usr/local/etc/redis/redis.conf --slaveof redis-master 6379redis-slave2:image: redis:latestcontainer_name: redis-slave2ports:- "6381:6379" # 將第二個從節點的 6379 端口映射到宿主機的 6381 端口networks:- redis-netcommand: redis-server --slaveof redis-master 6379 # 🔑 指定主節點地址和端口depends_on:- redis-master # 確保主節點先啟動# 可以添加 volumes 實現數據持久化 (可選) 💾# volumes:#   - ./slave2-data:/data#   - ./slave2-redis.conf:/usr/local/etc/redis/redis.conf# command: redis-server /usr/local/etc/redis/redis.conf --slaveof redis-master 6379networks:redis-net:driver: bridge # 創建一個橋接網絡供容器間通信

配置說明:

  • services: 定義了三個服務(容器):redis-master, redis-slave1, redis-slave2
  • image: redis:latest: 指定使用最新的官方 Redis 鏡像。建議在生產環境中使用具體的版本號(如 redis:7.2)。
  • container_name: 為容器指定一個易于識別的名稱。
  • ports: 將容器的 6379 端口映射到宿主機的不同端口。redis-master 映射到 6379,redis-slave1 映射到 6380,redis-slave2 映射到 6381。這樣你可以在宿主機上通過不同端口訪問它們。
  • networks: - redis-net: 將所有容器連接到名為 redis-net 的自定義 Docker 網絡。這使得容器可以通過容器名稱(redis-master, redis-slave1, redis-slave2)相互通信。
  • command: redis-server --slaveof redis-master 6379 🔑: 這是關鍵配置。它告訴 redis-slave1redis-slave2 容器啟動時,連接到名為 redis-master 的容器的 6379 端口,并成為它的從節點。
  • depends_on: - redis-master: 確保從節點容器在主節點容器啟動之后再啟動。
  • networks: redis-net: driver: bridge: 定義了一個名為 redis-net 的自定義橋接網絡。
  • volumes (注釋掉的部分) 💾: 如果需要數據持久化(即使容器停止或刪除,數據也不會丟失),取消這些行的注釋。
    • ./master-data:/data:將宿主機當前目錄下的 master-data 文件夾掛載到 redis-master 容器內的 /data 目錄(Redis 默認數據存儲目錄)。你需要手動創建 master-data, slave1-data, slave2-data 目錄。
    • ./master-redis.conf:/usr/local/etc/redis/redis.conf:如果你需要更復雜的 Redis 配置(如設置密碼 requirepassmasterauth,修改 RDB/AOF 配置等),可以創建一個 redis.conf 文件,并將其掛載到容器內。如果掛載了自定義配置文件,通常需要修改 command 來指定加載該配置文件。
🚀 啟動所有 Redis

redis-cluster 目錄下(包含 docker-compose.yml 文件的目錄),運行以下命令:

# 啟動容器并在后臺運行
docker compose up -d
# 如果你的 docker compose 不是插件形式,可能是 docker-compose up -d

在這里插入圖片描述

Docker Compose 會根據 `docker-compose.yml` 文件創建并啟動三個 Redis 容器。`-d` 參數表示在后臺(detached mode)運行。
🔍 驗證主從狀態
  • 查看容器狀態:

    docker compose ps
    # 或者 docker ps
    

    在這里插入圖片描述

    你應該能看到 redis-master, redis-slave1, redis-slave2 三個容器正在運行 (State 為 Up)。?

  • 檢查主節點信息:
    連接到主節點容器并查看復制信息。

    docker exec -it redis-master redis-cli
    

    進入 redis-cli 后,輸入:

    INFO replication
    

    在這里插入圖片描述

    在輸出中查找:

    • role:master ?:確認它是主節點。
    • connected_slaves:2 ?:確認有兩個從節點連接。
    • 下面會列出兩個 slave 的信息(IP、端口、狀態等)。
  • 檢查從節點信息:
    連接到任意一個從節點容器(例如 redis-slave1)并查看復制信息。

    docker exec -it redis-slave1 redis-cli
    

    進入 redis-cli 后,輸入:

    INFO replication
    

    在這里插入圖片描述

    在輸出中查找:

    • role:slave ?:確認它是從節點。
    • master_host:redis-master ?:確認主節點的主機名正確。
    • master_port:6379 ?:確認主節點的端口正確。
    • master_link_status:up ?:確認與主節點的連接正常。
  • ?? 測試數據同步:

    1. 主節點 (redis-master) 的 redis-cli 中設置一個鍵值對:
      SET mykey "hello world from master! 👋"
      
      應該返回 OK
    2. 從節點 (redis-slave1redis-slave2) 的 redis-cli 中獲取這個鍵的值:
      GET mykey
      
      應該能成功返回 "hello world from master! 👋"。這表明數據已從主節點同步到從節點 🎉。
      在這里插入圖片描述

🛑 停止和清理 (如果需要):
如果你想停止并刪除這些容器、網絡,可以在 redis-cluster 目錄下運行:

docker compose down

如果使用了掛載卷(volumes)并且想刪除數據,可以添加 -v 選項:

docker compose down -v # 這個會把數據也刪掉哦,請小心!

💡 重要提示和后續改進

  • 數據持久化: 上面的示例默認沒有啟用持久化。對于生產環境,強烈建議通過掛載 volumes 💾 來持久化 /data 目錄,并可能需要配置 RDB 快照或 AOF 日志。
  • 安全性: 示例沒有設置密碼 🔑。在生產環境中,務必為主節點設置 requirepass,并為從節點設置 masterauth 來連接到需要密碼的主節點。這需要在自定義的 redis.conf 文件中配置,并通過 volumes 掛載進去,同時修改 command 以加載配置文件。
  • 高可用: 這個設置只是主從復制,如果主節點宕機 💥,從節點不會自動提升為主節點。你需要手動處理故障轉移,或者使用 Redis Sentinel(哨兵模式)或 Redis Cluster(集群模式)來實現自動故障轉移和更高可用性。
  • 資源限制: 在生產環境中,你可能需要為每個 Redis 容器設置 CPU 和內存限制 ??,以防止它們消耗過多服務器資源。這可以在 docker-compose.yml 文件的服務定義中通過 deploy -> resources -> limits 來配置。
  • 監控: 部署后,需要建立監控機制 📊 來跟蹤 Redis 實例的健康狀況、內存使用、連接數和復制延遲等。

這樣,你就成功地在一臺 Linux 服務器上使用 Docker 搭建了一個 Redis 一主二從的復制結構啦!👍


三、 主從復制的數據同步原理是什么?

這個過程分為兩個階段:

  • a. 首次連接/全量復制 (小弟剛入門,大哥先給一本完整的秘籍 📖)

    1. 握手 🤝:小弟啟動后,會主動向大哥發送一個 PSYNC (或者舊版的 SYNC) 命令,告訴大哥:“大哥,我是新來的(或者斷線重連的),我想跟你混,告訴我你的ID和現在的數據進度(偏移量)”。
    2. 大哥準備:大哥收到后,會執行一個 BGSAVE 命令,在后臺生成一個當前數據的快照(RDB文件)📸。這就像大哥把目前所有的武功秘籍復印一份。
    3. 緩沖命令 ?:在生成快照期間,大哥如果又收到了新的寫命令(比如又學了新招式),會先把這些新命令緩存起來,不立刻發給這個正在等待快照的小弟。
    4. 發送快照 📤📁:大哥把生成的RDB快照文件發給小弟。
    5. 小弟加載 📥?:小弟收到快照文件后,會清空自己原來的舊數據(如果有的話),然后加載這個RDB文件,這樣小弟的數據就和大哥生成快照那個時間點完全一致了。
    6. 發送緩沖命令 📨:大哥把在生成快照期間緩存起來的新命令,再發給小弟。小弟執行這些命令,追上大哥最新的狀態。
    7. 完成 👍?:至此,小弟的數據就和大哥完全同步了。這個過程叫“全量復制”。
  • b. 持續同步/增量復制 (入門后,大哥有新招式隨時教 🏃?♂?💨)

    • 全量復制完成后,大哥每次執行一個“寫”命令(如 SET, DEL, INCR 等),都會把這個命令實時地、異步地發送給所有跟著他的小弟 📡。
    • 小弟收到命令后,就在自己這邊也執行一遍同樣的命令,從而保持和大哥的數據一致。
    • 這個過程是持續不斷的,只要主從連接正常,大哥一有動作,小弟馬上跟著學。
  • 斷線重連優化 (小弟臨時掉線了怎么辦?🔗?)

    • Redis 2.8 版本之后引入了 PSYNC 命令,支持部分重同步(Partial Resynchronization)
    • 大哥會維護一個“復制積壓緩沖區”(Replication Backlog),這是一個固定大小的隊列,記錄了最近發送給小弟們的命令。
    • 如果小弟只是短暫斷線(比如網絡抖動),重連時,小弟會告訴大哥自己斷線前的“進度”(復制偏移量 offset)。
    • 大哥檢查這個進度,如果在自己的積壓緩沖區里還能找到小弟斷線后產生的所有新命令,那么大哥就只把這些增量的命令發給小弟 🩹??。小弟執行完就追上了。這樣就避免了代價很高的全量復制。
    • 如果小弟斷線時間太長,或者積壓緩沖區太小,大哥找不到小弟需要的增量信息了,那就只能辛苦一點 😥,再來一次全量復制 🏋??♀?。

四、 主從復制的優缺點是什么?

  • 優點 (好處 👍)

    • 高可用性基礎 🛡?:是Redis Sentinel(哨兵)和 Redis Cluster(集群)實現自動故障轉移和高可用的基石。
    • 讀擴展性好 📈:可以通過增加Slave節點來線性地擴展系統的讀性能。
    • 數據冗余 📑:提供了數據的熱備份。
  • 缺點 (不足之處 👎)

    • 寫能力無擴展 ????:所有寫操作都必須經過Master,Master的寫壓力無法通過增加Slave來分攤。單點寫性能瓶頸 🏺。
    • 主節點故障問題 (若無哨兵等機制) ??:如果Master宕機,需要手動將一個Slave提升為新的Master,并且通知應用切換連接,這期間服務會中斷。需要配合哨兵或集群才能實現自動故障恢復。
    • 數據一致性問題 ?:主從復制是異步的。命令從Master發送到Slave需要時間,Slave執行也需要時間。所以在極短的時間窗口內,Slave的數據可能稍微落后于Master(比如Master剛寫完一個值,還沒來得及傳給Slave,這時去Slave讀可能讀到舊值)。這叫最終一致性,對于要求強一致性的場景可能有影響。
    • 全量復制開銷 🏋??♀?💸:首次連接或斷線重連時間過長導致的全量復制,會對Master造成CPU、內存和網絡帶寬的壓力,尤其是在數據量大的情況下。

五、 總結

Redis主從復制就是找一堆小弟(Slaves)跟著大哥(Master)學習。好處是大哥倒了有人頂上(高可用備份 💪),人多力量大能幫大哥分擔讀數據的活兒(讀寫分離/負載均衡 🤝🚀)。搭建起來就是在小弟的配置文件里寫上大哥的地址和密碼 ??🔑。同步原理是,新來的小弟先拿一份大哥的完整筆記(全量復制 📸??📖),之后大哥有新動作就實時通知小弟們跟著做(增量復制 🏃?♂?💨)。缺點是寫操作還得大哥一個人扛 ????,大哥真掛了得有人手動扶小弟上位(除非有哨兵幫忙 ??),而且小弟學東西總會慢半拍(數據有延遲 ?)。

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

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

相關文章

k8s 1.30.6版本部署(使用canal插件)

#系統環境準備 參考 https://blog.csdn.net/dingzy1/article/details/147062698?spm1001.2014.3001.5501 #配置下載源 curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/deb/Release.key |gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyri…

機器學習的一百個概念(7)獨熱編碼

前言 本文隸屬于專欄《機器學習的一百個概念》,該專欄為筆者原創,引用請注明來源,不足和錯誤之處請在評論區幫忙指出,謝謝! 本專欄目錄結構和參考文獻請見[《機器學習的一百個概念》 ima 知識庫 知識庫廣場搜索&…

RHCSA復習

在Linux中, wrx 分別代表寫(write)、讀(read)和執行(execute)權限,它們對應的權限值分別是: - r (讀權限):權限值為4。 - w &am…

“樂企“平臺如何重構業財稅票全流程生態?

2025年,國家稅務總局持續推進的"便民辦稅春風行動"再次推進數字化服務升級,其中"樂企"平臺作為稅務信息化的重要載體,持續優化數電票服務能力,為企業提供更高效、更規范的稅務管理支持。在這一背景下&#xf…

Android audio(6)-audiopolicyservice介紹

AudioPolicyService 是策略的制定者,比如某種 Stream 類型不同設備的音量(index/DB)是多少、某種 Stream 類型的音頻數據流對應什么設備等等。而 AudioFlinger 則是策略的執行者,例如具體如何與音頻設備通信,維護現有系…

Boost庫搜索引擎項目(版本1)

Boost庫搜索引擎 項目開源地址 Github:https://github.com/H0308/BoostSearchingEngine Gitee:https://gitee.com/EPSDA/BoostSearchingEngine 版本聲明 當前為最初版本,后續會根據其他內容對當前項目進行修改,具體見后續版本…

git分支合并信息查看

TortoiseGit工具 1、選擇"Revision graph" 2、勾選view中的 Show branchings and merges Arrows point towards merges 3、圖案說明 紅色部分?:代表當前分支 橙色部分?:代表遠程分支 黃色部分?:代表一個tag 綠色部分?&#xf…

Java學習筆記(多線程):ReentrantLock 源碼分析

本文是自己的學習筆記,主要參考資料如下 JavaSE文檔 1、AQS 概述1.1、鎖的原理1.2、任務隊列1.2.1、結點的狀態變化 1.3、加鎖和解鎖的簡單流程 2、ReentrantLock2.1、加鎖源碼分析2.1.1、tryAcquire()的具體實現2.1.2、acquirQueued()的具體實現2.1.3、tryLock的具…

在C++11及后續標準中,auto和decltype是用于類型推導的關鍵特性,它們的作用和用法。

在C11及后續標準中,auto和decltype是用于類型推導的關鍵特性,它們的作用和用法有所不同。以下是詳細說明: 1. auto 關鍵字 基本作用 自動推導變量的類型(根據初始化表達式)主要用于簡化代碼,避免顯式書寫…

Linux:進程程序替換execl

目錄 引言 1.單進程版程序替換 2.程序替換原理 3.6種替換函數介紹 3.1 函數返回值 3.2 命名理解 3.3 環境變量參數 引言 用fork創建子進程后執行的是和父進程相同的程序(但有可能執行不同的代碼分支),我們所創建的所有的子進程,執行的代碼&#x…

LeetCode.02.04.分割鏈表

分割鏈表 給你一個鏈表的頭節點 head 和一個特定值 x ,請你對鏈表進行分隔,使得所有 小于 x 的節點都出現在 大于或等于 x 的節點之前。 你不需要 保留 每個分區中各節點的初始相對位置。 示例 1: 輸入:head [1,4,3,2,5,2], x …

Johnson算法 流水線問題 java實現

某印刷廠有 6項加工任務J1,J2,J3,J4,J5,J6,需要在兩臺機器Mi和M2上完 成。 在機器Mi上各任務所需時間為5,1,8,5,3,4單位; 在機器M2上各任務所需時間為7,2,2,4,7,4單位。 即時間矩陣為: T1 {5, …

按鍵++,--在操作uint8_t類型(一個取值為1~10的數)中,在LCD中顯示兩位數字問題

問題概況 在執行按鍵,--過程中,本來數值為1~10.但是在執行過程中,發現數值在經過10數值后,后面的“0”會一直在LCD顯示屏中顯示。 就是執行操作中,從1,2,3,4,5&#xf…

【QT】QTreeWidgetItem的checkState/setCheckState函數和isSelected/setSelected函數

目錄 1、函數原型1.1 checkState/setCheckState1.2 isSelected/setSelected2、功能用途3、示例QTreeWidget的checkState/setCheckState函數和isSelected/setSelected這兩組函數有著不同的用途,下面具體說明: 1、函數原型 1.1 checkState/setCheckState Qt::CheckState QTr…

005 vue項目結構 vue請求頁面執行流程(vue2)

文章目錄 vue項目結構vue請求頁面執行流程main.jsrouterHelloWorld.vueApp.vueindex.html vue項目結構 config目錄存放的是配置文件,比如index.js可以配置端口 node_modules存放的是該項目依賴的模塊,這些依賴的模塊在package.json中指定 src目錄分析 1…

匯豐xxx

1. Spring Boot 的了解,解決什么問題? 我的理解: Spring Boot 是一個基于 Spring 框架的快速開發腳手架,它簡化了 Spring 應用的初始搭建和開發過程。解決的問題: 簡化配置: 傳統的 Spring 應用需要大量的…

基于 Spring Boot 瑞吉外賣系統開發(一)

基于 Spring Boot 瑞吉外賣系統開發(一) 系統概述 系統功能 技術選型 初始項目和數據準備 初始項目和SQL文件下載 創建數據庫并導入數據 打開reggie項目 運行效果 主函數啟動項目,訪問URL: http://127.0.0.1:8080/backend/pag…

大型語言模型智能應用Coze、Dify、FastGPT、MaxKB 對比,選擇合適自己的LLM工具

大型語言模型智能應用Coze、Dify、FastGPT、MaxKB 對比,選擇合適自己的LLM工具 Coze、Dify、FastGPT 和 MaxKB 都是旨在幫助用戶構建基于大型語言模型 (LLM) 的智能應用的平臺。它們各自擁有獨特的功能和側重點,以下是對它們的簡要對比: Coz…

【項目管理】第6章 信息管理概論 --知識點整理

項目管理 相關文檔,希望互相學習,共同進步 風123456789~-CSDN博客 (一)知識總覽 項目管理知識域 知識點: (項目管理概論、立項管理、十大知識域、配置與變更管理、績效域) 對應&…

Zapier MCP:重塑跨應用自動化協作的技術實踐

引言:數字化協作的痛點與突破 在當今多工具協同的工作環境中,開發者與辦公人員常常面臨數據孤島、重復操作等效率瓶頸。Zapier推出的MCP(Model Context Protocol)協議通過標準化數據交互框架,為跨應用自動化提供了新的…