動態

詳情 返回 返回

Redis主從複製詳解 - 動態 詳情

概述

Redis 的主從複製(Master-Slave Replication)是實現數據備份、讀寫分離和水平擴展的核心機制之一。通過主從複製,一個主節點(Master)可以將數據同步到多個從節點(Slave),從節點還可以級聯創建自己的從節點,從而形成樹狀結構。

注意,Redis的主從複製是實現高可用的核心機制,並不能實現高可用

Redis主從複製作用

數據冗餘:

主從複製實現了數據的熱備份,是持久化之外的一種數據冗餘方式。

故障恢復

當主節點出現問題時,可以由從節點提供服務,實現快速的故障恢復;實際上是一種服務的冗餘。

負載均衡:

在主從複製的基礎上,配合讀寫分離,可以由主節點提供寫服務,由從節點提供讀服務(即寫Redis數據時應用連接主節點,讀Redis數據時應用連接從節點),分擔服務器負載;尤其是在寫少讀多的場景下,通過多個從節點分擔讀負載,可以大大提高Redis服務器的併發量。

讀寫分離:

可以用於實現讀寫分離,主庫寫、從庫讀,讀寫分離不僅可以提高服務器的負載能力,同時可根據需求的變化,改變從庫的數量。

高可用基石

除了上述作用以外,主從複製還是哨兵和集羣能夠實施的基礎,因此説主從複製是Redis高可用的基礎。

Redis主從複製搭建

搭建主服務器

參考這篇文章:Redis6.2.x版本安裝

搭建從服務器

參考這篇文章:Redis6.2.x版本安裝

需要注意從服務器配置文件的修改:

# 第75行,修改遠程訪問地址
75:bind 0.0.0.0
# 第98行,修改端口號
98:port 6379
# 第259行,守護進程運行,默認位前台運行,需要修改為yes
259:daemonize yes
# 第304行,指定redis的日誌
304:logfile "/var/log/redis/redis.log"
# 第329行,指定數據庫的數量,默認是16個
329:databases 16
# 第433行,持久化的文件
433:dbfilename dump.rdb
# 第456行,設置redis的數據目錄,和我們上面創建的路徑保持一致
456:dir /data00/data/redis/
# 第903行,設置密碼,建議不要使用弱密碼
903:requirepass 123456

# 第479行,主庫的IP和端口
479:replicaof 127.0.0.1 6379
# 第486行,如果主服務器設置了密碼,需要配置認證
486:masterauth !Xinxin123

# 其它配置
# 從服務器是否可寫(默認只讀)
replica-read-only yes
# 複製緩衝區大小
repl-backlog-size 1mb
# 複製超時時間(秒)
repl-timeout 60
# 當主從斷開時,從服務器是否繼續提供服務
replica-serve-stale-data yes

啓動主庫之後再啓動從庫

[root@node01 ~]# redis-server /data00/data/redis/redis.conf

[root@node01 ~]# ss -lntup | grep 6379
tcp   LISTEN 0      511                          127.0.0.1:6379       0.0.0.0:*    users:(("redis-server",pid=1001533,fd=6))
tcp   LISTEN 0      511                              [::1]:6379          [::]:*    users:(("redis-server",pid=1001533,fd=7))

驗證主從複製是否成功

在主從分別執行INFO REPLICATION命令

# 主庫執行
127.0.0.1:6379> INFO REPLICATION
# Replication
role:master
connected_slaves:1
slave0:ip=10.37.99.63,port=6379,state=online,offset=98,lag=0
master_failover_state:no-failover
master_replid:2f61b8be8cbf19e45882f77bea61b55862bf74e5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:98
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:98

# 從庫執行
127.0.0.1:6379> INFO REPLICATION
# Replication
role:slave
master_host:10.37.97.56
master_port:6379
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_read_repl_offset:238
slave_repl_offset:238
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:2f61b8be8cbf19e45882f77bea61b55862bf74e5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:238
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:238

驗證主庫寫入數據,從庫是否能獲取到

# 主庫寫入數據
127.0.0.1:6379> set rep rep
OK

# 從庫查詢數據
127.0.0.1:6379> get rep
"rep"

驗證從庫寫數據,預期應該報錯

127.0.0.1:6379> set slave 1
(error) READONLY You can't write against a read only replica.

Redis主從複製原理

主從複製過程大體可以分為3個階段:連接建立階段(即準備階段)、數據同步階段、命令傳播階段。

在從節點執行 slaveof 命令後,複製過程便開始運作,下面圖示可以看出複製過程大致分為6個過程。
image

  1. 保存主節點信息

執行slaveof後 Redis會打印如下日誌:
image

  1. 從節點與主節點建立網絡連接

從節點(slave)內部通過每秒運行的定時任務維護複製相關邏輯,當定時任務發現存在新的主節點後,會嘗試與該節點建立網絡連接。
image

從節點會建立一個 socket 套接字,從節點建立了一個端口為51234的套接字,專門用於接受主節點發送的複製命令。從節點連接成功後打印如下日誌:
image

如果從節點無法建立連接,定時任務會無限重試直到連接成功或者執行 slaveofnoone 取消複製。

關於連接失敗,可以在從節點執行 info replication 查看 master_link_down_since_seconds 指標,它會記錄與主節點連接失敗的系統時間。從節點連接主節點失敗時也會每秒打印如下日誌,方便發現問題:
image

  1. 發送ping命令

連接建立成功後從節點發送 ping 請求進行首次通信, ping 請求主要目的如下:

  • 檢測主從之間網絡套接字是否可用。

  • 檢測主節點當前是否可接受處理命令。

如果發送 ping 命令後,從節點沒有收到主節點的 pong 回覆或者超時,比如網絡超時或者主節點正在阻塞無法響應命令,從節點會斷開復制連接,下次定時任務會發起重連。
image

image
從節點發送的 ping 命令成功返回,Redis 打印如下日誌,並繼續後續複製流程:
image

  1. 權限驗證

如果主節點設置了 requirepass 參數,則需要密碼驗證,從節點必須配置 masterauth 參數保證與主節點相同的密碼才能通過驗證。如果驗證失敗複製將終止,從節點重新發起復制流程。

  1. 同步數據集

主從複製連接正常通信後,對於首次建立複製的場景,主節點會把持有的數據全部發送給從節點,這部分操作是耗時最長的步驟。

  1. 命令持續複製

當主節點把當前的數據同步給從節點後,便完成了複製的建立流程。接下來主節點會持續地把寫命令發送給從節點,保證主從數據一致性。

主從複製數據同步原理

Redis支持主從複製,Redis的主從結構可以採用一主多從或者級聯結構,Redis主從複製可以根據是否是全量分為全量同步和增量同步。下圖為級聯結構。
image

全量同步階段

Redis全量同步一般發生在Slave初始化階段,這時Slave需要將Master上的所有數據都複製一份。具體步驟如下:

  • 從服務器配置主服務器的連接信息(slaveof屬性);

  • 從服務器連接上主服務器,發送SYNC命令

  • 主服務器判斷是否為全量複製:如果是全量複製,則進入下一步;否則可以看增量複製的子流程。

  • 主服務器接收到SYNC命名後,開始執行BGSAVE命令生成RDB文件並使用緩衝區記錄此後執行的所有寫命令;

  • 主服務器BGSAVE執行完後,向所有從服務器發送快照文件,並在發送期間繼續記錄被執行的寫命令;

  • 從服務器收到快照文件後丟棄所有舊數據,載入收到的快照;

  • 主服務器快照發送完畢後開始向從服務器發送緩衝區中的寫命令;

  • 從服務器完成對快照的載入,開始接收命令請求,並執行來自主服務器緩衝區的寫命令;
    image

增量同步階段

Redis增量複製是指Slave初始化後開始正常工作時主服務器發生的寫操作同步到從服務器的過程。

增量複製的過程主要是主服務器每執行一個寫命令就會向從服務器發送相同的寫命令,從服務器接收並執行收到的寫命令。

開啓無磁盤同步

Redis在與從數據庫進行復制初始化時將不會將快照存儲到磁盤,而是直接通過網絡發送給從數據庫,避免了IO性能差問題。

啓動無磁盤複製:

repl-diskless-sync yes

Add a new 評論

Some HTML is okay.