redis主從複製

misakivv發表於2024-04-15

目錄
  • 一、什麼是redis主從複製
    • 1、主從複製架構
    • 2、redis為什麼需要主從複製
  • 二、搭建主從複製
    • 1、涉及主機
    • 2、編譯安裝redis
      • 2.1、獲取軟體安裝包,安裝編譯環境
      • 2.2、編譯安裝
      • 2.3、配置變數
      • 2.4、驗證目錄結構
      • 2.5、準備目錄及檔案
    • 3、前臺啟動redis
      • 3.1、消除三個警告提示
    • 4、使用systemctl管理redis
      • 4.1、建立redis使用者
      • 4.2、編輯redis服務啟動檔案
      • 4.3、驗證redis啟動
    • 5、使用客戶端連線redis
    • 6、設定登陸密碼、修改監聽地址、資料目錄、日誌,PID檔案路徑
      • 6.1、修改配置檔案
      • 6.2、重啟redis
    • 7、建立命令軟連結
    • 8、啟用主從同步
      • 8.1、在master上設定key1
      • 8.2、slave登入設定key1
      • 8.3、所有slave設定master的IP和埠
      • 8.4、master端驗證slave資訊
    • 9、刪除主從同步
      • 9.1、slave節點取消主從複製
      • 9.2、在master上驗證
    • 10、同步日誌
      • 10.1、各個節點上觀察日誌
      • 10.2、修改slave節點
      • 10.3、登入檢視master和slave狀態
  • 三、模擬master節點當機
    • 1、停止master的redis服務
    • 2、觀察slave節點日誌
    • 3、觀察slave狀態
  • 四、主從複製故障恢復
    • 1、slave節點故障與恢復
    • 2、master節點故障與恢復
    • 3、主從複製故障恢復實現
      • 3.1、停止slave1主從同步並提升為新的master
      • 3.2、修改剩下的slave指向新的master節點
      • 3.3、在新的master節點檢視slave資訊
  • 五、實現redis的級聯複製
    • 1、涉及主機
    • 2、所有主機安裝reids
    • 3、搭建一主一從
      • 3.1、主節點建立驗證資料
      • 3.2、一級從節點設定master的IP和埠
    • 4、修改二級從節點指向一級從節點作為master
    • 5、在master上設定key,觀察是否同步
      • 5.1、在slave上進行驗證
    • 6、在一級從節點上檢視狀態

一、什麼是redis主從複製

1、主從複製架構

主從複製,是指將一臺Redis伺服器的資料,複製到其他的Redis伺服器。前者稱為主節點(master),後者稱為從節點(slave)。

資料的複製是單向的,只能由主節點到從節點。

Redis Replication是一種 master-slave 模式的複製機制,這種機制使得 slave 節點可以成為與 master 節點完全相同的副本,可以採用一

主多從或者級聯結構。架構如下:

image-20240414214100524

  • 一個master可以有多個slave
  • 一個slave只能有一個master
  • 資料流向是單向的,master到slave

2、redis為什麼需要主從複製

使用redis主從複製的原因在於redis單臺節點存在以下問題:

(1)、Redis雖然讀寫的速度都很快,單節點的Redis能夠支撐QPS大概在5w左右,如果上千萬的使用者訪問,Redis就承載不了,成為了高併發的瓶頸。

(2)、單節點的Redis不能保證高可用,當Redis因為某些原因意外當機時,會導致快取不可用

(3)、CPU的利用率上,單臺Redis例項只能利用單個核心,這單個核心在面臨海量資料的存取和管理工作時壓力會非常大。

二、搭建主從複製

1、涉及主機

角色 主機名 IP地址
master master 192.168.112.40
slave slave1 192.168.112.50
slave slave2 192.168.112.60

2、編譯安裝redis

所有主機

2.1、獲取軟體安裝包,安裝編譯環境

