一、概述
Redis 支持三种集群模式,分别为主从模式、哨兵模式和Cluster(集群)模式。主从模式:从节点异步的从主节点复制数据,这种架构主节点故障后无法自动切主。类似于mysql的主从复制。
哨兵模式:该模式在主从复制基础上加了一个哨兵集群负责监控主节点和从节点。如果检测到主节点故障,系统可以自动将从节点晋升为新的主节点。实现了自动故障转移。类似于mysql的主从复制+MHA。
集群模式:主从模式面临内存容量和写入性能的限制,因为这种模式的写入能力仍然局限于单个节点。为了解决这一问题,Redis在3.x版本之后推出了Cluster集群模式。Cluster模式通过数据分片和节点的水平扩展,实现了更高效的内存利用和写入性能。类似于mysql的mycat分片。
本文只介绍主从模式和哨兵模式
二、redis 主从复制
2.1、部署主从集群
1、redis安装
redis 安装见我另一篇博客:https://www.cnblogs.com/sunjiwei/p/18397893
2、主从集群配置
主库不用特别配置
从库添加上以下配置
# 添加主库信息
replicaof 192.168.167.160 6379 # 主库的ip端口
masterauth 111111 # 主库的密码
slave-serve-stale-data yes
repl-timeout 60
然后启动即可,启动后在主库执行以下命令可以看到集群状态:
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.167.161,port=6379,state=online,offset=4746,lag=0
slave1:ip=192.168.167.162,port=6379,state=online,offset=4746,lag=0
master_failover_state:no-failover
master_replid:d85cc1af62aed92133eb0d236687aaf24956c9f1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:4746
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:4746
在从库也执行这个命令:
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.167.160
master_port:6379
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_read_repl_offset:420
slave_repl_offset:420
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:d85cc1af62aed92133eb0d236687aaf24956c9f1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:420
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:420
2.2、主从复制架构
主从复制支持级联复制,即从库上还可以挂从库。
2.3、主从复制原理
首先要知道每一个 Redis master 都有一个 replication ID:这是一个较大的伪随机字符串。每个 master 也持有一个偏移量offset,这个offset是主服务器已经发送给所有从服务器的命令的偏移量,这是主服务器的内部状态,跟具体某个从服务器无关。每个slave服务器也有一个offset,它记录了从服务器读取主服务器发送的命令流的位置。主服务器也会记录每个从服务器的状态,包括它们的 offset,但这只是为了监控和管理目的,并不影响主服务器自身的 master_repl_offset。...
1、全量复制
如果是从库第一次连接主库,会进行全量复制, 过程如下:
1、slave服务器成功连接到master服务器,发送psync命令(Redis2.8之前是sync命令),开始进行数据同步
psync 命令需要 3 个组件支持:
a、主从节点各自复制偏移量
b、主节点复制积压缓冲区
c、主节点运行 ID,即replication id
psync 命令的使用方式:
命令格式为 psync{replication Id}{offset}
runId:从节点所复制主节点的运行 id
offset:当前从节点已复制的数据偏移量
psync 执行流程:
从节点发送 psync{runId}{offset} 命令给主节点,如果没有replication Id(比如从节点第一次连接主节点就是没有replication Id的) 则replication Id默认为 -1,offset 是从节点保存的复制偏移量,如果是第一次复制则offset也为 -1。主节点会根据 runid 和 offset 决定返回结果:
1、如果主节点回复 FULLRESYNC ,那么从节点将触发全量复制流程。
2、如果主节点回复 CONTINUE,从节点将触发部分复制,也叫增量复制。
3、如果主节点回复 ERR,说明主节点不支持 2.8 的 psync 命令,将使用 sync 执行全量复制。
2、master服务器收到psync命令之后,开始执行bgsave命令生成RDB快照文件并使用复制积压缓冲区记录此后执行的所有写命令
注意:
如果master收到了多个slave并发连接请求,它只会进行一次持久化,而不是每个连接都执行一次,然后再把这一份持久化的数据发送给多个并发连接的slave。
如果RDB复制时间超过60秒(repl-timeout),那么slave服务器就会认为复制失败,可以适当调节大这个参数
3、master服务器bgsave执行完之后,就会向所有Slava服务器发送快照文件,并在发送期间继续在缓冲区内记录被执行的写命令
4、slave服务器收到RDB快照文件后,会将接收到的数据写入磁盘,然后清空所有旧数据,在从本地磁盘载入收到的快照到内存中
5、主节点在从节点接受数据的期间,将新数据保存到“复制积压缓冲区”,当从节点加载 RDB 完毕,再发送过去。(如果从节点花费时间过长,将导致缓冲区溢出,最后全量同步失败)
6、slave服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令,从节点成功加载完 RBD 后,如果开启了AOF,那么会立即执行BGREWRITEAOF,重写AOF;
2、增量复制
当全量同步完成后,后续主库新的写操作就会通过复制积压缓冲区向从库同步,从库接收到这些写操作并执行,这就是增量复制。
或者如果出现网络闪断和其他异常情况导致从库和主库断开,如果断开的时间不长,主库的复制积压缓冲区没有被清理,则从库恢复和主库的连接后也是进行增量复制,而不会进行全量同步,这个叫断点续传。
3、无需磁盘参与的复制
正常情况下,一个全量重同步要求在磁盘上创建一个 RDB 文件,然后将它从磁盘加载进内存,然后 slave以此进行数据同步。
如果磁盘性能很低的话,这对 master 是一个压力很大的操作。Redis 2.8.18 是第一个支持无磁盘复制的版本。在此设置中,子进程直接发送 RDB 文件给 slave,无需使用磁盘作为中间储存介质。
无磁盘复制可以使用 repl-diskless-sync 配置参数。repl-diskless-sync-delay 参数可以延迟启动数据传输,目的可以在第一个 slave就绪后,等待更多的 slave就绪。
repl-diskless-sync no # 是否开启无磁盘复制,默认不开启
repl-diskless-sync-delay 5 # 等待一定时长再开始复制,因为要等更多slave重新连接过来
4、心跳
主从节点在建立复制后,他们之间维护着长连接并彼此发送心跳命令。
心跳的关键机制如下:
1、中从都有心跳检测机制,各自模拟成对方的客户端进行通信,通过 client list 命令查看复制相关客户端信息。
2、主节点默认每隔 10 秒对从节点发送 ping 命令,可修改配置 repl-ping-slave-period 控制发送频率。
3、从节点在主线程每隔一秒发送 replconf ack{offset} 命令,给主节点上报自身当前的复制偏移量。
4、主节点收到 replconf 信息后,判断从节点超时时间,如果超过 repl-timeout 60 秒,则判断节点下线。
三、哨兵模式
3.1、什么是哨兵模式
Redis Sentinel为Redis提供了高可用解决方案。哨兵模式是主从复制模式的一种进阶形式,它的核心优点在于能够自动实现主从切换和故障转移。
Redis Sentinel同时提供了一些其他的功能,例如:监控、通知、并为client提供配置。
下面是Sentinel的功能列表:
1、监控(Monitoring):Sentinel不断的去检查你的主从实例是否按照预期在工作。
2、通知(Notification):Sentinel可以通过一个api来通知系统管理员或者另外的应用程序,被监控的Redis实例有一些问题。
3、自动故障转移(Automatic failover):如果一个主节点没有按照预期工作,Sentinel会开始故障转移过程,把一个从节点提升为主节点,并重新配置其他的从节点使用新的主节点,使用Redis服务的应用程序在连接的时候也被通知新的地址。
4、配置提供者(Configuration provider):Sentinel给客户端的服务发现提供来源:对于一个给定的服务,客户端连接到Sentinels来寻找当前主节点的地址。当故障转移发生的时候,Sentinels将报告新的地址。
3.2、Sentinel的分布式特性
Redis Sentinel是一个分布式系统,Sentinel运行在有许多Sentinel进程互相合作的环境下,它本身就是这样被设计的。有许多Sentinel进程互相合作的优点如下(一个健康的集群部署,至少需要三个Sentinel实例):
当多个Sentinel同意一个master不再可用的时候,就执行故障检测。这明显降低了错误概率。
即使并非全部的Sentinel都在工作,Sentinel也可以正常工作,这种特性,让系统非常的健康。
sentinel 包含在redis安装包中,不需要单独下载。redis安装好后setinel也就可以使用了,但是需要单独配置sentinel配置文件,然后启动setinel进程。默认情况下,Sentinel端口为26379。
3.3、sentinel 部署
# 创建目录
mkdir -p /opt/sentinel/{log, data}
mkdir -p /etc/sentinel
编辑配置文件,sentinel 最小配置文件配置如下,如果需要更多配置再研究即可:
# server相关
pidfile /opt/sentinel/sentinel.pid
logfile /opt/sentinel/sentinel.log
dir /opt/sentinel/
port 26379
bind 0.0.0.0
# 修改为以守护进程模式后台运行
daemonize yes
# 是否开启保护模式
protected-mode no
# 高可用配置
sentinel monitor mymaster 192.168.167.160 6379 2
sentinel auth-pass mymaster 111111
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 5000
sentinel parallel-syncs mymaster 2
setinel 配置文件参数解释
# 哨兵sentinel实例运行的端口,为了跟主库一致,我们直接定义为26380端口
port 26379
# ip
bind 0.0.0.0
# 修改为以守护进程模式后台运行
daemonize yes
# 是否开启保护模式
protected-mode no
# 哨兵监听的主服务器,不需要监听从服务器,从节点会被自动发现,
# 后面的2表示主机挂掉以后setinel实例进行投票,只需要两票就可以判定主机宕机
# mymaster 是随便起的名字
sentinel monitor mymaster 192.168.167.160 6379 2
# 设置主机的密码(无密码可以省略)
sentinel auth-pass mymaster 111111
# 设置未得到主机响应时间,此处代表5秒未响应视为宕机,,默认30秒
sentinel down-after-milliseconds mymaster 5000
# 设置等待主机活动时间,此处代表5秒主机未活动,则重新选举主机,默认3min,单位毫秒
sentinel failover-timeout mymaster 5000
# 设置重新选举主机后,同一时间同步数据的从机数量,2表示每次只能2台从机同时同步主机数据,直到所有从机同步结束
sentinel parallel-syncs mymaster 2
# pid 文件位置
pidfile /opt/sentinel/sentinel.pid
# 修改日志文件位置
logfile /opt/sentinel/sentinel.log
# 数据文件位置
dir /opt/sentinel/
启动sentinel
# 启动
redis-sentinel /etc/sentinel/sentinel.conf
# 查看进程
[root@ob9 appendonlydir]# ps -ef |grep redis
root 13273 1 0 17:36 ? 00:00:00 redis-sentinel 0.0.0.0:26379 [sentinel]
root 13283 30866 0 17:36 pts/0 00:00:00 grep --color=auto redis
root 14255 1 0 9月10 ? 00:05:03 redis-server 0.0.0.0:6379
3.4、sentinel运维命令
连接sentinel: redis-cli -p 26379SENTINEL masters 展示监控的主节点和它们的状态列表
SENTINEL master <master name> 展示指定的主节点的信息
SENTINEL salves <master name> 展示这个主节点的从节点,以及它们的状态
SENTINEL sentinels <master name> 展示这个主节点的sentinel实例,以及它们的状态
SENTINEL get-master-addr-by-name <master name> 返回主节点的IP和端口号。如果这个主节点的一次故障转移正在进行,就返回提升的从节点的IP和端口号
SENTINEL reset <pattern> 这个命令将会根据匹配的名称重置主节点,pattern参数是通配符(glob-style)类型,重置进程清除主节点中之前的所有状态,并且移除主节点发现和关联的从节点和sentinel。
SENTINEL failover <master name> 如果主节点不可达,强制开始故障转移,不需要另外的Sentinels同意。
SENTINEL ckquorum <master name> 检查当前的Sentinel配置对于主节点的故障转移是否能达到仲裁人数,并且大多数是需要的来授权故障转移。这个命令应该在监控系统中使用来检查一个Sentinel部署是否正常。
SENTINEL flushconfig 强制Sentinel重新写入它的配置到磁盘上,包括当前Sentinel状态。通常,每次当它状态里的一些东西改变,Sentinel就会重写配置信息。然而有时候配置文件会丢失,由于错误的操作、磁盘故障、包升级脚本、或配置管理。在那种情况下,强制Sentinel重写它的配置文件是容易的。甚至之前的配置文件完全丢失,这个命令也能很好的工作。
参考文档:
https://redis.com.cn/topics/replication.html
https://www.cnblogs.com/ataoxz/p/18084394
https://cloud.tencent.com/developer/article/2033627