Redis 的主从复制机制
主从复制
概述
主从复制,是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。主节点负责写操作,从节点负责读操作
主从复制的作用
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写 Redis 数据时应用连接主节点,读 Redis 数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
- 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是 Redis 高可用的基础。
主从复制环境的搭建
1、在Redis的安装目录创建配置文件
新建 redis6379.conf 文件(注意,Redis 配置文件的 daemonize 参数值要为 yes,表示 Redis 可以后台启动)
#包含redis的默认配置文件的内容(后面是redis的配置文件路径)
include /opt/redis-6.2.6/redis.conf
#进程id
pidfile /var/run/redis_6379.pid
#端口号
port 6379
#持久化文件
dbfilename dump6379.rdb
#日志文件
logfile /var/log/redis/redis6379.log
新建 redis6380.conf 文件
include /opt/redis-6.2.6/redis.conf
pidfile /var/run/redis_6380.pid
port 6380
dbfilename dump6380.rdb
logfile /var/log/redis/redis6380.log
新建 redis6381.conf 文件
include /opt/redis-6.2.6/redis.conf
pidfile /var/run/redis_6381.pid
port 6381
dbfilename dump6381.rdb
logfile /var/log/redis/redis6381.log
此处仅为个人练习,所以使用单机,实际应用中一般为多台服务器
2、启动三台 Redis 服务器
[root@localhost redis-6.2.6]# /opt/redis-6.2.6/src/redis-server /opt/redis-6.2.6/redis6379.conf
[root@localhost redis-6.2.6]# /opt/redis-6.2.6/src/redis-server /opt/redis-6.2.6/redis6380.conf
[root@localhost redis-6.2.6]# /opt/redis-6.2.6/src/redis-server /opt/redis-6.2.6/redis6381.conf
[root@localhost redis-6.2.6]# ps -ef | grep redis
root 44737 1 0 10:49 ? 00:00:00 /opt/redis-6.2.6/src/redis-server *:6379
root 44747 1 0 10:49 ? 00:00:00 /opt/redis-6.2.6/src/redis-server *:6380
root 44765 1 0 10:49 ? 00:00:00 /opt/redis-6.2.6/src/redis-server *:6381
root 44774 1909 0 10:49 pts/0 00:00:00 grep --color=auto redis
后台启动的命令为:redis-server文件路径 redis.conf文件路径
3、分别查看三台 Redis 的主从复制信息
6379 端口的主从信息如下:
6380 端口的主从信息如下:
6381 端口的主从信息如下:
4、配置主节点、从节点(配从库不配主库)
刚刚启动的集群服务器中的每一个节点服务器都认为自己是主服务器,所以需要我们建立主从关系。
语法格式:slaveof ip port
例如,分别在 6380 和 6381 配置主节点:
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK
配置主从关系只需要在从机上指定主机的 ip 和 端口号即可。
注意:也可以在从机上使用 slaveof no one 命令取消主从关系
5、再次查看三台 Redis 的主从复制信息
配置过主从关系后的 6379 端口主从信息如下:
配置过主从关系后的 6380 端口主从信息如下:
配置过主从关系后的 6381 端口主从信息如下:
6、进行测试验证
在主节点上面创建新的 key,然后在从节点上面获取到 key 的 value
注意:从节点不能进行写操作
127.0.0.1:6379> set id 1
OK
127.0.0.1:6379> set name xiaobai
OK
127.0.0.1:6379> set age 23
OK
127.0.0.1:6379> get name
"xiaobai"
127.0.0.1:6380> get name
"xiaobai"
127.0.0.1:6380> get id
"1"
127.0.0.1:6381> get name
"xiaobai"
127.0.0.1:6381> get age
"23"
主从复制的原理
主从复制可以分为 3 个阶段
- 连接建立阶段(准备阶段)
- 数据同步阶段
- 命令传播阶段
而这三个阶段又可以分为 6 个过程:
- 保存主节点(master)信息。
- 从节点(slave)内部通过每秒运行的定时任务维护复制相关逻辑,当定时任务发现存在新的主节点后,会尝试与该节点建立网络连接。从节点会建立一个 socket 套接字,专门用于接受主节点发送的复制命令。
- 发送 ping 命令。连接建立成功后从节点发送 ping 请求进行首次通信。作用是:检测主从之间网络套接字是否可用;检测主节点当前是否可以接收命令
- 权限验证。如果主节点设置了 requirepass 参数,则需要密码验证,从节点必须配置 masterauth 参数保证与主节点相同的密码才能通过验证;如果验证失败复制将终止,从节点重新发起复制流程。
- 同步数据集。主从复制连接正常通信后,对于首次建立复制的场景,主节点会把持有的数据全部发送给从节点,这部分操作是耗时最长的步骤。
- 命令持续复制。当主节点把当前的数据同步给从节点后,便完成了复制的建立流程。接下来主节点会持续地把写命令发送给从节点,保证主从数据一致性。
主从同步策略:
主从刚刚连接的时候,进行全量同步;全量同步结束后,进行增量同步。
当然,如果有需要,从节点可以在任何时候发起全量同步。
Redis 的策略是,首先会尝试进行增量同步,如不成功,要求从机进行全量同步
哨兵模式
概述
哨兵模式是一种特殊的模式,首先 Redis 提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待 Redis 服务器响应,从而监控运行的多个 Redis 实例。
哨兵模式是为 Redis 提供一个高可靠解决方案。简单来讲,通过哨兵服务器监控主节点(master)/从节点(slave)实现主从复制集群的自动化管理。
主从复制的缺点(了解):
- 一旦主节点宕机,写服务无法使用,就需要手动去切换,重新选择主节点,手动设置主从关系。
- 在主服务器宕机后,需要手动把一台服务器切换为主服务器,需要人工干预,费时费力,还会造成一段时间内服务不可用。
哨兵模式的作用
- 集群监控:负责监控 Redis 主节点(master)和从节点(slave)进程是否正常工作
- 消息通知:如果某个 Redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员
- 故障转移:如果主节点(master)挂掉了,会自动转移到从节点(slave)上
- 配置中心:如果故障转移发生了,通知 client 客户端新的主节点(master)地址
相关概念:
- 主观下线:1台哨兵检测到某节点服务器下线。
- 客观下线:认为某个节点服务器下线的哨兵服务器达到指定数量。这个数量后面在哨兵的启动配置文件中指定。
- 心跳检查:心跳(heart beat)检查,客户端为了确认服务器端是否正在运行,不断的给服务器端发送数据库包。通过服务器端返回的数据包判断服务器端是否正在运行的工作机制
注意:只有 master 服务器做客观下线的判断, slave 只做主观下线的判定。
哨兵模式环境的搭建
1、在Redis的安装目录创建配置文件
新建 sentinel-26379.conf 文件
#端口
port 26379
#守护进程运行
daemonize yes
#日志文件
logfile "sentinel-26379.log"
sentinel monitor mymaster 127.0.0.1 6379 2
语法格式:sentinel monitor 别名 监控主节点地址 端口号 故障判定数
上述配置含义:该哨兵节点监控 127.0.0.1:6379 这个主节点,该主节点名称为 mymaster,最后的 2 代表 至少需要 2 个哨兵节点同意,才能判定主节点故障并进行故障转移。
哨兵节点个数尽量为单数。
每个哨兵节点,只需要配置监控主节点,便可以自动发现其他的哨兵节点和从节点
新建 sentinel-26380.conf 文件
port 26380
daemonize yes
logfile "sentinel-26380.log"
sentinel monitor mymaster 127.0.0.1 6379 2
新建 sentinel-26381.conf 文件
port 26381
daemonize yes
logfile "sentinel-26381.log"
sentinel monitor mymaster 127.0.0.1 6379 2
2、启动哨兵节点
哨兵节点的两种启动方式
- redis-sentinel文件路径 sentinel.conf文件路径
- redis-server文件路径 sentinel.conf文件路径 --sentinel
[root@localhost redis-6.2.6]# /opt/redis-6.2.6/src/redis-sentinel /opt/redis-6.2.6/sentinel-26379.conf
[root@localhost redis-6.2.6]# /opt/redis-6.2.6/src/redis-server /opt/redis-6.2.6/sentinel-26380.conf --sentinel
[root@localhost redis-6.2.6]# /opt/redis-6.2.6/src/redis-sentinel /opt/redis-6.2.6/sentinel-26381.conf
[root@localhost redis-6.2.6]# ps -ef | grep sentinel
root 66916 1 0 17:15 ? 00:00:00 /opt/redis-6.2.6/src/redis-sentinel *:26379 [sentinel]
root 67016 1 0 17:16 ? 00:00:00 /opt/redis-6.2.6/src/redis-server *:26380 [sentinel]
root 67037 1 0 17:17 ? 00:00:00 /opt/redis-6.2.6/src/redis-sentinel *:26381 [sentinel]
root 67053 1909 0 17:17 pts/0 00:00:00 grep --color=auto sentinel
3、分别查看三个端口的哨兵信息
4、进行测试验证
测试当主节点发生故障时,哨兵的监控和自动故障转移功能。
4.1 查看主节点(redis6379)进程 id,使用 kill -9 命令杀掉主节点
4.2 查看哨兵节点信息
注意:
如果 kill 掉原先主节点后,立即在哨兵节点中使用info Sentinel命令查看,会发现主节点还没有切换过来,因为哨兵发现主节点故障并转移,需要一段时间。
4.3 重启 redis6379 节点,并查看其主从复制信息
4.4 查看配置文件
故障转移阶段,哨兵和主从节点的配置文件都会被改写
5、总结
- 哨兵系统中的主从节点,与普通的主从节点并没有什么区别,故障发现和转移是由哨兵来控制和完成的。
- 哨兵节点本质上是 Redis 节点。
- 每个哨兵节点,只需要配置监控主节点,便可以自动发现其他的哨兵节点和从节点。
- 在哨兵节点启动和故障转移阶段,各个节点的配置文件会被重写(config rewrite)。
哨兵模式的原理
哨兵模式大致可以分为三个阶段
- 监控阶段:哨兵(sentinel)每秒会向主节点(master)发送 ping 命令,而哨兵(sentinel)之间也会通过发布(publish)订阅(subscribe)来保证信息的同步
- 通知阶段:哨兵(sentinel)不断的向主节点(master)和从节点(slave)发起通知,收集信息。
- 故障转移阶段:通知阶段哨兵(sentinel)发送的通知没得到主节点(master)的回应,就会把主节点(master)标记为 SRI_S_DOWN ,并且把主节点(master)的状态发给各个哨兵(sentinel),其他哨兵(sentinel)听到主节点(master)挂了,也会去核实,当有一半的哨兵(sentinel)都认为主节点(master)挂了的时候,就会把主节点(master)标记为 SRI_0_DOWN。
投票方式
当主节点挂掉之后,哨兵是通过投票的方式来决定哪个 sentinel 成为故障转移的主导者,然后会配置出新的主节点。
注意:部署哨兵至少部署三个且奇数个的 sentinel 节点。
选出来故障转移的哨兵之后,哨兵会选出来新的主节点,而原则是:
以偏移量为主,偏移量最接近(一般为相等)主节点偏移量的从节点会优先被选为新的主节点
剔除节点的一些情况:
- 故障节点
- 不在线的
- 响应慢的
- 与原先主节点断开时间久的
- 优先级原则(可以在配置文件里面配置)
Cluster 模式
Cluster 模式是一个由多个主从节点群组成的分布式服务集群,它具有复制、高可用和分片特性。
Cluster 模式没有中心点,而且可以水平拓展,无限延伸。Cluster 模式有以下优点:
- Cluster 模式有多个 master,可以减小访问瞬断问题的影响
- Cluster 模式有多个 master,可以提供更高的并发量
- Cluster 模式可以分片存储,这样就可以存储更多的数据
哨兵模式的缺点(了解):
- 当 master 挂掉的时候,sentinel 会选举出来一个 master,选举的时候是没有办法去访问 Redis 的,会存在访问瞬断的情况;
- 哨兵模式,对外只有 master 节点可以写,slave 节点只能用于读。尽管 Redis 单节点最多支持 10W 的 QPS,但是在电商大促的时候,写数据的压力全部在 master上。
- Redis 的单节点内存不能设置过大,若数据过大在主从同步将会很慢;在节点启动的时候,时间特别长;
Cluster 的搭建过程这里就不在展示了~