1 Redis集羣簡介
Redis集羣和高可用有幾種方式:其中一種是主從複製,實現數據的多機備份和讀操作的負載均衡。一主多從,主庫支持讀寫操作,從庫只支持讀。在主從複製基礎上,哨兵實現了自動化的故障恢復。通過哨兵監控主節點狀態,主節點宕機時自動切換到從節點。另外一種是集羣,多節點分片存儲,結合主從複製,實現故障切換。本例主要介紹主從複製加哨兵模式和集羣模式。
2 Redis配置規劃
2.1 Redis哨兵模式規劃
本次計劃使用兩台虛擬機進行Redis哨兵,每台虛擬機運行Redis節點一個、Redis哨兵服務一個。10.10.1.45上的Redis節點為初始的主節點、10.10.1.46上的Redis節點為初始的從節點。
| 服務器 | 服務器一 | 服務器二 |
|---|---|---|
| IP地址 | 10.10.1.45 | 10.10.1.46 |
| 安裝用户 | kylin(管理員) | |
| 安裝目錄 | /data/redis | |
| 節點數據目錄 | /data/redis/data | |
| 節點配置目錄 | /data/redis/conf | |
| 節點日誌目錄 | /data/redis/logs | |
| Redis端口 | 6379 | |
| Redis密碼 | 142857 | |
| 哨兵端口 | 26379 | |
| 哨兵密碼 | 無 | |
| 主從同步密碼 | 142857 | |
| 主從組名 | mymaster | |
2.2 Redis集羣模式規劃
本次計劃使用三台虛擬機進行Redis集羣,每台虛擬機運行集羣主、備節點各一個。三台服務器的節點遵循循環主備關係,即A服務器上的主節點對應備節點在B服務器上,B服務器上的主節點對應備節點在C服務器上,C服務器上的主節點對應備節點在A服務器上。
| 服務器 | 服務器一 | 服務器二 | 服務器三 |
|---|---|---|---|
| IP地址 | 10.10.1.41 | 10.10.1.42 | 10.10.1.43 |
| 安裝用户 | kylin(管理員) | ||
| 安裝目錄 | /data/redis | ||
| 主節點數據目錄 | /data/redis/data/6379 | ||
| 從節點數據目錄 | /data/redis/data/6380 | ||
| 節點配置目錄 | /data/redis/conf | ||
| 節點日誌目錄 | /data/redis/logs | ||
| 主節點端口 | 6379 | ||
| 從節點端口 | 6380 | ||
| Redis密碼 | 142857 | ||
| 主從同步密碼 | 142857 | ||
3 安裝Redis軟件
3.1 安裝版本説明
銀河麒麟V10的桌面版和高級服務器版的安裝體系差異較大,默認已經安裝的包也不同,因此在編譯Redis之前,銀河麒麟V10的桌面版和高級服務器版需要安裝不同的包。本例基於以下銀河麒麟版本建立。
Kylin-Desktop-V10-GFB-HWE-Release-020-X86_64
Kylin-Desktop-V10-GFB-020-Release-20.1.3-ARM64
Kylin-Server-V10-GFB-Release-030-X86_64
Kylin-Server-V10-GFB-030-Release-30.1.3-ARM64
3.2 麒麟V10桌面版(GFB)
3.2.1 安裝前準備
使用管理員用户,創建安裝文件目錄。
kylin@KL1:~$ mkdir Install
3.2.2 安裝g++
銀河麒麟V10國防桌面版使用源代碼編譯的方式安裝Redis,需要先安裝g++。銀河麒麟V10使用的gcc版本是9.3.0,g++也應使用相同的版本,需要安裝g++和libstdc++兩個包。可以從Ubuntu網站獲取“g++-9_9.3.0-10ubuntu2_amd64.deb”、“libstdc++-9-dev_9.3.0-10ubuntu2_amd64.deb”兩個包。
kylin@KL1:~$ gcc --version
gcc (Ubuntu 9.3.0-10kylin2) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
管理員賬户使用sudo dpkg -i命令安裝libstdc++和g++。
kylin@KL1:~/Install$ sudo dpkg -i libstdc++-9-dev_9.3.0-10ubuntu2_amd64.deb g++-9_9.3.0-10ubuntu2_amd64.deb
正在選中未選擇的軟件包 libstdc++-9-dev:amd64。
(正在讀取數據庫 ... 系統當前共安裝有 186622 個文件和目錄。)
準備解壓 libstdc++-9-dev_9.3.0-10ubuntu2_amd64.deb ...
正在解壓 libstdc++-9-dev:amd64 (9.3.0-10ubuntu2) ...
正在選中未選擇的軟件包 g++-9。
準備解壓 g++-9_9.3.0-10ubuntu2_amd64.deb ...
正在解壓 g++-9 (9.3.0-10ubuntu2) ...
正在設置 libstdc++-9-dev:amd64 (9.3.0-10ubuntu2) ...
正在設置 g++-9 (9.3.0-10ubuntu2) ...
正在處理用於 man-db (2.9.1-1kylin0k1) 的觸發器 ...
建立一個符號連接,把/usr/bin目錄下的x86_64-linux-gnu-g++-9鏈接到g++。
kylin@KL1:~/Install$ sudo ln -s /usr/bin/x86_64-linux-gnu-g++-9 /usr/bin/g++
3.2.3 安裝tcl
銀河麒麟V10國防桌面版使用源代碼編譯的方式安裝Redis,需要先安裝tcl。Redis8.2要求tcl版本8.5以上,需要安裝tcl和libtcl兩個包。從銀河麒麟網站獲取“libtcl8.6_8.6.10+dfsg-1_amd64.deb”包,從Ubuntu網站上獲取“tcl8.6_8.6.1-4ubuntu1_amd64.deb”包。
管理員賬户使用sudo dpkg -i命令安裝libtcl和tcl。
kylin@KL1:~/Install$ sudo dpkg -i libtcl8.6_8.6.10+dfsg-1_amd64.deb tcl8.6_8.6.1-4ubuntu1_amd64.deb
正在選中未選擇的軟件包 libtcl8.6:amd64。
(正在讀取數據庫 ... 系統當前共安裝有 187471 個文件和目錄。)
準備解壓 libtcl8.6_8.6.10+dfsg-1_amd64.deb ...
正在解壓 libtcl8.6:amd64 (8.6.10+dfsg-1) ...
正在選中未選擇的軟件包 tcl8.6。
準備解壓 tcl8.6_8.6.1-4ubuntu1_amd64.deb ...
正在解壓 tcl8.6 (8.6.1-4ubuntu1) ...
正在設置 libtcl8.6:amd64 (8.6.10+dfsg-1) ...
正在設置 tcl8.6 (8.6.1-4ubuntu1) ...
正在處理用於 libc-bin (2.31-0kylin9.1k20.8) 的觸發器 ...
正在處理用於 man-db (2.9.1-1kylin0k1) 的觸發器 ...
3.3 銀河麒麟高級服務器版(GFB)
3.3.1 安裝前準備
銀河麒麟V10高級服務器版,允許使用root直接登錄,這裏安全起見,創建用户kylin並加入wheel組,作為管理員用户使用。
[root@localhost ~]# adduser kylin
[root@localhost ~]# passwd kylin
更改用户 kylin 的密碼 。
新的 密碼:
重新輸入新的 密碼:
passwd:所有的身份驗證令牌已經成功更新。
[root@localhost ~]# usermod -aG wheel kylin
再使用root用户創建/data共享目錄。
[root@localhost ~]# mkdir /data
[root@localhost ~]# chmod a+rwx /data
[root@localhost ~]# chmod -t /data
使用root用户修改主機名,並重新登錄。
[root@localhost ~]# hostnamectl set-hostname KL1
[root@localhost ~]# logout
使用kylin用户創建目錄Install用於放置所有安裝文件。
[kylin@KL1 ~]$ mkdir Install
3.4 編譯Redis
解壓縮redis-8.2.1.tar.gz包。
kylin@KL1:~/Install$ tar -zxf redis-8.2.1.tar.gz
進入redis解壓後目錄下的deps目錄,運行make fast_float和make jemalloc。銀河麒麟高級服務器版不需要此步驟。
kylin@KL1:~/Install$ cd redis-8.2.1/deps/
kylin@KL1:~/Install/redis-8.2.1/deps$ make fast_float
MAKE fast_float
cd fast_float && make libfast_float CFLAGS="" LDFLAGS=""
make[1]: 進入目錄“/home/kylin/redis-8.2.1/deps/fast_float”
g++ -Wall -O3 -std=c++11 -DFASTFLOAT_ALLOWS_LEADING_PLUS -c fast_float_strtod.cpp
ar -r libfast_float.a fast_float_strtod.o
ar: 正在創建 libfast_float.a
make[1]: 離開目錄“/home/kylin/Install/redis-8.2.1/deps/fast_float”
kylin@KL1:~/Install/redis-8.2.1/deps$ make jemalloc
MAKE jemalloc
cd jemalloc && ./configure --disable-cxx --with-version=5.3.0-0-g0 --with-lg-quantum=3 --disable-cache-oblivious --with-jemalloc-prefix=je_ CFLAGS="" LDFLAGS=""
checking for xsltproc... false
checking for gcc... gcc
…………
這裏有很多提示信息,此處省略。
…………
make[1]: 離開目錄“/home/kylin/Install/redis-8.2.1/deps/jemalloc”
進入redis解壓後目錄,使用make指令編譯Redis。
kylin@KL1:~/Install/redis-8.2.1/deps$ cd ..
kylin@KL1:~/Install/redis-8.2.1$ make
for dir in src; do make -C $dir all; done
make[1]: 進入目錄“/home/kylin/Install/redis-8.2.1/src”
CC Makefile.dep
rm -rf redis-server redis-sentinel redis-cli redis-benchmark redis-check-rdb redis-check-aof *.o *.gcda *.gcno *.gcov redis.info lcov-html Makefile.dep *.so
…………
這裏有很多提示信息,此處省略。
…………
LINK redis-benchmark
INSTALL redis-check-rdb
INSTALL redis-check-aof
Hint: It's a good idea to run 'make test' ;)
make[1]: 離開目錄“/home/kylin/Install/redis-8.2.1/src”
使用make test指令進行測試。
kylin@KL1:~/Install/redis-8.2.1$ make test
for dir in src; do make -C $dir test; done
make[1]: 進入目錄“/home/kylin/Install/redis-8.2.1/src”
Cleanup: may take some time... OK
Starting test server at port 21079
[ready]: 387245
Testing unit/acl-v2
…………
這裏有很多提示信息,此處省略。
…………
515 seconds - defrag
0 seconds - list-large-memory
1 seconds - set-large-memory
\o/ All tests passed without errors!
Cleanup: may take some time... OK
make[1]: 離開目錄“/home/kylin/Install/redis-8.2.1/src”
3.5 安裝Redis
按照規劃創建redis目錄。(哨兵模式不需要創建6380目錄)。
kylin@KL1:~/Install/redis-8.2.1$ mkdir /data/redis
kylin@KL1:~/Install/redis-8.2.1$ mkdir /data/redis/data
kylin@KL1:~/Install/redis-8.2.1$ mkdir /data/redis/data/6379
kylin@KL1:~/Install/redis-8.2.1$ mkdir /data/redis/data/6380
kylin@KL1:~/Install/redis-8.2.1$ mkdir /data/redis/conf
kylin@KL1:~/Install/redis-8.2.1$ mkdir /data/redis/logs
使用make install指令進行安裝,使用PREFIX參數指定安裝目錄。
kylin@KL1:~/Install/redis-8.2.1$ make install PREFIX=/data/redis
for dir in src; do make -C $dir install; done
make[1]: 進入目錄“/home/kylin/Install/redis-8.2.1/src”
Hint: It's a good idea to run 'make test' ;)
INSTALL redis-server
INSTALL redis-benchmark
INSTALL redis-cli
make[1]: 離開目錄“/home/kylin/Install/redis-8.2.1/src”
修改配置文件,加入REDIS_HOME環境變量,擴充PATH環境變量。
kylin@KL1:~/Install/redis-8.2.1$ sudo vi /etc/profile
…………
原有的配置信息。
…………
export REDIS_HOME=/data/redis
export PATH=$PATH:$REDIS_HOME/bin
在另外兩台服務器上同樣安裝Redis。注意,銀河麒麟V10高級服務器版默認已經安裝了Redis 4.0.11版,如果直接輸入redis-server、redis-cli會默認調用Redis 4.0.11版的相應程序,因此在後續配置時需要指明程序目錄,如:“/data/redis/bin/redis-server”、“/data/redis/bin/redis-cli”。
4 配置Redis哨兵模式
4.1 開放防火牆端口
麒麟高級服務器版默認開啓了防火牆,需要開放規劃的Redis相關的端口,包括6379、26379等,以上端口均為TCP協議。
kylin@KL5 ~$ sudo firewall-cmd --add-port=6379/tcp --permanent
success
kylin@KL5 ~$ sudo firewall-cmd --add-port=26379/tcp --permanent
success
kylin@KL5 ~$ sudo firewall-cmd --reload
success
kylin@KL5 ~$ sudo firewall-cmd --list-ports
6379/tcp 26379/tcp
4.2 修改配置文件
從redis解壓後目錄複製文件redis.conf到“/data/redis/conf/”目錄並改名為redis_6379.conf,從redis解壓後目錄複製文件sentinel.conf到“/data/redis/conf/”目錄。
kylin@KL5:~/Install/redis-8.2.1$ cp redis.conf /data/redis/conf/redis_6379.conf
kylin@KL5:~/Install/redis-8.2.1$ cp sentinel.conf /data/redis/conf/
kylin@KL5:~/Install/redis-8.2.1$ cd /data/redis/conf/
修改每台服務器上的配置文件redis_6379.conf中以下內容。
kylin@KL5:/data/redis/conf$ vi redis_6379.conf
# 監聽所有網絡,默認127.0.0.1。
bind 0.0.0.0
# 監聽端口。
port 6379
# 允許後台運行。
daemonize yes
# PID 存放路徑。
pidfile /data/redis/redis_6379.pid
# 日誌存放路徑。
logfile /data/redis/logs/redis_6379.log
# 數據目錄。
dir /data/redis/data/6379
# 主服務器地址,只在從機上配置。
replicaof 10.10.1.45 6379
# 主從同步master的密碼。
masterauth 142857
# Redis密碼。
requirepass 142857
修改每台服務器上的配置文件sentinel.conf中以下內容。其中最少切換哨兵數量為最少幾個哨兵認為主服務器不可用時,就啓動切換。如果是三台服務器集羣,則此值應為2。
kylin@KL5:/data/redis/conf$ vi sentinel.conf
# 禁用保護模式。
protected-mode no
# 允許後台運行。
daemonize yes
# PID 存放路徑。
pidfile /data/redis/sentinel.pid
# 日誌存放路徑。
logfile /data/redis/logs/sentinel.log
# 哨兵監控集羣名稱、主機地址、主機端口、最少切換哨兵數量。
sentinel monitor mymaster 10.10.1.45 6379 1
# 哨兵的認證密碼。
sentinel auth-pass mymaster 142857
啓動Redis服務和哨兵服務,啓動順序為主Redis服務、從Redis服務、主從哨兵服務。
kylin@KL5:~$ redis-server /data/redis/conf/redis_6379.conf
kylin@KL6:~$ redis-server /data/redis/conf/redis_6379.conf
kylin@KL5:~$ redis-sentinel /data/redis/conf/sentinel.conf
kylin@KL6:~$ redis-sentinel /data/redis/conf/sentinel.conf
4.3 測試主從複製
使用客户端工具連接主機,插入一條數據。
使用客户端工具連接從機,可以看到從主機插入的數據。
使用客户端工具連接從機,插入數據,會報只讀錯誤。
使用客户端工具連接哨兵,可以正常插入數據。
4.4 測試主從切換
在任意一台主機上使用redis-cli連接主機節點查看主從信息。
[kylin@KL5 ~]$ /data/redis/bin/redis-cli -a 142857 -h 10.10.1.45 -p 6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.10.1.45:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.10.1.46,port=6379,state=online,offset=625523,lag=0
master_failover_state:no-failover
master_replid:32d947d15baa4b28ab4c2c7d7611c806071497f5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:625791
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:625791
在任意一台主機上使用redis-cli連接從機節點查看主從信息。
[[kylin@KL6 ~]$ /data/redis/bin/redis-cli -a 142857 -h 10.10.1.46 -p 6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.10.1.46:6379> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_read_repl_offset:598455
slave_repl_offset:598455
replica_full_sync_buffer_size:0
replica_full_sync_buffer_peak:0
master_current_sync_attempts:172
master_total_sync_attempts:172
master_link_down_since_seconds:173
total_disconnect_time_sec:2362
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:32d947d15baa4b28ab4c2c7d7611c806071497f5
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:598455
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:574
repl_backlog_histlen:597882
測試使用暫停虛擬機的方法模擬主機節點故障,本次模擬10.10.1.45故障。此時發生主從切換。通過查看從機上的日誌可以看到切換過程。
[kylin@KL6 ~]$ tail -f /data/redis/logs/redis_6379.log
1316020:M 25 Sep 2025 17:53:24.248 * Connection with master lost.
1316020:M 25 Sep 2025 17:53:24.248 * Caching the disconnected master state.
1316020:M 25 Sep 2025 17:53:24.248 * Discarding previously cached master state.
1316020:M 25 Sep 2025 17:53:24.248 * Setting secondary replication ID to 32d947d15baa4b28ab4c2c7d7611c806071497f5, valid up to offset: 730848. New replication ID is 6953fb9624393785ffb6185768aa6a31da91a90a
1316020:M 25 Sep 2025 17:53:24.248 * MASTER MODE enabled (user request from 'id=2650 addr=10.10.1.46:54626 laddr=10.10.1.46:6379 fd=12 name=sentinel-5b7103f3-cmd age=313 idle=0 flags=x db=0 sub=0 psub=0 ssub=0 multi=4 watch=0 qbuf=188 qbuf-free=20286 argv-mem=4 multi-mem=169 rbs=2048 rbp=1024 obl=45 oll=0 omem=0 tot-mem=23717 events=r cmd=exec user=default redir=-1 resp=2 lib-name= lib-ver= io-thread=0 tot-net-in=28007 tot-net-out=1192513 tot-cmds=645')
1316020:M 25 Sep 2025 17:53:24.257 * CONFIG REWRITE executed with success.
此時,使用客户端工具連接原從機,插入數據,可以正常插入。
此時連接原從機節點,查看主從信息,顯示原從機節點自動升級為主機節點。
[kylin@KL6 ~]$ /data/redis/bin/redis-cli -a 142857 -h 10.10.1.46 -p 6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.10.1.46:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:6953fb9624393785ffb6185768aa6a31da91a90a
master_replid2:32d947d15baa4b28ab4c2c7d7611c806071497f5
master_repl_offset:750613
second_repl_offset:730848
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:574
repl_backlog_histlen:750040
將10.10.1.45恢復,再次查看原從機日誌消息,可以看到10.10.1.45已經上線,但成為從機。
[kylin@KL6 ~]$ tail -f /data/redis/logs/redis_6379.log
1316020:M 25 Sep 2025 17:59:39.617 * Replica 10.10.1.45:6379 asks for synchronization
1316020:M 25 Sep 2025 17:59:39.617 * Partial resynchronization not accepted: Requested offset for second ID was 736647, but I can reply up to 730848
1316020:M 25 Sep 2025 17:59:39.617 * Replica 10.10.1.45:6379 is capable of rdb channel synchronization, and partial sync isn't possible. Full sync will continue with dedicated rdb channel.
1316020:M 25 Sep 2025 17:59:39.618 * Replica 10.10.1.45:6379 asks for synchronization
1316020:M 25 Sep 2025 17:59:39.618 * Full resync requested by replica 10.10.1.45:6379 (rdb-channel)
1316020:M 25 Sep 2025 17:59:39.618 * Delay next BGSAVE for diskless SYNC
1316020:M 25 Sep 2025 17:59:44.655 * Starting BGSAVE for SYNC with target: replicas sockets (rdb-channel)
1316020:M 25 Sep 2025 17:59:44.655 * Starting to deliver RDB and replication stream to replica: 10.10.1.45:6379
1316020:M 25 Sep 2025 17:59:44.655 * Background RDB transfer started by pid 1394719 to replica socket
1394719:C 25 Sep 2025 17:59:44.657 * Fork CoW for RDB: current 2 MB, peak 2 MB, average 2 MB
1316020:M 25 Sep 2025 17:59:44.668 * Connection with replica (rdbchannel) 10.10.1.45:6379 lost.
1316020:M 25 Sep 2025 17:59:44.668 * Synchronization with replica 10.10.1.45:6379 succeeded
1316020:M 25 Sep 2025 17:59:44.756 * Background RDB transfer terminated with success
[kylin@KL6 ~]$ /data/redis/bin/redis-cli -a 142857 -h 10.10.1.46 -p 6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.10.1.46:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.10.1.45,port=6379,state=online,offset=759951,lag=0
master_failover_state:no-failover
master_replid:6953fb9624393785ffb6185768aa6a31da91a90a
master_replid2:32d947d15baa4b28ab4c2c7d7611c806071497f5
master_repl_offset:760086
second_repl_offset:730848
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:574
repl_backlog_histlen:759513
4.5 註冊系統服務
使用管理員賬户,創建服務描述文件redis_6379.service。
kylin@KL5:~$ sudo vi /etc/systemd/system/redis_6379.service
# 基本信息。
[Unit]
Description=Redis Server 6379
After=network.target
Wants=network.target
# 服務設置。
[Service]
# 啓動和停止命令。
Type=forking
ExecStart=/data/redis/bin/redis-server /data/redis/conf/redis_6379.conf
ExecStop=/data/redis/bin/redis-cli -a 142857 -h 127.0.0.1 -p 6379 shutdown
# 運行用户與權限。
User=kylin
Group=kylin
# 服務生命週期管理。
Restart=on-failure
RestartSec=30s
StartLimitInterval=10
# 日誌設置。
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=redis-6379
# 資源限制。
LimitNOFILE=65536
MemoryMax=16G
# 安裝分類。
[Install]
WantedBy=multi-user.target
使用管理員賬户,創建服務描述文件redis_sentinel.service。
kylin@KL5:~$ sudo vi /etc/systemd/system/redis_sentinel.service
# 基本信息。
[Unit]
Description=Redis Sentinel
After=network.target
Wants=network.target
# 服務設置。
[Service]
# 啓動和停止命令。
Type=forking
ExecStart=/data/redis/bin/redis-sentinel /data/redis/conf/sentinel.conf
ExecStop=/data/redis/bin/redis-cli -h 127.0.0.1 -p 26379 shutdown
# 運行用户與權限。
User=kylin
Group=kylin
# 服務生命週期管理。
Restart=on-failure
RestartSec=30s
StartLimitInterval=10
# 日誌設置。
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=redis-sentinel
# 資源限制。
LimitNOFILE=65536
MemoryMax=16G
# 安裝分類。
[Install]
WantedBy=multi-user.target
使用systemctl daemon-reload加載服務,使用systemctl enable設置服務自啓動,使用systemctl start啓動服務。
kylin@KL5:~$ sudo systemctl daemon-reload
kylin@KL5:~$ sudo systemctl enable redis_6379
Created symlink /etc/systemd/system/multi-user.target.wants/redis_6379.service → /etc/systemd/system/redis_6379.service.
kylin@KL1:~$ sudo systemctl enable redis_sentinel
Created symlink /etc/systemd/system/multi-user.target.wants/redis_sentinel.service → /etc/systemd/system/redis_sentinel.service.
kylin@KL1:~$ sudo systemctl start redis_6379
kylin@KL1:~$ sudo systemctl start redis_sentinel
可以使用systemctl status查看服務狀態,也可以查看日誌確定服務是否正常啓動。
5 配置Redis集羣模式
5.1 開放防火牆端口
麒麟高級服務器版默認開啓了防火牆,需要開放規劃的Redis相關的端口,包括6379、6380、16379、16380等,以上端口均為TCP協議。
kylin@KL1 ~$ sudo firewall-cmd --add-port=6379/tcp --permanent
success
kylin@KL1 ~$ sudo firewall-cmd --add-port=6380/tcp --permanent
success
kylin@KL1 ~$ sudo firewall-cmd --add-port=16379/tcp --permanent
success
kylin@KL1 ~$ sudo firewall-cmd --add-port=16380/tcp --permanent
success
kylin@KL1 ~$ sudo firewall-cmd --reload
success
kylin@KL1 ~$ sudo firewall-cmd --list-ports
6379/tcp 6380/tcp 16379/tcp 16380/tcp
5.2 修改配置文件
從redis解壓後目錄複製redis.conf到/data/redis/conf/目錄並改名為redis_6379.conf。
kylin@KL1:~/Install/redis-8.2.1$ cp redis.conf /data/redis/conf/redis_6379.conf
kylin@KL1:~/Install/redis-8.2.1$ cd /data/redis/conf/
修改配置文件redis_6379.conf中以下內容。
kylin@KL1:/data/redis/conf$ vi redis_6379.conf
# 監聽所有網絡,默認127.0.0.1。
bind 0.0.0.0
# 監聽端口,主為6379,從為6380。
port 6379
# 允許後台運行。
daemonize yes
# PID 存放路徑。
pidfile /data/redis/redis_6379.pid
# 日誌存放路徑。
logfile /data/redis/logs/redis_6379.log
# 數據目錄。
dir /data/redis/data/6379
# 主從同步master的密碼。
masterauth 142857
# Redis密碼。
requirepass 142857
# 接收後數據寫入 appendonly.aof 文件。
appendonly yes
# 開啓集羣。
cluster-enabled yes
# 集羣配置文件,由Redis自動生成。
cluster-config-file /data/redis/conf/nodes_6379.conf
# 節點互連超時的閥值,單位毫秒。
cluster-node-timeout 15000
# 允許部分槽不可用
cluster-require-full-coverage no
將配置文件redis_6379.conf複製一份為redis_6380.conf,修改文件內容如下。
kylin@KL1:/data/redis/conf$ cp redis_6379.conf redis_6380.conf
kylin@KL1:/data/redis/conf$ vi redis_6380.conf
# 監聽所有網絡,默認127.0.0.1。
bind 0.0.0.0
# 監聽端口,主為6379,從為6380。
port 6380
# 允許後台運行。
daemonize yes
# PID 存放路徑。
pidfile /data/redis/redis_6380.pid
# 日誌存放路徑。
logfile /data/redis/logs/redis_6380.log
# 數據目錄。
dir /data/redis/data/6380
# 主從同步master的密碼。
masterauth 142857
# Redis密碼。
requirepass 142857
# 接收後數據寫入 appendonly.aof 文件。
appendonly yes
# 開啓集羣。
cluster-enabled yes
# 集羣配置文件,由Redis自動生成。
cluster-config-file /data/redis/conf/nodes_6380.conf
# 節點互連超時的閥值,單位毫秒。
cluster-node-timeout 15000
# 允許部分槽不可用。
cluster-require-full-coverage no
啓動Redis服務。
kylin@KL1:~$ redis-server /data/redis/conf/redis_6379.conf
kylin@KL1:~$ redis-server /data/redis/conf/redis_6380.conf
將配置文件redis_6379.conf、redis_6380.conf複製到另外兩台服務器。
kylin@KL1:~$ scp /data/redis/conf/redis_6379.conf kylin@10.10.1.42:/data/redis/conf/
redis_6379.conf 100% 109KB 56.8MB/s 00:00
kylin@KL1:~$ scp /data/redis/conf/redis_6379.conf kylin@10.10.1.43:/data/redis/conf/
redis_6379.conf 100% 109KB 67.9MB/s 00:00
kylin@KL1:~$ scp /data/redis/conf/redis_6380.conf kylin@10.10.1.42:/data/redis/conf/
redis_6380.conf 100% 109KB 56.8MB/s 00:00
kylin@KL1:~$ scp /data/redis/conf/redis_6380.conf kylin@10.10.1.43:/data/redis/conf/
redis_6380.conf 100% 109KB 67.9MB/s 00:00
啓動另外兩台服務器上的Redis服務。
5.3 創建集羣節點
在其中一台服務器上使用redis-cli創建主節點,系統自動分配槽,接受即可。
kylin@KL1:~$ redis-cli -a 142857 --cluster create 10.10.1.41:6379 10.10.1.42:6379 10.10.1.43:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 3 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
M: e2b6cc1f2f3977bc37ee9bffbf860edc26274cf6 10.10.1.41:6379
slots:[0-5460] (5461 slots) master
M: af75957d10c763cca25ce38418d4ebcc9109b414 10.10.1.42:6379
slots:[5461-10922] (5462 slots) master
M: a16d534d6abde9dd91e0288081b009f136cec20e 10.10.1.43:6379
slots:[10923-16383] (5461 slots) master
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 10.10.1.41:6379)
M: e2b6cc1f2f3977bc37ee9bffbf860edc26274cf6 10.10.1.41:6379
slots:[0-5460] (5461 slots) master
M: a16d534d6abde9dd91e0288081b009f136cec20e 10.10.1.43:6379
slots:[10923-16383] (5461 slots) master
M: af75957d10c763cca25ce38418d4ebcc9109b414 10.10.1.42:6379
slots:[5461-10922] (5462 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
為每個主節點循環增加對應的從節點,如為A主節點增加b從節點,為B主節點增加c從節點,為C主節點增加a從節點。
將10.10.1.42:6380添加為10.10.1.41:6379的從節點。
kylin@KL1:~$ redis-cli -a 142857 --cluster add-node 10.10.1.42:6380 10.10.1.41:6379 --cluster-slave --cluster-master-id e2b6cc1f2f3977bc37ee9bffbf860edc26274cf6
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Adding node 10.10.1.42:6380 to cluster 10.10.1.41:6379
>>> Performing Cluster Check (using node 10.10.1.41:6379)
M: e2b6cc1f2f3977bc37ee9bffbf860edc26274cf6 10.10.1.41:6379
slots:[0-5460] (5461 slots) master
M: af75957d10c763cca25ce38418d4ebcc9109b414 10.10.1.42:6379
slots:[5461-10922] (5462 slots) master
M: a16d534d6abde9dd91e0288081b009f136cec20e 10.10.1.43:6379
slots:[10923-16383] (5461 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 10.10.1.42:6380 to make it join the cluster.
Waiting for the cluster to join
>>> Configure node as replica of 10.10.1.41:6379.
[OK] New node added correctly.
將10.10.1.43:6380添加為10.10.1.42:6379的從節點。
kylin@KL1:~$ redis-cli -a 142857 --cluster add-node 10.10.1.43:6380 10.10.1.42:6379 --cluster-slave --cluster-master-id af75957d10c763cca25ce38418d4ebcc9109b414
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Adding node 10.10.1.43:6380 to cluster 10.10.1.42:6379
>>> Performing Cluster Check (using node 10.10.1.42:6379)
M: af75957d10c763cca25ce38418d4ebcc9109b414 10.10.1.42:6379
slots:[5461-10922] (5462 slots) master
S: 02c659db7838cdc9c77a3bb6be3bc944b3c69579 10.10.1.42:6380
slots: (0 slots) slave
replicates e2b6cc1f2f3977bc37ee9bffbf860edc26274cf6
M: e2b6cc1f2f3977bc37ee9bffbf860edc26274cf6 10.10.1.41:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: a16d534d6abde9dd91e0288081b009f136cec20e 10.10.1.43:6379
slots:[10923-16383] (5461 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 10.10.1.43:6380 to make it join the cluster.
Waiting for the cluster to join
>>> Configure node as replica of 10.10.1.42:6379.
[OK] New node added correctly.
將10.10.1.41:6380添加為10.10.1.43:6379的從節點。
kylin@KL1:~$ redis-cli -a 142857 --cluster add-node 10.10.1.41:6380 10.10.1.43:6379 --cluster-slave --cluster-master-id a16d534d6abde9dd91e0288081b009f136cec20e
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Adding node 10.10.1.41:6380 to cluster 10.10.1.43:6379
>>> Performing Cluster Check (using node 10.10.1.43:6379)
M: a16d534d6abde9dd91e0288081b009f136cec20e 10.10.1.43:6379
slots:[10923-16383] (5461 slots) master
M: af75957d10c763cca25ce38418d4ebcc9109b414 10.10.1.42:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 02c659db7838cdc9c77a3bb6be3bc944b3c69579 10.10.1.42:6380
slots: (0 slots) slave
replicates e2b6cc1f2f3977bc37ee9bffbf860edc26274cf6
S: 5e9a0509562217da0f8e62cee8c8c25b309d57b8 10.10.1.43:6380
slots: (0 slots) slave
replicates af75957d10c763cca25ce38418d4ebcc9109b414
M: e2b6cc1f2f3977bc37ee9bffbf860edc26274cf6 10.10.1.41:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 10.10.1.41:6380 to make it join the cluster.
Waiting for the cluster to join
>>> Configure node as replica of 10.10.1.43:6379.
[OK] New node added correctly.
在任意一台主機上使用redis-cli連接任意一個節點使用cluster info查看集羣信息,使用cluster nodes查看集羣節點。
kylin@KL1:~$ redis-cli -a 142857 -h 10.10.1.41 -p 6379 -c
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.10.1.41:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:3
cluster_my_epoch:1
cluster_stats_messages_ping_sent:235
cluster_stats_messages_pong_sent:229
cluster_stats_messages_sent:464
cluster_stats_messages_ping_received:228
cluster_stats_messages_pong_received:233
cluster_stats_messages_meet_received:1
cluster_stats_messages_received:462
total_cluster_links_buffer_limit_exceeded:0
10.10.1.41:6379> cluster nodes
5e9a0509562217da0f8e62cee8c8c25b309d57b8 10.10.1.43:6380@16380 slave af75957d10c763cca25ce38418d4ebcc9109b414 0 1758097783000 2 connected
af75957d10c763cca25ce38418d4ebcc9109b414 10.10.1.42:6379@16379 master - 0 1758097784000 2 connected 5461-10922
eb3f6e4a86a4c5ccfd779e7eb8ed0d795f89546c 10.10.1.41:6380@16380 slave a16d534d6abde9dd91e0288081b009f136cec20e 0 1758097784560 3 connected
02c659db7838cdc9c77a3bb6be3bc944b3c69579 10.10.1.42:6380@16380 slave e2b6cc1f2f3977bc37ee9bffbf860edc26274cf6 0 1758097785564 1 connected
e2b6cc1f2f3977bc37ee9bffbf860edc26274cf6 10.10.1.41:6379@16379 myself,master - 0 0 1 connected 0-5460
a16d534d6abde9dd91e0288081b009f136cec20e 10.10.1.43:6379@16379 master - 0 1758097784000 3 connected 10923-16383
10.10.1.41:6379> quit
5.4 測試集羣複製
使用客户端工具測試集羣效果。
5.5 測試集羣切換
在任意一台主機上使用redis-cli連接任意一個節點查看集羣信息(示例中為了顯示清晰,縮寫了節點ID)。可以看出現在節點10.10.1.41:6379、10.10.1.42:6379、10.10.1.43:6379是主節點,10.10.1.41:6380、10.10.1.42:6380、10.10.1.43:6380是從節點。
kylin@KL1:~$ redis-cli -a 142857 -h 10.10.1.41 -p 6379 -c cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
e2……f6 10.10.1.41:6379@16379 myself,master - 0 0 1 connected 0-5460
af……14 10.10.1.42:6379@16379 master - 0 1758101546000 2 connected 5461-10922
a1……0e 10.10.1.43:6379@16379 master - 0 1758101544000 5 connected 10923-16383
eb……6c 10.10.1.41:6380@16380 slave a1……0e 0 1758101546975 5 connected
02……79 10.10.1.42:6380@16380 slave e2……f6 0 1758101545000 1 connected
5e……b8 10.10.1.43:6380@16380 slave af……14 0 1758101544966 2 connected
測試使用暫停虛擬機的方法模擬服務器故障,本次模擬10.10.1.43故障。此時向Redis集羣中插入數據,發現耗時很久,系統正在進行集羣切換。
此時查看查看集羣信息,顯示10.10.1.43:6379、10.10.1.43:6380已經失效,10.10.1.41:6380自動升級為主節點。
kylin@KL1:~$ redis-cli -a 142857 -h 10.10.1.41 -p 6379 -c cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
e2……f6 10.10.1.41:6379@16379 myself,master - 0 0 1 connected 0-5460
af……14 10.10.1.42:6379@16379 master - 0 1758102319735 2 connected 5461-10922
a1……0e 10.10.1.43:6379@16379 master,fail - 1758102089620 1758102087000 7 connected
eb……6c 10.10.1.41:6380@16380 master - 0 1758102320000 8 connected 10923-16383
02……79 10.10.1.42:6380@16380 slave e2……f6 0 1758102320739 1 connected
5e……b8 10.10.1.43:6380@16380 slave,fail af……14 1758102091629 1758102087610 2 connecte
將10.10.1.43恢復,再次查看集羣消息,可以看到10.10.1.43:6379、10.10.1.43:6380均為從節點。
kylin@KL1:~$ redis-cli -a 142857 -h 10.10.1.41 -p 6379 -c cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
e2……f6 10.10.1.41:6379@16379 myself,master - 0 0 1 connected 0-5460
af……14 10.10.1.42:6379@16379 master - 0 1758102599089 2 connected 5461-10922
a1……0e 10.10.1.43:6379@16379 slave eb……6c 0 1758102597000 8 connected
eb……6c 10.10.1.41:6380@16380 master - 0 1758102597079 8 connected 10923-16383
02……79 10.10.1.42:6380@16380 slave e2……f6 0 1758102597000 1 connected
5e……b8 10.10.1.43:6380@16380 slave af……14 0 1758102598084 2 connected
此時用redis-cli連接10.10.1.43:6379,將其還原為主節點。
kylin@KL1:~$ redis-cli -a 142857 -h 10.10.1.43 -p 6379 -c cluster failover
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
OK
kylin@KL1:~$ redis-cli -a 142857 -h 10.10.1.41 -p 6379 -c cluster nodes
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
e2……f6 10.10.1.41:6379@16379 myself,master - 0 0 1 connected 0-5460
af……14 10.10.1.42:6379@16379 master - 0 1758102761000 2 connected 5461-10922
a1……0e 10.10.1.43:6379@16379 master - 0 1758102761892 9 connected 10923-16383
eb……6c 10.10.1.41:6380@16380 slave a1……0e 0 1758102762896 9 connected
02……79 10.10.1.42:6380@16380 slave e2……f6 0 1758102759883 1 connected
5e……b8 10.10.1.43:6380@16380 slave af……14 0 1758102760000 2 connected
5.6 註冊系統服務
使用管理員賬户,創建服務描述文件redis_6379.service、redis_6380.service。
kylin@KL1:~$ sudo vi /etc/systemd/system/redis_6379.service
# 基本信息。
[Unit]
Description=Redis Master 6379
After=network.target
Wants=network.target
# 服務設置。
[Service]
# 啓動和停止命令。
Type=forking
ExecStart=/data/redis/bin/redis-server /data/redis/conf/redis_6379.conf
ExecStop=/data/redis/bin/redis-cli -a 142857 -h 127.0.0.1 -p 6379 shutdown
# 運行用户與權限。
User=kylin
Group=kylin
# 服務生命週期管理。
Restart=on-failure
RestartSec=30s
StartLimitInterval=10
# 日誌設置。
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=redis-6379
# 資源限制。
LimitNOFILE=65536
MemoryMax=16G
# 安裝分類。
[Install]
WantedBy=multi-user.target
使用systemctl daemon-reload加載服務,使用systemctl enable設置服務自啓動,使用systemctl start啓動服務。
kylin@KL1:~$ sudo systemctl daemon-reload
kylin@KL1:~$ sudo systemctl enable redis_6379
Created symlink /etc/systemd/system/multi-user.target.wants/redis_6379.service → /etc/systemd/system/redis_6379.service.
kylin@KL1:~$ sudo systemctl enable redis_6380
Created symlink /etc/systemd/system/multi-user.target.wants/redis_6380.service → /etc/systemd/system/redis_6380.service.
kylin@KL1:~$ sudo systemctl start redis_6379
kylin@KL1:~$ sudo systemctl start redis_6380
可以使用systemctl status查看服務狀態,也可以查看日誌確定服務是否正常啓動。
kylin@KL1:~$ sudo systemctl status redis_6379
● redis_6379.service - Redis Master 6379
Loaded: loaded (/etc/systemd/system/redis_6379.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2025-09-18 13:46:12 CST; 23s ago
Process: 158217 ExecStart=/data/redis/bin/redis-server /data/redis/conf/redis_6379.conf (cod>
Main PID: 158218 (redis-server)
Tasks: 4 (limit: 997)
Memory: 2.9M
CGroup: /system.slice/redis_6379.service
└─158218 /data/redis/bin/redis-server 0.0.0.0:6379 [cluster]
9月 18 13:46:12 KL1 systemd[1]: Starting Redis Master 6379...
9月 18 13:46:12 KL1 systemd[1]: Started Redis Master 6379.
kylin@KL1:~$ tail /data/redis/logs/redis_6379.log -f
159134:M 18 Sep 2025 13:47:59.693 * Reading RDB base file on AOF loading...
159134:M 18 Sep 2025 13:47:59.693 * Loading RDB produced by version 8.2.1
159134:M 18 Sep 2025 13:47:59.693 * RDB age 7335 seconds
159134:M 18 Sep 2025 13:47:59.693 * RDB memory usage when created 2.10 Mb
159134:M 18 Sep 2025 13:47:59.694 * RDB is base AOF
159134:M 18 Sep 2025 13:47:59.694 * Done loading RDB, keys loaded: 0, keys expired: 0.
159134:M 18 Sep 2025 13:47:59.694 * DB loaded from base file appendonly.aof.1.base.rdb: 0.001 seconds
159134:M 18 Sep 2025 13:47:59.694 * DB loaded from append only file: 0.001 seconds
159134:M 18 Sep 2025 13:47:59.899 * Opening AOF incr file appendonly.aof.1.incr.aof on server start
159134:M 18 Sep 2025 13:47:59.899 * Ready to accept connections tcp
6 參考文獻
https://cloud.tencent.com/developer/article/2342178
https://juejin.cn/post/7443371563422531636
https://juejin.cn/post/7477883775227822119
https://blog.csdn.net/qq_41978931/article/details/151804803
https://www.tkcnn.com/redis/manual/sentinel.html