首页 > 编程知识 正文

redis的主从复制和哨兵机制,Redis 集群之间是如何复制的?

时间:2023-05-04 21:12:33 阅读:268735 作者:1178

Redis主从复制 前言Redis主从复制有哪些问题数据一致性网络延迟过期数据过期时间解决方案 复制风暴客户端缓冲区溢出复制积压缓冲区复制风暴的危害复制风暴解决方案 结束语

前言

对于分布式系统而言,针对高可用,无论是计算高可用还是存储高可用都是采用冗余的方式。
计算高可用的冗余相对比较简单,因为在多数场景下计算节点都是无状态的,直接水平扩展即可。但对于存储高可用来说,其复杂度是计算高可用不可比拟的,因为存储高可用需要面对很多的问题。比如数据一致性,扩容/缩容可能导致的数据迁移等问题。

存储高可用的核心就是数据冗余,也就是多副本。本篇只针对Redis高可用方案-主从复制会产生的一些问题进行探讨。

Redis主从复制有哪些问题 数据一致性

这里的数据一致性是占在用户的角度考量的,不是在系统本身的角度考量的。Redis主从数据不一致主要有以下因素导致。

网络延迟

Redis主从复制是异步的,主节点的主线程不会等待从节点接收到数据。因网络本身的不可靠性这种延迟是固有的。

针对此场景的解决方案有以下方式

从硬件环境考虑,给主从复制配置更好的网络环境监控主从复制延迟:通过 info replication命令通过比对 slave_repl_offset和master_repl_offset的值,当超过指定的阀值,就不允许访问从节点,降低延迟对业务的影响。 过期数据

先简单介绍下Redis过期数据的删除问题,Redis删除过期数据的策略有以下两种:

惰性删除:访问缓存数据时,如果数据过期,执行删除定时删除:Redis定时扫描一定量的key,删除过期数据

在Redis主从复制环境下,且从节点配置为只读模式,访问从节点上的过期数据,从节点不会执行物理删除,外部请求是否能够看到从节点的上的过期数据,和Redis的版本有关。在Redis3.2之前,访问从节点上的过期数据,Redis会返回缓存数据。Redis 3.2之后的版本,访问从节点上的过期数据,会返回空值,但不会物理删除。

过期时间

redis有四种设置缓存过期时间的命令,分别是

expire 单位s, 相对时间pexpire 单位ms,相对时间expireat 绝对时间pexpireat 绝对时间

expire和pexpire 设置的过期时间是相对时间,redis开始处理expire或pexpire命令时的时间开始算起,expireat和pexpireat设置到是绝对时间,也就是时间点。

对于相对时间的设置方式,可能会由于网络原因或从节点负载的问题导致主节点数据已过期而从节点数据还未过期,这在上述所说的redis3.2之后的版本会导致主从数据不一致。

对于时间点这种设置方式,依赖于主从节点的时钟是否同步。

解决方案 从硬件环境考虑,给主从复制配置更好的网络环境监控主从复制延迟,比如通过 info replication命令通过比对 slave_repl_offset和master_repl_offset的值,当超过指定的阀值,就不允许访问从节点,降低延迟对业务的影响升级redis到3.2版本或更新版本,能够解决从节点过期数据可见性问题对于其他类型的(网络延迟,时钟不同步)只能是配置更好的网络环境以及时钟尽量同步 复制风暴

复制风暴,是指redis 客户端缓冲区溢出和复制积压缓冲区溢出导致从节点不断的向主节点发起全量复制,给主节点CPU,内存,网络等带来巨大的消耗。

下面分别介绍。

客户端缓冲区溢出

client-output-buffer-limit slave 256mb 64mb 60

上述为客户端缓冲区默认配置项,slave 表示从节点类型的客户端, 后面三个值分别表示:最大限制,最小限制,最小限制持续时间。

此缓冲区可以理解为类似于socket buffer的功能,暂存发送到网络上的数据。当客户端缓冲区使用量超过最大限制或 达到最小限制且持续时间达到配置的值,主节点会直接关闭此连接,也就意味着复制失败。在哨兵模式下,哨兵节点会让从节点重新发起复制请求。

为什么会出现缓冲区溢出呢?快照数据量大,网络环境不好,从节点处理不及时,导致缓冲区不断的堆积。

复制积压缓冲区


复制积压缓冲区是指在主从之间出现短暂的网络断链,待复制数据被暂存到复制积压缓冲区。

复制积压缓冲区是环形区域,上图中master_repl_offset 表示在从节点发起全量复制或主从出现断链期间主节点写数据到复制积压缓冲区的位置。slave_repl_offset 为从节点需要从复制积压缓冲区中获取数据的起始位置。

当主从出现网络断链或数据集过大,且主节点写并发很高,就会导致master_repl_offset 追赶上slave_repl_offset,追赶上之后,slave_repl_offset和master_repl_offset 之间的数据便会被覆盖,当从节点请求其slave_repl_offset之后数据时无法从复制积压缓冲区中找到数据,便会触发从节点再次发起全量复制,以此往复,便出现复制风暴。

复制风暴的危害

复制风暴之所以会对主节点产生比较大的影响,主要是因为主从之间的全量复制。
全量复制是从节点向主节点发起全量复制请求,主节点会fork一个子进程,生成RDB快照。

下图为fork一个子进程后,父进程发生了写操作(从上到下):

如果redis数据集很大,fork操作本身也会很耗时。由于fork使用COW(copy on write)写时复制技术,虽然fork操作使得子进程和父进程共享物理内存页,但是子进程要复制一些进程数据结构,其中内存页表(虚拟内存和物理内存地址映射表),redis占用内存越大,其页表就会越大,复制也就会更耗时。如果主节点写并发高,就会导致父进程将写操作对应的内存页进行拷贝,会占用额外内存,就导致redis内存占用增加,最终导致内存不足,且很可能会触发操作系统的OOM杀死redis进程。

除此之外,fork操作是在主线程中进行,fork耗时过长会阻塞主线程,那么主线程服务于外部的请求就会被阻塞。频繁的全量RDB对CPU资源消耗也会生高,会使得主线程对CPU的使用率降低。

频繁的全量复制,也会占用大量的网络带宽资源,如果redis节点是单网卡的话,那么外部请求的处理则会更耗时。

复制风暴解决方案

前面已经分析了复制风暴出现的原因及其危害。那么我们就可以采取针对性的措施来避免。

根据网络环境及主从复制情况配置更大的客户端缓冲区和复制积压缓冲区避免给单Redis节点配置过大的内存,一个大内存的节点不如多个小内存的节点(比如一个32G内存的节点,不如配置两个16G的节点) 结束语

期待读者们的评论,在学习的道路上一起前进。GO! GO! GO!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。