6.2.7
,安装包为:redis-6.2.7-amd64.tar.gz
,为方便配置程序提前进行了编译并同时对配置文件做了部分修改,因此和默认安装包存在部分差别。/opt/redis-6.2.7-amd64
/data/redis
编辑/etc/sysctl.conf
, 例如:vim /etc/sysctl.conf
, 添加参数如下:
vm.overcommit_memory=1
net.core.somaxconn=4096
net.ipv4.tcp_max_syn_backlog=4096
保存然后执行 sysctl -p
生效。
集群共3个节点分别如下:
192.168.1.21 ecs21
192.168.1.22 ecs22
192.168.1.23 ecs23
节点角色如下:
+----+
| M1 |
| S1 |
+----+
|
+----+ | +----+
| R2 |----+----| R3 |
| S2 | | S3 |
+----+ +----+
Configuration: quorum = 2
其中Redis有3个节点1个Master两个Replica节点,Sentinel必须是奇数个节点,例如:3、5、7等,至少3个才具备高可用性,因为Sentinel占用的资源不多所以在机器数量不多的情况下可以和Redis混合部署,并且可以管理多套Redis主从集群。
安装思路是首先在其中1个节点上进行配置,配置成功后将安装包发送至其他节点,然后再稍微进行单独的配置即可。
首先选定ecs21
节点上默认初始的Master进行配置,首先解压安装包到安装目录:
tar xvzf redis-6.2.7-amd64.tar.gz -C /opt/
cd /opt/redis-6.2.7-amd64
具体目录结构,参考Redis单节点配置中的说明。
首先在ecs21
上编辑Redis的配置文件redis.conf
主要内容如下:
# 默认为了安全只绑定回环地址
bind 127.0.0.1 -::1
# 由于配置主从 必须要绑定外部网卡
bind 0.0.0.0 ::
# 服务监听的端口号
port 6379
# pid文件 如果单机上有多个 redis 实例,不同的实例要单独修改
pidfile /var/run/redis_6379.pid
# 日志文件 如果单机上有多个 redis 实例, 不同的实例要单独修改
logfile "/var/log/redis_6379.log"
# RDB持久化的目录 默认为: ./ 务必修改正确
dir "/data/redis/"
# 用于ACL文件 默认为./users.acl 务必修改为实际的绝对路径
aclfile /opt/redis-6.2.7-amd64/users.acl
# 开启无盘复制
repl-diskless-sync yes
repl-diskless-sync-delay 5
# 可靠性配置
min-replicas-to-write 1
min-replicas-max-lag 10
# 副本同步的用户名和密码
masterauth <replica-pass>
masteruser <replica-user>
简单说一下上面新增的配置,参数repl-diskless-sync
表示开启无盘复制,开启后可以提升复制的性能。
另外可靠性配置主要依靠min-replicas-to-write
和min-replicas-max-lag
这两个参数,这两个参数的配置是可选的,主要是为了可靠性考虑,参数具体表示至少有1个副本连接到当前Master才可以写入,并且数据同步的延迟不能超过10s,我们目前的情况正常会有2个副本连接到主节点,之所以这样配置是为了保证一定的稳定性,允许1个副本挂掉,但是如果全部副本挂掉时主节点也会阻止写入,否则当副本启动时同步的流量会比较大,所以至少保证要有1个副本正常才可以,同时写入的延迟不能超过10s,如果由于网络原因延迟过大也会禁止客户端写入,这样可以防止Redis主节点和副本之间的积压太大从而触发全盘复制,这样配置可以提供一些尽力而为的可靠性,上面的配置只对主节点的角色生效,对于副本节点则没有任何影响。
最后要使用独立的复制用户,这样复制节点通过该用户访问主节点,获取主节点最新的指令更新,并且同步执行,这个只是副本向主节点认证所需的密码,主节点相对于副本节点其实是具有root权限的,这个用户只需要添加psync replconf ping
这3个非常少的权限即可。
同样也是在ecs21
节点上先进行配置,编辑配置文件sentinel.conf
主要配置如下:
port 26379
daemonize yes
# 日志文件位置
logfile "/var/log/redis-sentinel.log"
# 配置监控的Redis主从集群组
sentinel monitor mymaster 192.168.1.21 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 2
sentinel auth-user mymaster <sentinel-user>
sentinel auth-pass mymaster <sentinel-pass>
aclfile /opt/redis-6.2.7-amd64/sentinel-users.acl
sentinel sentinel-user <username>
sentinel sentinel-pass <password>
sentinel monitor mymaster 192.168.1.21 6379 2
这一行用于告诉Sentinel要监控的分组,名字为mymaster
,这个名字可以自己定义,包含大小写字母、数字以及._- 这些,其余的都不支持,然后后面跟上当前的Redis Master节点的ip和端口,最后的2表示法定人数,也就是有几个Sentinel认为该Master不可达,才开始启动故障转移,不过故障转移不仅和这个有关,还和Sentinel本身的法定人数有关,为了方便说明问题,我们假设有5个Sentinel,那么如果有2个Sentinel认为Master不可达,其中1个Sentinel将启动故障转移,对于5个Sentinel,最多允许两个故障,也就是说此时至少有3个Sentinel可达,才会真正执行故障转移操作,通常情况下后面这个数字一般是和Sentinel本身的法定人数保持一致,比如当前有3个Sentinel,那么至少需要2个Sentinel认为该Master不可达,而且Sentinel本身有2个是可达的,才启动故障转移,至少两个条件其中1个不具备,则不会启动故障转移,所以说如果在这里配置1个Sentinel是无效的,如果是两个节点配置两个Redis看似可以,但是由于Redis和Sentinel在同一个节点上,通常会同时失去联系,那么这个时候永远也达不到法定人数,同样无法实现故障转移,但是如果后面的数字设置为1,将会发生非常危险的状况,因为此时单侧将独立执行,出现“脑裂”的情况。
然后下面就是超时时间的配置了,同样需要指定监控组,例如down-after-milliseconds
表示Sentinel认为服务不可达的时间,然后failover-timeout
表示故障恢复的超时时间,然后后面的parallel-syncs
表示节点被提升为Master后最多允许几个副本同时同步,如果这个值太高的话流量和主节点的压力会比较大,如果设置的比较低那么同步速度会很慢,当前我们设置为2
Sentinel可以灵活按照组的概念来配置要监控的主从集群,所以可以通过添加配置同时监控多个Redis主从组,而不需要启动多个Sentinel实例。
然后再往下的sentinel auth-user
以及sentinel auth-pass
表示Sentinel监控Redis所使用的用户名和密码,需要在所有Redis实例中都创建这个用户,同时分配最小权限。
然后下面的配置aclfile
和Redis的ACL是一致的,表示用户访问Sentinel本身所使用的用户文件,注意一定要修改为真实的路径,后面紧接着是Sentinel角色之间认证所使用的用户,可以自己创建,也可以使用默认的,默认情况下拥有超级权限,所以一定要设置高强度的密码,和Redis一样,超级用户只用于Sentinel内部之间通信,不可以提供给客户端使用,客户端需要使用受限的用户访问Sentinel。
本文中上面两个部分中提及的所有Redis和Sentinel用户,在Redis安装包中都已经完成了默认的配置,并保存至users.acl
以及sentinel-users.acl
中,在配置时需要以实际的用户和密码替换<>
中对应的标识即可,要特别注意各个用户的用途和关系,不要配置混乱了。
现在我们仅在3个节点的ecs21
节点上完成了Redis和Sentinel的基本配置,接下来需要将安装目录同步至其他所有节点,这样所有节点的配置保持一致,不过为了方便后续使用systemd
管理,我们首先修改好service文件中的安装目录。
编辑services/redis.service
:
[Unit]
Description=redis
After=network.target local-fs.target
[Service]
User=root
Group=root
Type=forking
ExecStart={{ redis_home }}/bin/redis-server {{ redis_home }}/redis.conf
TimeoutSec=90s
RestartSec=10s
Restart=always
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
替换其中的{{ redis_home }}
为当前实际的安装目录,如下:
[Unit]
Description=redis
After=network.target local-fs.target
[Service]
User=root
Group=root
Type=forking
ExecStart=/opt/redis-6.2.7-amd64/bin/redis-server /opt/redis-6.2.7-amd64/redis.conf
TimeoutSec=90s
RestartSec=10s
Restart=always
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
然后保存,继续编辑service/redis-sentinel.service
同样替换其中的{{ redis_home }}
安装目录,如下:
[Unit]
Description=redis sentinel
After=network.target local-fs.target
[Service]
User=root
Group=root
Type=forking
ExecStart=/opt/redis-6.2.7-amd64/bin/redis-sentinel /opt/redis-6.2.7-amd64/sentinel.conf
TimeoutSec=90s
RestartSec=10s
Restart=always
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
修改之后保存。
然后即可将当前的Redis安装目录同步至其他的节点,在当前ecs21
节点上执行:
# 在ecs21上执行 注意目录后面一定不要加'/'
rsync -av /opt/redis-6.2.7-amd64 ecs22:/opt
rsync -av /opt/redis-6.2.7-amd64 ecs23:/opt
同步完成后,现在3个节点保持一致,由于默认情况下我们以ecs21
作为Master角色,所以需要修改ecs22
和ecs23
的Redis配置文件,告诉它们从ecs21
进行复制,所以分别在ecs22
和ecs23
上编辑配置文件redis.conf
,添加配置如下:
replicaof 192.168.1.21 6379
修改完成后保存配置,注意需要在剩余的节点上完成修改,即ecs22
和ecs23
。
依次在ecs21,ecs22,ecs23
上启动Redis服务:
./bin/redis-server ./redis.conf
然后依次启动Sentinel服务:
./bin/redis-sentinel ./sentinel.conf
启动之后可以进入Sentinel客户端:
./bin/redis-cli -p 26379
然后进行用户认证后,即可查看主从的状态:
sentinel master mymaster
这样即可返回集群的信息,然后可以单独查看当前的Master节点:
sentinel get-master-addr-by-name mymaster
以及副本节点:
sentinel replicas mymaster
还可以查看其他Sentinel服务的运行状态:
sentinel sentinels mymaster
然后此时可以从Redis主节点进入后写入数据,查看副本节点成功同步过去,则说明复制运行正常,同时副本节点是read only的状态,不允许写入。
如果需要测试高可用的情况,只需要选择主节点的Redis服务kill掉,然后观察Sentinel和其他Redis的日志,在默认30s之后完成选举并切换,表示高可用的运行正常。
同样和单节点一样为了方便使用Redis相关命令可以将bin
目录添加至环境变量中:
# 所有机器都需要添加bin目录到PATH中
export PATH=$PATH:/opt/redis-6.2.7-amd64/bin
将上面的指令添加至/etc/profile
或者~/.bashrc
中均可。
然后将Redis服务添加至systemd管理,在所有节点依次执行下面的命令添加系统服务:
# 所有节点都需要执行
cd /opt/redis-6.2.7-amd64
cp services/*.service /usr/lib/systemd/system
执行后需要先停止掉手动启动的Redis服务,然后重新使用systemd
启动:
# 在所有节点上启动Redis服务
systemctl start redis.service
# 查看状态
systemctl status redis.service
# 在所有节点上启动Sentinel服务
systemctl start redis-sentinel.service
systemctl status redis-sentinel.service
启动后可以连接Sentinel或者查看日志是否正常,最后可以在所有节点上设置Redis和Sentinel服务开机自动启动:
# 在所有节点上分别执行
systemctl enable redis.service
systemctl enable redis-sentinel.service
这样Redis和Sentinel服务就可以根据系统自动启动了。
Reference: