- 一、什麼是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 節點完全相同的副本,可以採用一
主多從或者級聯結構。架構如下:
- 一個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/
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
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指向另一個從節點即可,並及時修復故障從節點
2、master節點故障與恢復
需要提升slave為新的master
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 從節點不僅作為其直接主節點的副本,還能充當其他從節點的主節點。這種結構允許資料複製跨越多個層級,形成一種樹狀拓撲結構。
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"
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