yum install -y make gcc tcl
wget https://download.redis.io/releases/redis-5.0.9.tar.gz
tar xf redis-5.0.9.tar.gz

2.2、編譯安裝

cd redis-5.0.9/src/
make
make PREFIX=/apps/redis install

2.3、配置變數

echo "PATH=/apps/redis/bin:$PATH" > /etc/profile.d/redis.sh
. /etc/profile.d/redis.sh

2.4、驗證目錄結構

tree /apps/redis/

image-20240414221118668

2.5、準備目錄及檔案

mkdir /apps/redis/{etc,log,data,run}
cp ~/redis-5.0.9/redis.conf /apps/redis/etc/

3、前臺啟動redis

redis-server /apps/redis/etc/redis.conf

3.1、消除三個警告提示

不難發現,前臺啟動時會出現三個WARNING,預設情況, redis配置檔案的引數和核心引數不匹配, 因此還需要修改配置引數, 否則啟動時會有警告, 但是並不影響使用

echo "net.core.somaxconn = 1024" >> /etc/sysctl.conf
[root@master src]# sysctl -p
net.core.somaxconn = 1024
echo "vm.overcommit_memory=1" >> /etc/sysctl.conf
[root@master src]# sysctl -p
net.core.somaxconn = 1024
vm.overcommit_memory = 1
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo "echo never > /sys/kernel/mm/transparent_hugepage/enabled" >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local

再次啟動redis可以看到警告消除

redis-server /apps/redis/etc/redis.conf

image-20240414222918359

4、使用systemctl管理redis

4.1、建立redis使用者

useradd -r -s /sbin/nologin redis
chown -R redis.redis /apps/redis/

4.2、編輯redis服務啟動檔案

vim /lib/systemd/system/redis.service

