一、Redis 主從同步介紹
Redis 是一個開源的內存資料庫,用 C 語言編寫,支持多種數據結構,如字元串、哈希表、列表等。Redis 使用非同步 IO,在內存中存儲數據,非常適用於緩存和實時數據分析等場景。Redis 的主從同步機制是實現高可用架構的重要組成部分。
Redis 主從同步,一般指一主多從的同步模式,其中主節點負責寫入數據,從節點負責讀取數據並保持和主節點數據的同步。在這種模式下,主節點將寫入數據同步到所有從節點,從而實現數據的備份、讀取負載均衡和故障切換等功能。
Redis 的主從同步採用非同步複製方式,從節點會定期發送同步請求給主節點,主節點在接收到同步請求後會將當前的數據快照和寫入操作非同步推送到從節點。從節點會先接收到全量同步,之後再接收到增量同步,從而把自己的數據與主節點的數據保持同步。
二、Redis 主從同步配置
在 Redis 中,實現主從同步需要進行一些配置。首先,需要在主節點和從節點之間建立連接,然後在主節點上進行配置,啟用主從同步功能,設置從節點的 IP 和埠號。
具體的配置步驟如下:
# 在主節點上配置 slaveof master_ip master_port # 在從節點上配置 # 如果主節點和從節點不在同一台機器上,需要設置主節點的 IP 和埠號 # 如果主節點和從節點在同一台機器上,則不需要設置 replicaof master_ip master_port
其中,slaveof
命令用於在主節點上配置從節點,replicaof
命令用於在從節點上配置主節點。在配置完成後,從節點會自動連接到主節點,並開始數據同步。
三、Redis 主從同步實現原理
Redis 的主從同步實現依賴於複製和命令傳播兩個模塊。
複製模塊
複製模塊由同步源和同步目標兩個部分組成,同步源即主節點,同步目標即從節點。同步源在接收到同步請求後,會將當前執行的寫命令內容和參數進行序列化,並發送給同步目標,從而實現數據的同步。
// 同步請求處理實現 void syncCommand(client *c) { // 序列化當前執行的寫命令並發送給同步目標 replicationFeedSlaves(c->db->id, &c->argv, c->argc); c->flags |= CLIENT_MASTER_FORCE_REPLY; addReply(c, shared.ok); }
命令傳播模塊
當主節點執行寫入命令時,需要將命令發送給所有從節點進行同步。消息的發送有兩種方式:非同步複製和主節點判斷從節點已經收到的可靠複製。
在非同步複製方式中,主節點將命令發送給所有從節點,並返回結果。在寫入數據前,主節點會將寫操作添加到寫命令 AOF(append-only file)文件中,從節點會定期讀取 AOF 文件,從而保持和主節點數據的一致性。
// AOF 文件寫操作實現 int flushAppendOnlyFile(int force) { ... if (server.aof_selected_db->dirty == 0) { ... return C_OK; } // 將 AOF 文件和複製緩存中的內容發送給所有從節點 feedSlaves(ALL_SLAVES,server.delCommand,c->db->id,c->argv,c->argc,"del",OBJ_SHARED_INTEGERS[2]->ptr); ... // 將寫操作添加到 AOF 文件中 addReply(c,shared.ok); writeCommandsVectorLenToFile(c->db->id,c->argv,c->argc); ... }
在可靠複製方式中,主節點根據從節點的複製緩衝區中保存的 offset 和 ACK 信息來判斷哪些命令已經被從節點接收並執行。主節點會等待從節點的 ACK 信息後,再執行後續操作。
// 可靠複製方式實現 void syncWithMaster(void) { while(1) { // 讀取主節點發送的命令並執行 if (syncReadLine(reply,buf,PROTO_REPLY_CHUNK_BYTES,maxlen,&rlen) == -1) goto cleanup; if (rlen == 0) goto cleanup; if (buf[0] == '-') { // 命令出錯,中止同步 ... } else if (buf[0] == '+') { // 命令執行成功,繼續同步 ... } else if (buf[0] == '*') { // 命令包含多個回復,解析後繼續同步 ... } else if (buf[0] == '$') { // 命令結果為 BulkString 類型,解析後繼續同步 ... } else if (buf[0] == ':') { // 命令結果為 Integer 類型,解析後繼續同步 ... } // 發送 ACK 信息給主節點 if (write(sfd,"+",1) != 1) goto cleanup; } }
四、Redis 主從同步流程
Redis 主從同步流程可以分為全量同步和增量同步兩個階段。
全量同步
全量同步也叫 initial sync,是主從節點第一次進行同步時使用的同步方式。全量同步會在從節點啟動時自動觸發,主節點會將當前的數據快照和寫命令推送給從節點,從節點會接收到全量同步數據並進行載入,之後再接收增量同步。
具體的全量同步流程如下:
- 從節點請求主節點進行全量同步
- 主節點返回 RDB 快照文件
- 從節點載入 RDB 快照文件,並接收增量同步
# 在從節點上執行 SLAVEOF master_ip master_port
# 主節點發送 RDB 快照文件 $redis-benchmark -t set -n 100000 -r 100000 -D redis-master
增量同步
增量同步也叫 partial sync,是在全量同步完成後進行的同步方式。增量同步會在主節點執行寫入操作後,將寫入操作推送給所有從節點,從節點接收到寫入操作後進行同步。
具體的增量同步流程如下:
- 從節點連接主節點,並請求進行數據同步
- 主節點接收到同步請求,並推送寫入命令給所有從節點
- 從節點接收到命令並執行
# 在從節點上執行 SLAVEOF master_ip master_port
# 主節點推送命令給所有從節點 SET key value
五、Redis 主從同步優化
為了提高 Redis 主從同步的效率和穩定性,我們可以進行一些優化。
優化複製緩衝區
為了避免從節點處理速度低於主節點的寫入速度,導致從節點複製緩衝區積壓過多,我們可以擴大從節點複製緩衝區的大小。
# 在從節點上配置 repl_backlog_size size
優化 AOF 緩衝區
為了避免從節點讀取 AOF 文件時,因為 AOF 緩衝區寫滿而阻塞,導致數據同步失敗,我們可以啟用 AOF 重寫機制,定期對 AOF 文件進行重寫。
# 在主節點上配置 auto-aof-rewrite-percentage percentage auto-aof-rewrite-min-size size
啟用故障轉移機制
在主從同步環境下,如果主節點出現故障,則需要從節點接替主節點成為新的主節點。為了實現自動切換,我們可以啟用 Redis 的 Sentinel(哨兵)機制。
# 在主節點和從節點上啟用 Sentinel sentinel monitor master_name master_ip master_port num_slaves
六、總結
Redis 主從同步是實現高可用的必要手段,在多節點環境下具有重要意義。掌握 Redis 主從同步的配置、實現原理和優化策略,可以提高系統的穩定性和性能。
原創文章,作者:TJND,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/142168.html