Redis复制

redis ginotang 542℃ 0评论

Redis复制

Redis只支持主从(master-slave)复制,但不支持主主(master-master)复制。Redis主要有两个作用:

  • 数据安全
  • 负载均衡

Redis slave保存master中数据的一个完整副本,即使master宕机了,slave依然可以向外提供服务。

Redis slave通常充当一个只读角色。写操作发送给master,而读操作则发送给slave,这样master的一部分压力就被slave分担了。

复制原理

通常一个完整的复制过程都会经历下面的几个步骤:

步骤 Master上的操作 Slave上的操作
1 等待命令 连接到Master,发送sync命令
2 执行BGSAVE操作,保存RDB文件; 在生成RDB的过程中,所有新接收的写操作都被存放到缓冲区(backlog) 在等待Master RDB的过程中,根据配置的不同,要么继续为客户端提供旧的数据,要么返回错误给客户端
3 完成BGSAVE,并开始向Slave发送快照文件, backlog中的写操作继续保持着 丢弃所有旧的数据,开始接收Master的快照
4 一旦快照发送完成,继续把backlog中的写操作命令发送给Slave 处理完Master发送的快照后,接收Master的后续写操作
5 发送完backlog,正常向外提供服务 处理完Master发送的backlog数据,正常向外提供服务

Master/Slave 链

Master可以有多个Slave,Slave也可以有自己的Slave。当读操作远远大于写操作的时候,添加更多的Slave往往都是我们优先选择的解决方案,当然,这些Slave一般都不会指向唯一的Master,而是像下图所显示的结构:

master-slave-chain

master-slave-chain

这样做的好处是可以防止单一master在和所有Slave同步的过程中造成的网络过载或者master资源负荷过高的问题,最终的结果是master性能受到影响。

全量同步和增量同步

Redis内部维护着一个Replication ID和Replication offset,当Slave向Master发送psync的时候,会把这个Replication ID一同发送给Master,Master会根据这个ID查询同步偏移量(offset)。下面是具体通讯机制:

  • 当Master和Slave之间网络畅通,Master会持续发送命令给Slave以保持数据同步
  • 当Master和Slave之间连接已断开,Slave会尝试连接到Master,获取上次连接断开之前丢失的命令。这就是增量同步
  • 如果无法进行增量同步,那么Slave会请求进行全量同步,这个过程会重复上表中的步骤1~5

注:由于sync命令不能进行增量同步,因此新版本中改用psync命令。

确保复制过程的数据安全

在复制环境下,最好打开Master的数据持久化功能(RDB),AOF可以酌情考虑是否开启。如果确实不希望使用RDB,那么最好避免Redis服务崩溃后自动重启

考虑下面的情况:

  • 两台Redis,Node A作为Master,Node B作为Slave,Node B从Node A接收数据
  • Node A没有开启RDB,当Node A宕机后被自动重启,这时候Node A中没有任何数据
  • Node B从Node A同步数据,因为Node A的数据全部丢失,同步的时候会导致Node B的数据也一起消失

配置Replication

以下命令在Slave中配置:

Redis Sentinel

Sentinel是Redis的高可用解决方案,它具有以下作用

  • 监控: Sentinel可以检查Redis master和slave是否按照预期工作
  • 提醒:通过API接口,Sentinel可以提醒管理者Redis实例发生的问题
  • 自动故障转移:如果Redis Master掉线,Sentinel会把其中一个Slave提升为Master
  • 配置提供者:通过Sentinel,客户端可以获取当前Master的最新状态

分布性

Sentinel天生就是为分布式设计的,这就要求多个Sentinel实例一起工作,有以下好处:

  • 只有多个Sentinel共同认为Redis Master掉线,这个master才被确认为真正掉线,这样可以降低错误率。
  • 如果只有一个Sentinel进程,如果这个进程运行出错,或者是网络堵塞,那么将无法实现redis集群的主备切换
  • 如果有多个Sentinel,redis的客户端可以随意地连接任意一个sentinel来获得关于redis集群中的信息

仲裁(quorum

我们必须在配置文件中指定仲裁的数量,这个数量是指共同确认master掉线的Sentinel实例个数。假如网络上分布了5个Sentinel实例,而我们的配置文件中配置了仲裁数量为2,那么只要5个实例中的其中2个投出票数,这个master就是客观上的掉线了。

现在Sentinel需要做的事情就是选举一个新的master,具体步骤

  • 2个仲裁实例中的其中一个会被选举为leader,作为故障转移
  • leader选举完毕之后故障转移并没有真正开始,这个leader还需要网络上其他可与之通讯的Sentinel实例授权之后才能被提升为master。

SDOWN和ODOWN

即主观掉线和客观掉线。Redis master被单个Sentinel实例标记为掉线,它只能被认为是主观掉线,一个被认为主观掉线的Redis master并不会触发故障转移。而必须等到状态转移为客观掉线的时候,故障转移才会真正发生。

客观掉线必须通过指定数量的Sentinel确认(即仲裁),它们通过sentinel is-master-down-by-addr进行互相通讯,最终确认master掉线的事实。

ODOWN状态只对master有效,这个状态不会出现在Sentinel和Slave中,而SDOWN则会,一个状态为SDOWN的Slave不会被用于故障转移。

配置Sentinel

一个健康的监控系统应该至少包含3个Sentinel实例,且各个实例都不应该处于同一台服务器上面。

现在配置3台Redis服务器:1台master,其余2台作为slave,3台服务器都配置有sentinel。

sentinels

sentinels

它们的ip地址分别是:

  • master 192.168.11.6
  • slave 1 192.168.11.9 # slave-priority 10
  • slave 2 192.168.11.10 # slave-priority 100

master 开启RDB,slave开启AOF

3个Sentinel实例的配置基本相同,主要配置(/etc/redis-sentinel.conf)为:

配置好之后就可以启动所有sentinel服务,centos7中可以通过systemctl命令启动

随便连接一个sentinel服务查看当前信息

模拟master宕机

然后观察任意sentinel实例下面的/var/log/redis/sentinel.log文件,可以清楚看到master的切换过程

转载请注明:Pure nonsense » Redis复制

喜欢 (0)
0 0 投票数
文章评分
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x
()
x