[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart=/apps/redis/bin/redis-server /apps/redis/etc/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target

4.3、驗證redis啟動

reids的預設啟動埠是6379

systemctl daemon-reload
systemctl enable --now redis
ss -ntl

5、使用客戶端連線redis

  • 格式:

    redis-cli -h IP/HOSTNAME -p PORT -a PASSWORD
    
  • 連線例項:

    redis-cli
    127.0.0.1:6379> info
    127.0.0.1:6379> exit
    

6、設定登陸密碼、修改監聽地址、資料目錄、日誌,PID檔案路徑

6.1、修改配置檔案

 sed -i -e "s/bind 127.0.0.1/bind 0.0.0.0/" -e "/# requirepass/a requirepass centos" -e "/^dir .*/c dir /apps/redis/data/" -e "/logfile .*/c logfile /apps/reids/log/redis_6379.log" -e "/^pidfile .*/c pidfile /apps/redis/run/redis_6379.pid" /apps/redis/etc/redis.conf

6.2、重啟redis

systemctl restart redis
redis-cli
127.0.0.1:6379> info
NOAUTH Authentication required.
127.0.0.1:6379> auth centos
OK

7、建立命令軟連結

ln -s /apps/redis/bin/ /usr/bin/

8、啟用主從同步

  • 預設redis 狀態為master,需要轉換為slave角色並指向master伺服器的IP+PORT+Password
  • REPLICAOF MASTER_IP PORT 指令可以啟用主從同步複製功能,早期版本使用 SLAVEOF 指令

8.1、在master上設定key1

[root@master ~]# redis-cli -a centos
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_replid:f4efa528f4a3d63441a78ae714b3165a2c962fa4
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:6379> set key1 v1-master
OK
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> get key1
"v1-master"
127.0.0.1:6379>

8.2、slave登入設定key1

slave1

[root@slave1 ~]# redis-cli -a centos --no-auth-warning
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_replid:53bb55466d846a521874f723a093                                               512a4ebcd55b
master_replid2:000000000000000000000000000                                               0000000000000
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:6379> set key1 v1-slave1
OK
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> get key1
"v1-slave1"
127.0.0.1:6379>

slave2

[root@slave2 ~]# redis-cli -a centos --no-auth-warning
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_replid:ba138fa5f600850d0339b347f388                                               af2655504162
master_replid2:000000000000000000000000000                                               0000000000000
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:6379> set key1 v1-slave2
OK
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> get key1
"v1-slave2"
127.0.0.1:6379>

8.3、所有slave設定master的IP和埠

slave1:

127.0.0.1:6379> replicaof 192.168.112.40 6379
OK
127.0.0.1:6379> config set masterauth centos
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.112.40
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_repl_offset:0
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:2132feee25664555e9ef7b6c1d20d105ee308e3d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:0
127.0.0.1:6379> get key1
"v1-master"·

slave2:

127.0.0.1:6379> replicaof 192.168.112.40 6379
OK
127.0.0.1:6379> config set masterauth centos
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.112.40
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:70
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:2132feee25664555e9ef7b6c1d20d105ee308e3d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:70
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:57
repl_backlog_histlen:14
127.0.0.1:6379> get key1
"v1-master"

這裡特地在兩臺slave上設定不同的資料是為了驗證Slave 端切換master同步後會丟失之前的所有資料

8.4、master端驗證slave資訊

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.112.50,port=6379,state=online,offset=378,lag=1
slave1:ip=192.168.112.60,port=6379,state=online,offset=378,lag=1
master_replid:2132feee25664555e9ef7b6c1d20d105ee308e3d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:378
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:378

9、刪除主從同步

9.1、slave節點取消主從複製

REPLICAOF NO ONE 指令可以取消主從複製

在任意一臺slave上操作:

127.0.0.1:6379> replicaof no one
OK
127.0.0.1:6379> info replication
# Replication
role:master		#角色變為master
connected_slaves:0
master_replid:e8839adba5e81db5da86007a3b2bbdcc7d84de7d
master_replid2:2132feee25664555e9ef7b6c1d20d105ee308e3d
master_repl_offset:2464
second_repl_offset:2465
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:57
repl_backlog_histlen:2408

9.2、在master上驗證

可以看到slave數量減少為1

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.112.50,port=6379,state=online,offset=2492,lag=0
master_replid:2132feee25664555e9ef7b6c1d20d105ee308e3d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2492
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2492

10、同步日誌

10.1、各個節點上觀察日誌

master上:

[root@master ~]# tail /apps/redis/log/redis_6379.log
22618:M 15 Apr 2024 15:35:25.707 * Synchronization with replica 192.168.112.50:6379 succeeded
22618:M 15 Apr 2024 15:36:09.639 * Replica 192.168.112.60:6379 asks for synchronization
22618:M 15 Apr 2024 15:36:09.639 * Full resync requested by replica 192.168.112.60:6379
22618:M 15 Apr 2024 15:36:09.639 * Starting BGSAVE for SYNC with target: disk
22618:M 15 Apr 2024 15:36:09.639 * Background saving started by pid 22639
22639:C 15 Apr 2024 15:36:09.640 * DB saved on disk
22639:C 15 Apr 2024 15:36:09.640 * RDB: 0 MB of memory used by copy-on-write
22618:M 15 Apr 2024 15:36:09.647 * Background saving terminated with success
22618:M 15 Apr 2024 15:36:09.647 * Synchronization with replica 192.168.112.60:6379 succeeded
22618:M 15 Apr 2024 16:05:22.257 # Connection with replica 192.168.112.60:6379 lost.

slave節點:

[root@slave1 ~]# tail /apps/redis/log/redis_6379.log
12569:S 15 Apr 2024 15:35:25.702 * Connecting to MASTER 192.168.112.40:6379
12569:S 15 Apr 2024 15:35:25.702 * MASTER <-> REPLICA sync started
12569:S 15 Apr 2024 15:35:25.703 * Non blocking connect for SYNC fired the event.
12569:S 15 Apr 2024 15:35:25.703 * Master replied to PING, replication can continue...
12569:S 15 Apr 2024 15:35:25.703 * Partial resynchronization not possible (no cached master)
12569:S 15 Apr 2024 15:35:25.704 * Full resync from master: 2132feee25664555e9ef7b6c1d20d105ee308e3d:0
12569:S 15 Apr 2024 15:35:25.709 * MASTER <-> REPLICA sync: receiving 196 bytes from master
12569:S 15 Apr 2024 15:35:25.709 * MASTER <-> REPLICA sync: Flushing old data
12569:S 15 Apr 2024 15:35:25.709 * MASTER <-> REPLICA sync: Loading DB in memory
12569:S 15 Apr 2024 15:35:25.709 * MASTER <-> REPLICA sync: Finished with success

10.2、修改slave節點

slave1:

[root@slave1 ~]# echo "replicaof 192.168.112.40 6379" >> /apps/redis/etc/redis.conf
[root@slave1 ~]# echo "masterauth centos" >> /apps/redis/etc/redis.conf
[root@slave1 ~]# systemctl restart redis

slave2:

[root@slave2 ~]# echo "replicaof 192.168.112.40 6379" >> /apps/redis/etc/redis.conf
[root@slave2 ~]# echo "masterauth centos" >> /apps/redis/etc/redis.conf
[root@slave2 ~]# systemctl restart redis

10.3、登入檢視master和slave狀態

master:

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.112.50,port=6379,state=online,offset=4816,lag=0
slave1:ip=192.168.112.60,port=6379,state=online,offset=4816,lag=0

slave1:

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.112.40
master_port:6379
master_link_status:up

slave2:

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.112.40
master_port:6379
master_link_status:up

三、模擬master節點當機

1、停止master的redis服務

[root@master ~]# systemctl stop redis

slave節點觀察:

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.112.40
master_port:6379
master_link_status:down		#顯示down,表示無法連線master

2、觀察slave節點日誌

[root@slave1 ~]# tail /apps/redis/log/redis_6379.log
23515:S 15 Apr 2024 16:51:45.023 # Error condition on socket for SYNC: Connection refused
23515:S 15 Apr 2024 16:51:46.043 * Connecting to MASTER 192.168.112.40:6379
23515:S 15 Apr 2024 16:51:46.043 * MASTER <-> REPLICA sync started
23515:S 15 Apr 2024 16:51:46.043 # Error condition on socket for SYNC: Connection refused
23515:S 15 Apr 2024 16:51:47.055 * Connecting to MASTER 192.168.112.40:6379
23515:S 15 Apr 2024 16:51:47.056 * MASTER <-> REPLICA sync started
23515:S 15 Apr 2024 16:51:47.056 # Error condition on socket for SYNC: Connection refused
23515:S 15 Apr 2024 16:51:48.078 * Connecting to MASTER 192.168.112.40:6379
23515:S 15 Apr 2024 16:51:48.078 * MASTER <-> REPLICA sync started
23515:S 15 Apr 2024 16:51:48.079 # Error condition on socket for SYNC: Connection refused

3、觀察slave狀態

[root@slave1 ~]# redis-cli -a centos
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> set key1 v1-slave1
(error) READONLY You can't write against a read only replica.
127.0.0.1:6379> get key1
"v1-master"

發現slave狀態只讀無法寫入資料

四、主從複製故障恢復

1、slave節點故障與恢復

client指向另一個從節點即可,並及時修復故障從節點

image-20240415171245751

2、master節點故障與恢復

需要提升slave為新的master

image-20240415171850225

master故障後,只能手動提升一個slave為新master,不支援自動切換。master的切換會導致master_replid發生變化,slave之前的master_replid就和當前master不一致從而會引發所有slave的全量同步

3、主從複製故障恢復實現

當前主從複製中master節點故障

[root@master ~]# systemctl stop redis

3.1、停止slave1主從同步並提升為新的master

slave1:

127.0.0.1:6379> replicaof no one
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_replid:a3bc41f15f4e2f0f701c452eeaf24a6080ade51c
master_replid2:2132feee25664555e9ef7b6c1d20d105ee308e3d
master_repl_offset:5488
second_repl_offset:5489
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:5488
127.0.0.1:6379> set keytest1 vtest1
OK

3.2、修改剩下的slave指向新的master節點

slave2:

127.0.0.1:6379> replicaof 192.168.175.20 6379
OK
127.0.0.1:6379> config set masterauth centos
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.112.50
master_port:6379
master_link_status:up
127.0.0.1:6379> set key100 v100
(error) READONLY You can't write against a read only replica.		#只讀
127.0.0.1:6379> get keytest1
"vtest1"

3.3、在新的master節點檢視slave資訊

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.112.60,port=6379,state=online,offset=5830,lag=1

五、實現redis的級聯複製

Redis 的級聯複製(Cascade Replication)是指在主從複製的基礎上,透過建立多級複製鏈路,使得一個 Redis 從節點不僅作為其直接主節點的副本,還能充當其他從節點的主節點。這種結構允許資料複製跨越多個層級,形成一種樹狀拓撲結構。

image-20240415180454175

1、涉及主機

角色 主機名 IP地址
主節點 master 192.168.112.10
一級從節點 slave1 192.168.112.20
二級從節點 slave2 192.168.112.30
二級從節點 slave3 192.168.112.40

2、所有主機安裝reids

3、搭建一主一從

3.1、主節點建立驗證資料

master:

[root@master ~]# redis-cli -a centos --no-auth-warning
127.0.0.1:6379> set key-test1 test1
OK
127.0.0.1:6379> keys *
1) "key-test1"
127.0.0.1:6379> get key-test1
"test1"

