概念
主從復制,是指將一臺 Redis 服務器的數據,復制到其他的Redis服務器。前者稱為主節點(master),后者稱為從節點(slave);數據的復制是單向的,只能由主節點到從節點。
默認情況下,每臺Redis服務器都是主節點;且一個主節點可以有多個從節點(或沒有從節點),但一個從節點只能有一個主節點。
主從復制的作用
主從復制的作用主要包括:
- 數據冗余:主從復制實現了數據的熱備份,是持久化之外的一種數據冗余方式。
- 故障恢復:當主節點出現問題時,可以由從節點提供服務,實現快速的故障恢復;實際上是一種服務的冗余。
- 負載均衡:在主從復制的基礎上,配合讀寫分離,可以由主節點提供寫服務,由從節點提供讀服務(即寫Redis數據時應用連接主節點,讀Redis數據時應用連接從節點),分擔服務器負載;尤其是在寫少讀多的場景下,通過多個從節點分擔讀負載,可以大大提高Redis服務器的并發量。
- 高可用基石:除了上述作用以外,主從復制還是哨兵和集群能夠實施的基礎,因此說主從復制是Redis高可用的基礎。
如何使用主從復制
為了更直觀的理解主從復制,在介紹其內部原理之前,先說明我們需要如何操作才能開啟主從復制。
1. 建立復制
需要注意,主從復制的開啟,完全是在從節點發起的;不需要我們在主節點做任何事情。
從節點開啟主從復制,有 3 種方式:
(1)配置文件
在從服務器的配置文件中加入:slaveof
(2)啟動命令
redis-server啟動命令后加入 --slaveof
(3)客戶端命令
Redis服務器啟動后,直接通過客戶端執行命令:slaveof ,則該Redis實例成為從節點。
上述 3 種方式是等效的,下面以客戶端命令的方式為例,看一下當執行了slaveof 后,Redis 主節點和從節點的變化。
2. 實例
準備工作:啟動兩個節點
1) 復制配置文件
[root@localhost bin]# ls ### 進入redis 安裝目錄下可執行目錄
dump.rdb redis-benchmark redis-check-aof redis-check-rdb redis-cli redis.conf redis-sentinel redis-server
[root@localhost bin]# cp redis.conf redis1.conf ### 復制配置文件作為其中一個從機
[root@localhost bin]# cp redis.conf redis2.conf ### 復制配置文件作為其中一個從機
[root@localhost bin]# vi redis1.conf ### 修改redis1.conf端口為 6381
##***** :/6379 搜索即可找到
此時之前的 redis 實例端口為6379 ,現在又多一個6381。
接下來分別啟動各自服務。
啟動6379:
[root@localhost bin]# redis-server redis.conf ###******* 注意使用各自的配置文件
16624:C 05 Aug 2021 09:11:14.767 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
16624:C 05 Aug 2021 09:11:14.767 # Redis version=6.0.6, bits=64, commit=00000000, modified=0, pid=16624, just started
16624:C 05 Aug 2021 09:11:14.767 # Configuration loaded
[root@localhost bin]# redis-cli -p 6379
127.0.0.1:6379> info replication ###******* 查看主從情況
# Replication
role:master ###******* 默認自己都為master 主節點
connected_slaves:0
master_replid:e2995fc02165a6f45644b6076aa4ae7c75ccf3d6
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:28
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:28
127.0.0.1:6379>
再啟動6381:
[root@localhost bin]# redis-server redis1.conf #***** 使用第二個實例配置文件啟動
16641:C 05 Aug 2021 09:12:07.514 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
16641:C 05 Aug 2021 09:12:07.515 # Redis version=6.0.6, bits=64, commit=00000000, modified=0, pid=16641, just started
16641:C 05 Aug 2021 09:12:07.515 # Configuration loaded[root@localhost bin]# redis-cli -p 6381 ##**** 使用6381
127.0.0.1:6381> info replication
# Replication
role:master ##**** 一樣顯示主節點
connected_slaves:0
master_replid:fdc1b15ab0d76bca91227af2c0ebf8198a7c8541
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6381>
從上面看出,兩個Redis節點啟動后(分別稱為6379節點和6381節點),默認都是主節點。
3. 主從配置
此時在6381節點執行 slaveof 命令,使之變為從節點:
127.0.0.1:6381> slaveof 127.0.0.1 6379 ## 建立主從關系,附屬6379
OK127.0.0.1:6381> info replication
# Replication
role:slave ## 顯示變為了從節點了
master_host:127.0.0.1
master_port:6379
master_link_status:up ## 和主節點保持了連接狀態
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:70
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:e2995fc02165a6f45644b6076aa4ae7c75ccf3d6
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:70
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:42
127.0.0.1:6381>
再看 6379 節點:
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1 # 所屬從節點有一個
slave0:ip=127.0.0.1,port=6381,state=online,offset=196,lag=1
master_replid:e2995fc02165a6f45644b6076aa4ae7c75ccf3d6
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:196
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:196
測試讀寫操作:
先在從節點查詢一個不存在的 key,然后去主節點添加此 key ,會發現會自動同步到各個從節點
127.0.0.1:6381> get age
(nil)127.0.0.1:6381> get age ### 當主節點存入age 后 ,再取值,發現已經自動同步到從機了
"23"
127.0.0.1:6381> set age 24
(error) READONLY You can't write against a read only replica.
127.0.0.1:6381>
注意:上面的error提示中,說明從節點是只能讀,不能寫的。所謂主從復制。讀寫分離
4. 啟動命令方式
redis-server啟動命令后加入 --slaveof
上面的方式,使用客戶端命令方式來實現的主從的配置。
下面使用啟動時指定主從關系。
redis-server myredis/redis1.conf --slaveof 127.0.0.1 6379?啟動 Redis 服務時,指定所屬的主節點為 6379 端口上的服務
[root@wang ~]# redis-server myredis/redis1.conf --slaveof 127.0.0.1 6379
29087:C 25 Aug 2021 16:04:29.836 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
29087:C 25 Aug 2021 16:04:29.836 # Redis version=6.0.6, bits=64, commit=00000000, modified=0, pid=29087, just started
29087:C 25 Aug 2021 16:04:29.836 # Configuration loaded
[root@wang ~]# redis-cli -p 6381
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:1007
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:f05b6c77978f163ae77ebed3dcd0bb85790ed197
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1007
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
5. 配置文件方式
可以在啟動的配置文件中 redis1.config 中追加下面的一行配置 :
slaveof 127.0.0.1 6379
[root@wang myredis]# echo "slaveof 127.0.0.1 6379" >> redis1.conf
[root@wang myredis]# tail -5 redis1.conf