主库会基于 ping check 方式检查从库是否在线,如果在线则直接同步数据文件至从服务端,从服务端也可以主动发送同步请求到主服务端,主库如果是启动了持久化功能时,会不断的同步数据到磁盘上,主库一旦收到从库的同步请求时,主库会将内存中的数据做快照,然后把数据文件同步给从库,从库得到以后是保存在本地文件中(磁盘),而后则把该文件装载到内存中完成数据重建。
① 启动 redis slave
② slave 会向 master 发送同步命令,请求主库上的数据,不论从是第一次连接,还是非第一次连接,master 此时都会启动一个后台的子进程将数据快照保存在数据文件中,然后把数据文件发送给 slave。
③ slave 收到数据文件以后会保存到本地,而后把文件重载装入内存。
① 一个 Master 可以有多个 Slave;
② 支持链式复制(一个 slave 也可以是其他的 slave 的 slave);
③ Master 以非阻塞方式同步数据至 slave(master 可以同时处理多个 slave 的读写请求,salve 端在同步数据时也可以使用非阻塞方式);
# 主服务器拷贝redis到从服务器
scp -r /usr/local/redis 192.168.137.6:/usr/local
# 从服务器操作
# 创建软连接
ln -s /usr/local/redis/bin/* /usr/local/bin
# 修改配置文件中的ip地址
sed -i 's/192.168.137.253/192.168.137.6/g' /usr/local/redis/etc/redis.conf
# 创建日志目录
mkdir /var/log/redis
# 创建数据目录
mkdir /usr/local/redis/data
#指定 master IP,端口,也可将 replicaof masterip masterport 替换为 slaveof masterip masterport
sed -i '/# replicaof/c replicaof 192.168.1.11 6379' /usr/local/redis/etc/redis.conf
#指定主 redis 连接认证密码(操作失败),主服务器必须配置requirepass 123456
sed -i '/masterauth/a masterauth 123456' /usr/local/redis/etc/redis.conf
注意:从服务器配置masterauth 123456
时,主服务器必须配置 requirepass 123456
# 启动redis服务
redis-server /usr/local/redis/etc/redis.conf
# 将redis设置开机自启动
echo "redis-server /usr/local/redis/etc/redis.conf" >> /etc/rc.local
# 查看主从信息
redis-cli -h 192.168.137.6
192.168.137.6:6379> info replication
测试:在master中插入数据,在slave中查询
redis 主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换 为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。
① 用于管理多个 redis 服务实现 HA;
② 监控多个 redis 服务节点
③ 自动故障转移
sentinel 是一个分布式系统,可以在一个架构中运行多个 sentinel 进程,多个进程之间使用“流言协议”接收 redis 主节点是否离线,并使用“投票协议”是否实现故障转移,选择哪一个 redis 的从服务器成为主服务器。
该方案有个缺陷:因为主从实例地址(IP,PORT)是不同的,当故障发生进行主从切换后,应用程序无法知道新地址,在 Jedis2.2.2 中新增了对 Sentinel 的支持,应用通过redis.clients.jedis.JedisSentinelPool.getResource()取得的 Jedis 实例会及时更新到新的主实例地址。
Jedis 是 Redis 官方推荐的 Java 连接开发工具。要在 Java 开发中使用好 Redis 中间件,必须对 Jedis 熟悉才能写成漂亮的代码。运维人员不下需要关心 redis 集群连接接,这个是开发人员作的工作。如果要提供统一访问出口。可以使用 Twemproxy 中间件部署集群。
sentinel 可以部署在另外的主机上也可以部署在 redis 主机上,sentinel 既能监控又能提供配置功能,向 sentinel 指明主 redis 服务器即可(仅监控主服务器), sentinel 可以从主服务中获取主从架构信息,并分辨从节点。sentinel 可以监控当前整个主从服务器架构的工作状态,一旦发现 master 离线的情况,sentinel 会从多个从服务器中选择并提升一个从节点成为主节点,当主节点被从节点取代以后,那么 IP 地址则发生了变化,客户之前连接的主节点 IP 无法连接,此时可以向 sentinel 发起查询请求,sentinel 会告知客户端新的主节点的 IP,所以 sentinel 是 redis 在主从架构中实现高可用的解决方案。
为了防止 sentinel 误判和单点故障,sentinel 也应该部署为集群,sentinel 多个节点同时监控 redis 主从架构,一旦有一个 sentinel 节点发现 redis 的主节点不在线时的情况,sentinel 会与其他的 sentinel 节点协商,看其他的 sentinel 节点是否也同样发现 redis 的主节点不在线,如果 sentinel 的多个点节点都发现 redis 的主节点都为离线,那么则判定 redis 主节点为离线状态,以此方式避免误判,同样也避免了单点故障。
Reids 可以在一台机器上启动多个进程,即在一台主机上开启 3 个 redis 进程,相 当于 3 台 redis 服务器。也可以在 3 台不同的服务器上进行搭建 redis。
实验拓扑
服务类型 |
Is master server? |
IP 地址 |
端口 |
redis |
y |
192.168.137.253 |
6379 |
redis |
n |
192.168.137.252 |
6379 |
redis |
n |
192.168.137.6 |
6379 |
sentinel |
- |
192.168.137.253 |
26379 |
sentinel |
- |
192.168.137.252 |
26379 |
sentinel |
- |
192.168.137.6 |
26379 |
# 主服务器拷贝redis到从服务器
scp -r /usr/local/redis 192.168.137.6:/usr/local
# 从服务器操作
# 创建软连接
ln -s /usr/local/redis/bin/* /usr/local/bin
# 修改配置文件中的ip地址
sed -i 's/192.168.137.253/192.168.137.6/g' /usr/local/redis/etc/redis.conf
# 创建日志目录
mkdir /var/log/redis
# 创建数据目录
mkdir /usr/local/redis/data
#指定 master IP,端口,也可将 replicaof masterip masterport 替换为 slaveof masterip masterport
sed -i '/# replicaof/c replicaof 192.168.1.11 6379' /usr/local/redis/etc/redis.conf
#指定主 redis 连接认证密码(操作失败),主服务器必须配置requirepass 123456
sed -i '/masterauth/a masterauth 123456' /usr/local/redis/etc/redis.conf
# 启动redis服务
redis-server /usr/local/redis/etc/redis.conf
# 将redis设置开机自启动
echo "redis-server /usr/local/redis/etc/redis.conf" >> /etc/rc.local
# 查看主从信息
redis-cli -h 192.168.137.6
192.168.137.6:6379> info replication
三个 sentinel 节点的 sentinel.conf 文件配置一样,如果是在同一个主机上,则需要使用不同的端口号。
① 生成sentinel.conf
# 将redis解压目录中的sentinel.conf 复制到/usr/local/redis/etc/中
cp /usr/local/src/redis-6.2.6/sentinel.conf /usr/local/redis/etc/
# 编辑sentinel.conf文件
vim /usr/local/redis/etc/sentinel.conf
#----------------------------------------配置文件-----------------------------------
daemonize yes
#添加监控 IP,一定要写 0.0.0.0,不然主从切换不了
bind 0.0.0.0
logfile "/var/log/redis/sentinel_26379.log"
# sentinel monitor
#此项可以出现多次,可以监控多组 redis 主从架构,此项用于监控主节点
# 自定义的主节点名称, 主节点的 IP 地址,主节点的端口号,
#主节点对应的 quorum 法定数量,是一个大于 sentinel 数量一半的值,
#所以 sentinel 数量尽量为奇数个,如果 sentinel 有 3 个,则指定为 2 即可,
#如果有 4 个,不能够指定为2,避免导致集群分裂,
#为集群名称,可以自定义,如果同时监控有多组 redis 集群时,不能相同
#注:最后数字 2 表示如果有两个 sentinel 认为 master 挂了,则这个 master 即认为不可用;
sentinel monitor mymaster 192.168.1.11 6379 2
# sentinel auth-pass
# sentinel author-pass 定义服务的密码,mymaster 是服务名称,123456 是 Redis 服务器密码
sentinel auth-pass mymaster 123456
#sentinel down-after-milliseconds
#默认 30 秒,sentinel 会通过 ping 来判断 master 是否存活
#如果在 30 秒内 master 返回 pong 给sentinel,
#则认为 master 是好的,否则 sentinel 认为 master 不可用。
sentinel down-after-milliseconds mymaster 30000
#sentinel parallel-syncs
#当 Sentinel 节点集合对主节点故障判定达成一致时,Sentinel 领导者节点会做故障转移操作,
#选出新的主节点,原来的从节点会向新的主节点发起复制操作,
#限制每次向新的主节点发起复制操作的从节点个数为 1
sentinel parallel-syncs mymaster 1
#sentinel failover-timeout
#故障转移超时时间,在指定时间没能完成则判定为失败,单位为毫秒(默认为 180 秒)
sentinel failover-timeout mymaster 180000
#----------------------------------------配置文件-----------------------------------
# 将sentinel.conf拷贝到其他从服务器
scp /usr/local/src/redis-6.2.6/sentinel.conf 192.168.137.252:/usr/local/redis/etc
scp /usr/local/src/redis-6.2.6/sentinel.conf 192.168.137.6:/usr/local/redis/etc
注意:Redis Sentinel 中的身份验证,
② 启动服务
# 启动三台服务器的sentinel
redis-sentinel /usr/local/redis/etc/sentinel.conf
# 添加开机自启动
echo "redis-sentinel /usr/local/redis/etc/sentinel.conf" >> /etc/rc.local
# 查看进程
ps -ef | grep redis
③ 查看集群状态
redis-cli -h 192.168.137.253 -p 26379
192.168.137.253:26379>info sentinel
192.168.137.253:26379>client list
注意:当我们启动主从节点和 sentinel 节点后,sentinel.conf 配置文件会自动添加或修改参数。
测试自动 failover:可以通过跟踪 sentinel 的日志文件查看 failover 切换
① 关闭master: redis-cli -a 123456 shutdown
② 查看主从状态:
redis-cli -h 192.168.137.253 -p 26379
192.168.137.253:26379> info sentinel
192.168.137.253:26379> sentinel masters
③ 启动主服务器(旧master)
注意:重启修复好的旧 master 之后,会自动成为新master的从库。JClouds上没有添加连接主服务器密码
#注意 JClouds 上没有添加连接主服务器密码
sed -i '/masterauth/a masterauth 123456' /usr/local/redis/etc/redis.conf
redis-server /usr/local/redis/etc/redis.conf
# 查看主从状态
redis-cli -h 192.168.137.253 -p 6379
192.168.137.253:6379> auth 123456
192.168.137.253:6379> info replication
④ 在新的主 redis 上查看主从信息
[root@Book etc] redis-cli -a 123456
127.0.0.1:6379> info replication
结论:由以上测试可见,主的故障离线后,sentinel 重新选了其一个从 reids 成为了新的主节点,在原来的主节点重新上线后,仍然不会恢复为主节点。