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