為什么Redis主從模式能保持數據一致
互聯網 2022/5/2 19:13:19
為什么Redis主從模式能保持數據一致。想要知道答案,我們得深入分析Redis實例之間如何進行數據同步。
概述
在具體分析今天的問題之前,我們需要了解 Redis 具有高可靠性,又是什么意思呢?其實,這里有兩層含義:一是數據盡量少丟失,二是服務盡量少中斷。AOF 和 RDB 保證了前者,而對于后者,Redis 的做法就是增加副本冗余量,將一份數據同時保存在多個實例上。即使有一個實例出現了故障,需要過一段時間才能恢復,其他實例也可以對外提供服務,不會影響業務使用。多實例保存同一份數據,聽起來好像很不錯,但是,我們必須要考慮一個問題:這么多副本,它們之間的數據如何保持一致呢?數據讀寫操作可以發給所有的實例嗎?實際上,Redis 提供了主從庫模式,以保證數據副本的一致,主從庫之間采用的是讀寫分離的方式。
1)讀操作:主庫、從庫都可以接收;
2)寫操作:首先到主庫執行,然后,主庫將寫操作同步給從庫。
到了這里我們發現幾個問題:
1)主從庫為什么要采用讀寫分離的方式;
2)主庫如何把數據同步給從庫;
3)主從庫之前網絡斷了怎么辦;
不過既然Redis具有高可用性,說明這些問題都已經有了答案。
設計
主從庫為什么要采用讀寫分離的方式
你可以設想一下,如果不管是主庫還是從庫,都能接收客戶端的寫操作,那么,一個直接的問題就是:如果客戶端對同一個數據(例如 k1)前后修改了三次,每一次的修改請求都發送到不同的實例上,在不同的實例上執行,那么,這個數據在這三個實例上的副本就不一致了(分別是 v1、v2 和 v3)。在讀取這個數據的時候,就可能讀取到舊的值。
如果我們非要保持這個數據在三個實例上一致,就要涉及到加鎖、實例間協商是否完成修改等一系列操作,但這會帶來巨額的開銷,當然是不太能接受的。
主庫如何把數據同步給從庫
當我們啟動多個 Redis 實例的時候,它們相互之間就可以通過 replicaof(Redis 5.0 之前使用 slaveof)命令形成主庫和從庫的關系,之后會按照三個階段完成數據的第一次同步。
數據同步
第一階段
建立連接,協商同步,psync(runId=?,offest=-1),此時主庫會調用FULLRESYNC進行同步。
第二階段
主庫執行 bgsave 命令,生成 RDB 快照文件,接著將文件發給從庫。從庫接收到 RDB 文件后,會先清空當前數據庫,然后加載 RDB 文件。這是因為從庫在通過 replicaof 命令開始和主庫同步前,可能保存了其他數據。為了避免之前數據的影響,從庫需要先把當前數據庫清空。
可能會有人質疑,主庫生成RDB快照文件,不會阻塞主庫的讀寫操作嗎?會不會有額外的性能開銷?那這些問題我們今天就不展開討論了,感興趣的同學可以讀下源碼。
rdbSaveBackground就是用來處理在后臺將數據保存到磁盤上的函數:
int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) { pid_t childpid;
if (hasActiveChildProcess()) return C_ERR; ...
if ((childpid = redisFork()) == 0) { int retval;
/* Child */ redisSetProcTitle("redis-rdb-bgsave"); retval = rdbSave(filename,rsi); if (retval == C_OK) { sendChildCOWInfo(CHILD_INFO_TYPE_RDB, "RDB"); } exitFromChild((retval == C_OK) ? 0 : 1); } else { /* Parent */ ... } ...}
第三階段
增量復制
repl_backlog_buffer
最后,也就是第三個階段,主庫會把第二階段執行過程中新收到的寫命令,再發送給從庫。具體的操作是,當主庫完成 RDB 文件發送后,就會把此時 replication buffer 中的修改操作發給從庫,從庫再重新執行這些操作。這樣一來,主從庫就實現同步了。
主從庫如果斷開連接了,下次建立連接時會通過repl_backlog_buffer環形緩沖區進行增量復制,psync(runId=1,offest=100),offest=100用于標記從庫在repl_backlog_buffer中的位置。
總結
為什么Redis主從模式能保持數據一致?
- 采用讀寫分離,避免加鎖、實例間協商是否完成修改等操作,減少不必要的性能損耗;
- 主從實例間通過RDB快照進行數據同步,同步期間主庫的寫操作額外記錄一份到replication buffer中,同步完成時,發送給從庫,從庫再重新執行這些操作。
- 后續的數據同步通過repl_backlog_buffrt來標記主從實例環形緩沖區中的位置,從庫執行這些操作。
若有收獲,就點個贊吧

關于找一找教程網
本站文章僅代表作者觀點,不代表本站立場,所有文章非營利性免費分享。
本站提供了軟件編程、網站開發技術、服務器運維、人工智能等等IT技術文章,希望廣大程序員努力學習,讓我們用科技改變世界。
[為什么Redis主從模式能保持數據一致]http://www.yachtsalesaustralia.com/tech/detail-318767.html
- 2022-05-19Centos7部署Redis集群
- 2022-05-19定時任務部署多少臺服務器,怎么確保只有一臺服務器執行--redis 分布式鎖
- 2022-05-19laravel redis秒殺功能
- 2022-05-19女朋友面試回來抱怨說會redis,面試官問了一堆redis
- 2022-05-19redis 設計與實現 讀書筆記 - 鏈表
- 2022-05-18Redis 4.x/5.x 主從復制導致的命令執行
- 2022-05-18部署單機版Redis
- 2022-05-18Redis 集群
- 2022-05-18Redis核心技術與實踐 01 | 基本架構:一個鍵值數據庫包含什么?
- 2022-05-18Redis核心技術與實踐 02 | 數據結構:快速的Redis有哪些慢操作?