3.2、一級從節點設定master的IP和埠

slave1:

[root@slave1 ~]# redis-cli -a centos --no-auth-warning
127.0.0.1:6379> replicaof 192.168.112.10 6379
OK
127.0.0.1:6379> config set masterauth centos
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.112.10
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:14
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:c8e3d3769a39454be02a13bec0324b01b43c81b7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14
127.0.0.1:6379> get key-test1
"test1"

4、修改二級從節點指向一級從節點作為master

slave2:

[root@slave2 ~]# redis-cli -a centos --no-auth-warning
127.0.0.1:6379> replicaof 192.168.112.20 6379
OK
127.0.0.1:6379> config set masterauth centos
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.112.20
master_port:6379
master_link_status:up
127.0.0.1:6379> keys *
1) "key-test1"
127.0.0.1:6379> get key-test1
"test1"

slave3:

[root@slave3 ~]# redis-cli -a centos --no-auth-warning
127.0.0.1:6379> replicaof 192.168.112.20 6379
OK
127.0.0.1:6379> config set masterauth centos
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.112.20
master_port:6379
master_link_status:up
127.0.0.1:6379> keys *
1) "key-test1"
127.0.0.1:6379> get key-test1
"test1"

5、在master上設定key,觀察是否同步

127.0.0.1:6379> set name misaki
OK
127.0.0.1:6379> get name
"misaki"

5.1、在slave上進行驗證

127.0.0.1:6379> get name
"misaki"

image-20240415183751899

6、在一級從節點上檢視狀態

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.112.10
master_port:6379
master_link_status:up
master_last_io_seconds_ago:6	#最近一次與master通訊已經過去多少秒
master_sync_in_progress:0	#是否正在與master通訊
slave_repl_offset:1332		#當前同步的偏移量
slave_priority:100		 #slave優先順序,master故障後優先順序值越小越優先同步
slave_read_only:1
connected_slaves:2
slave0:ip=192.168.112.30,port=6379,state=online,offset=1332,lag=1
slave1:ip=192.168.112.40,port=6379,state=online,offset=1332,lag=1
master_replid:c8e3d3769a39454be02a13bec0324b01b43c81b7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1332
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1332

相關文章