網(wǎng)站首頁 編程語言 正文
【Redis】Redis 的主從同步
很多企業(yè)都沒有使用 Redis 的集群,但是至少都做了主從。有了主從,當(dāng)主節(jié)點(Master) 掛掉的時候,運維讓從節(jié)點 (Slave) 過來接管,服務(wù)就可以繼續(xù),否則主節(jié)點需要經(jīng)過數(shù)據(jù)恢復(fù)和重啟的過程,這就可能會拖延很長的時間,從而影響線上業(yè)務(wù)的持續(xù)服務(wù)。
盡管 Redis 的性能很好,但是有時候依舊滿足不了應(yīng)用的需要,比如過多的用戶進入主頁.導(dǎo)致 Redis 被頻繁訪問,此時就存在大量的讀操作。在一些熱門網(wǎng)站,某個時刻(比如促銷商品的時候)有每秒成千上萬的請求是司空見慣的,這個時候大量的讀操作會到達 Redis 服務(wù)器.觸發(fā)許許多多的操作,顯然靠一臺 Redis 服務(wù)器是完全不夠用的。一些服務(wù)網(wǎng)站對安全性有較高的要求,當(dāng)主服務(wù)器不能正常工作時,需要從服務(wù)器代替原來的主服務(wù)器作為災(zāi)備,以保證系統(tǒng)可以繼續(xù)正常工作。因此更多的時候我們希望可以讀/寫分離,讀/寫分離的前提是讀操作遠遠比寫操作頻繁得多,如果把數(shù)據(jù)存放在多臺服務(wù)器上,就可以從多臺服務(wù)器中讀取數(shù)據(jù),從而減輕單臺服務(wù)器的壓力了,讀/寫分離的技術(shù)已經(jīng)廣泛用于數(shù)據(jù)庫中。
? 在了解 Redis 的主從復(fù)制之前,讓我們先來理解一下現(xiàn)代分布式系統(tǒng)的理論基石——CAP 原理。
CAP 原理
CAP 原理就好比分布式領(lǐng)域的牛頓定律,它是分布式存儲的理論基石。自從CAP的論文發(fā)表之后,分布式存儲中間件猶如雨后春筍般涌現(xiàn)出來。理解這個原理其實很簡單,本節(jié)我們首先對這個原理進行簡單的講解。
-
C
:Consistent,一致性 -
A
:Availability,可用性 -
P
:Partition tolerance ,分區(qū)容忍性
分布式系統(tǒng)的節(jié)點往往都是分布在不同的機器上進行網(wǎng)絡(luò)隔離開的,這意味著必然會有網(wǎng)絡(luò)斷開的風(fēng)險,這個網(wǎng)絡(luò)斷開的場景的專業(yè)詞匯叫作網(wǎng)絡(luò)分區(qū)
。
如下圖所示,在網(wǎng)絡(luò)分區(qū)發(fā)生時,兩個分布式節(jié)點之間無法進行通信,我們對一個節(jié)點進行的修改操作將無法同步到另外一個節(jié)點,所以數(shù)據(jù)的一致性
將無法滿足,因為兩個分布式節(jié)點的數(shù)據(jù)不再保持一致。除非我們犧牲可用性
,也就是暫停分布式節(jié)點服務(wù),在網(wǎng)絡(luò)分區(qū)發(fā)生時,不再提供修改數(shù)據(jù)的功能,直到網(wǎng)絡(luò)狀況
完全恢復(fù)正常再繼續(xù)對外提供服務(wù)。
用一句話概括 CAP 原理就是: 當(dāng)網(wǎng)絡(luò)分區(qū)發(fā)生時,一致性和可用性兩難全
最終一致
Redis的主從數(shù)據(jù)是異步同步的,所以分布式的 Redis系統(tǒng)并不滿足一致性
要求當(dāng)客戶端在 Redis的主節(jié)點修改了數(shù)據(jù)后,立即返回,即使在主從網(wǎng)絡(luò)斷開的情況下主節(jié)點依舊可以正常對外提供修改服務(wù),所以 Redis 滿足可用性
。
Redis 保證最終一致性
,從節(jié)點會努力追趕主節(jié)點,最終從節(jié)點的狀態(tài)會和主節(jié)點的狀態(tài)保持一致。如果網(wǎng)絡(luò)斷開了,主從節(jié)點的數(shù)據(jù)將會出現(xiàn)大量不一致,但一旦網(wǎng)絡(luò)恢復(fù),從節(jié)點會采用多種策略努力追趕,繼續(xù)盡力保持和主節(jié)點一致。
主從同步與從從同步
Redis 同步支持主從同步和從從同步,從從同步功能是 Redis 后續(xù)版本增加的功能,以減輕主節(jié)點的同步負(fù)擔(dān)。后面為了描述上的方便,統(tǒng)一理解為主從同步。
增量同步
Redis 同步的是指令流,主節(jié)點會將那些對自己的狀態(tài)產(chǎn)生修改性影響的指令錄在本地的內(nèi)存 buffer 中,然后異步將 bufer 中的指令同步到從節(jié)點,從節(jié)點一邊執(zhí)行同步的指令流來達到和主節(jié)點一樣的狀態(tài),一邊向主節(jié)點反饋自己同步到哪里了(偏移量)。
? 因為內(nèi)存的 buffer 是有限的,所以 Redis 主節(jié)點不能將所有的指令都記錄在內(nèi)存 buffer 中。Redis 的復(fù)制內(nèi)存 buffer是一個定長的環(huán)形數(shù)組,如圖所示,如果數(shù)組內(nèi)容滿了,就會從頭開始覆蓋前面的內(nèi)容。
? 如果因為網(wǎng)絡(luò)狀況不好,從節(jié)點在短時間內(nèi)無法和主節(jié)點進行同步,那么當(dāng)網(wǎng)絡(luò)狀況恢復(fù)時,Redis 的主節(jié)點中那些沒有同步的指令在buffer 中有可能已經(jīng)被后續(xù)的指令覆蓋掉了,從節(jié)點將無法直接通過指令流來進行同步,這個時候就需要用到更加復(fù)雜的同步機制一一快照同步。
快照同步
? 快照同步是一個非常耗費資源的操作,如圖所示,它首先需要在主節(jié)點上進行一次 bgsave
,將當(dāng)前內(nèi)存的數(shù)據(jù)全部快照到磁盤文件中,然后再將快照文件的內(nèi)容全部傳送到從節(jié)點。從節(jié)點將快照文件接受完畢后,立即執(zhí)行一次全量加載,加載之前先要將當(dāng)前內(nèi)存的數(shù)據(jù)清空,加載完畢后通知主節(jié)點繼續(xù)進行增量同步。
? 在整個快照同步進行的過程中,主節(jié)點的復(fù)制 buffer 還在不停地往前移動,如果快照同步的時間過長或者復(fù)制 buffer 太小,都會導(dǎo)致同步期間的增量指令在復(fù)制 buffer 中被覆蓋,這樣就會導(dǎo)致快照同步完成后無法進行增量復(fù)制,然后會再次發(fā)起快照同步,如此極有可能會陷入快照同步的死循環(huán)。所以務(wù)必配置一個合適的復(fù)制 buffer 大小參數(shù),避免快照復(fù)制的死循環(huán)。
Redis 主從同步基礎(chǔ)概念
互聯(lián)網(wǎng)系統(tǒng)一般以主從架構(gòu)為基礎(chǔ),所謂主從架構(gòu)設(shè)計的思路大概如下。
- 在多臺數(shù)據(jù)服務(wù)器中,只有一臺主服務(wù)器,而主服務(wù)器只負(fù)責(zé)寫入數(shù)據(jù),不負(fù)責(zé)讓外部程序讀取數(shù)據(jù)。
- 存在多臺從服務(wù)器,從服務(wù)器不寫入數(shù)據(jù),只負(fù)責(zé)同步主服務(wù)器的數(shù)據(jù),并讓外部程序讀取數(shù)據(jù)。
- 主服務(wù)器在寫入數(shù)據(jù)后,即刻將寫入數(shù)據(jù)的命令發(fā)送給從服務(wù)器,從而使得主從數(shù)據(jù)同先。
- 應(yīng)用程序可以隨機讀取某一臺從服務(wù)器的數(shù)據(jù),這樣就分?jǐn)偭俗x數(shù)據(jù)的壓力。
- 當(dāng)從服務(wù)器不能工作的時候,整個系統(tǒng)將不受影響;當(dāng)主服務(wù)器不能工作的時候,可以方便地從從服務(wù)器中選取一臺來當(dāng)主服務(wù)器。
請注意上面的思路,我用了“大概”這兩個字,因為這只是一種大概的思路,每一種數(shù)據(jù)存儲軟件都會根據(jù)其自身的特點對上面的這幾點思路加以改造,但是萬變不離其宗,只要理解了這幾點就很好理解 Redis 的復(fù)制機制。主從同步機制如下圖所示。
這個時候讀數(shù)據(jù)可以隨機從從服務(wù)器上讀取,當(dāng)從服務(wù)器是多臺的時候,單臺服務(wù)器的壓力就大大降低了,這十分有利于系統(tǒng)性能的提高,當(dāng)主服務(wù)器出現(xiàn)不能工作的情況時,也可以切換為其中的一臺從服務(wù)器繼續(xù)讓系統(tǒng)穩(wěn)定運行,所以也有利于系統(tǒng)運行的安全。當(dāng)然,由于Redis 自身具備的特點,所以其也有實現(xiàn)主從同步的特殊方式。
首先,明確主機,我們將從主機復(fù)制數(shù)據(jù)發(fā)往從機:其次,明確從機。有了這兩點后,就可以進行進一步配置了;再次,看 redis.conf 文件,這里要關(guān)注的只有 replicaof
這個配置選項,它的配置格式是:
replicaof <masterip> <masterport>
其中,masterip
代表主機,masterport
代表端口。當(dāng)從機 Redis 服務(wù)重啟時,就會同步主機的數(shù)據(jù)。當(dāng)不想讓從機繼續(xù)復(fù)制主機的數(shù)據(jù)時,可以在從機執(zhí)行命令
replicaof no one
這樣從機就不會再接收主機更新的數(shù)據(jù)了。又或者原來的主機已經(jīng)無法工作了,需要復(fù)制新的主機,這個時候執(zhí)行
replicaof <masterip> <masterport>
就能讓從機復(fù)制另外一臺主機的數(shù)據(jù)了。
在實際的 Linux 環(huán)境中,配置文件 redis.conf中還有一個bind 的配置,默認(rèn)為127.0.0.1
也就是只允許本機訪問,這里需要修改它,將其配置為0.0.0.0
,這樣其他的服務(wù)器就能夠訪問了。
Redis 主從同步的過程
Redis 主從同步的過程如下圖所示。
上圖中左邊的流程是主服務(wù)器,右邊的流程是從服務(wù)器,這里有必要進行更深層次的描述。
(1)無論如何要先保證主服務(wù)器開啟,開啟主服務(wù)器后,從服務(wù)器通過命令或者重啟配置項可以同步到主服務(wù)器。
(2)當(dāng)從服務(wù)器啟動時,讀取同步的配置,根據(jù)配置決定是否使用當(dāng)前數(shù)據(jù)響應(yīng)客戶端,然后發(fā)送SYNC命令。當(dāng)主服務(wù)器接收到同步命令時,就會執(zhí)行 bgsave
命令備份數(shù)據(jù),但是主服務(wù)器并不會拒絕客戶端的讀/寫,而是將來自客戶端的寫命令寫入緩沖區(qū)。從服務(wù)器未收到主服務(wù)器備份的快照文件時,會根據(jù)其配置決定使用現(xiàn)有數(shù)據(jù)響應(yīng)或者拒絕客戶端請求。
(3)當(dāng)bgsave
命令被主服務(wù)器執(zhí)行完后,開始向從服務(wù)器發(fā)送備份文件,這個時候從服務(wù)器就會丟棄所有現(xiàn)有的數(shù)據(jù),開始載入主服務(wù)器發(fā)送的快照文件。
(4)當(dāng)主服務(wù)器發(fā)送完備份文件后,從服務(wù)器就會執(zhí)行這些寫入命令。此時就會把 bgsave
執(zhí)行之后的緩存區(qū)內(nèi)的寫命令也發(fā)送給從服務(wù)器,從服務(wù)完成備份文件解析,就開始像往常-樣,接收命令,等待命令寫入。
(5)緩沖區(qū)的命令發(fā)送完成后,主服務(wù)器執(zhí)行完一條寫命令,就向從服務(wù)器發(fā)送同步寫入命令,從服務(wù)器就和主服務(wù)器保持一致了。而此時當(dāng)從服務(wù)器完成主服務(wù)器發(fā)送的緩沖區(qū)命令后,就開始等待主服務(wù)器的命令了。
以上5步就是 Redis 主從同步的過程。
**在主服務(wù)器同步到從服務(wù)器的過程中,需要備份文件,所以在配置的時候一般需要預(yù)留-些內(nèi)存空間給主服務(wù)器,用以執(zhí)行備份命令。**一般來說主服務(wù)器使用 50%~65%的內(nèi)存空間,以為主從復(fù)制留下可用的內(nèi)存空間。
多從機同步機制,如下圖所示。
如果出現(xiàn)多臺同步,那么可能出現(xiàn)頻繁等待和操作 bgsave 命令的情況,導(dǎo)致主機在較長時間里性能不佳,這個時候我們會考慮主從鏈同步的機制,以減少這種可能。
不過復(fù)制功能也不是必需的,如果你只用 Redis做緩存,跟 memcache 一樣對待也就不需要從節(jié)點做備份,掛掉了重新啟動一下就行。但是只要你使用了 Redis 的持久化功能,就必須認(rèn)真對待主從復(fù)制,它是系統(tǒng)數(shù)據(jù)安全的基礎(chǔ)保障。
原文鏈接:https://blog.csdn.net/Mr_VK/article/details/132353177
- 上一篇:沒有了
- 下一篇:沒有了
相關(guān)推薦
- 2022-07-12 Hive獲取當(dāng)天0點時間,條件查詢某一天數(shù)據(jù)
- 2024-03-21 SpringBoot +MyBatis批量插入數(shù)據(jù)
- 2022-07-15 SQL?Server中執(zhí)行動態(tài)SQL_MsSql
- 2022-11-28 golang進程在docker中OOM后hang住問題解析_Golang
- 2022-05-27 五個經(jīng)典鏈表OJ題帶你進階C++鏈表篇_C 語言
- 2022-04-21 Docker容器跨主機通信overlay網(wǎng)絡(luò)的解決方案_docker
- 2022-07-16 (ES6以上以及TS) Map對象轉(zhuǎn)數(shù)組
- 2022-08-21 golang協(xié)程與線程區(qū)別簡要介紹_Golang
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支