redis主从复制常见的一些坑

读写分离的问题

164518_Leru_3371837.png

1.数据复制的延迟

读写分离时,master会异步的将数据复制到slave,如果这是slave发生阻塞,则会延迟master数据的写命令,造成数据不一致的情况

解决方法:可以对slave的偏移量值进行监控,如果发现某台slave的偏移量有问题,则将数据读取操作切换到master,但本身这个监控开销比较高,所以关于这个问题,大部分的情况是可以直接使用而不去考虑的。

2.读到过期的数据

我们知道redis在删除过期key的时候,是有两种策略,第一种是懒惰型策略,即只有当redis操作这个key的时候,发现这个key过期,就会把这个key删除。第二种是定期采样一些key进行删除。

针对上面说的两种过期策略,会有个问题,即如果我们过期key的数量非常多,而采样速度根本比不上过期key的生成速度时会造成很多过期数据没有删除,但在redis里master和slave达成一种协议,slave是不能处理数据的(即不能删除数据)而我们的客户端没有及时读到到过期数据同步给master将key删除,就会导致slave读到过期的数据(这个问题已经在redis3.2版本中解决)

主从配置不一致

这个问题一般很少见,但如果有,就会发生很多诡异的问题

例如:

1. maxmemory配置不一致:这个会导致数据的丢失

原因:例如master配置4G,slave配置2G,这个时候主从复制可以成功,但,如果在进行某一次全量复制的时候,slave拿到master的RDB加载数据时发现自身的2G内存不够用,这时就会触发slave的maxmemory策略,将数据进行淘汰。更可怕的是,在高可用的集群环境下,如果我们将这台slave升级成master的时候,就会发现数据已经丢失了。

2. 数据结构优化参数不一致(例如hash-max-ziplist-entries):这个就会导致内存不一致

原因:例如在master上对这个参数进行了优化,而在slave没有配置,就会造成主从节点内存不一致的诡异问题。

规避全量复制

首先,我们知道,redis复制有全量复制和部分复制两种(这个我前面博客有写到)而全量复制的开销是很大的。那么我们来看看,如何尽量去规避全量复制。

1.第一次全量复制

当我们某一台slave第一次去挂到master上时,是不可避免要进行一次全量复制的,那么,我们如何去想办法降低开销呢?

方案1:小主节点,例如我们把redis分成2G一个节点,这样一来,会加速RDB的生成和同步,同时还可以降低我们fork子进程的开销(master会fork一个子进程来生成同步需要的RDB文件,而fork是要拷贝内存快的,如果主节点内存太大,fork的开销就大)。

方案2:既然第一次不可以避免,那我们可以选在集群低峰的时间(凌晨)进行slave的挂载。

2.节点RunID不匹配

例如我们主节点重启(RunID发生变化),对于slave来说,它会保存之前master节点的RunID,如果它发现了此时master的RunID发生变化,那它会认为这是master过来的数据可能是不安全的,就会采取一次全量复制

解决办法:对于这类问题,我们只有是做一些故障转移的手段,例如master发生故障宕掉,我们选举一台slave晋升为master(哨兵或集群)

3.复制积压缓冲区不足

我在全量复制与部分复制那篇文章提到过,master生成RDB同步到slave,slave加载RDB这段时间里,master的所有写命令都会保存到一个复制缓冲队列里(如果主从直接网络抖动,进行部分复制也是走这个逻辑),待slave加载完RDB后,拿offset的值到这个队列里判断,如果在这个队列中,则把这个队列从offset到末尾全部同步过来,这个队列的默认值为1M。而如果发现offset不在这个队列,就会产生全量复制。

解决办法:增大复制缓冲区的配置 rel_backlog_size 默认1M,我们可以设置大一些,从而来加大我们offset的命中率。这个值,我们可以假设,一般我们网络故障时间一般是分钟级别,那我们可以根据我们当前的QPS来算一下每分钟可以写入多少字节,再乘以我们可能发生故障的分钟就可以得到我们这个理想的值。

规避复制风暴

什么是复制风暴?举例:我们master重启,其master下的所有slave检测到RunID发生变化,导致所有从节点向主节点做全量复制。尽管redis对这个问题做了优化,即只生成一份RDB文件,但需要多次传输,仍然开销很大。

1.单主节点复制风暴:主节点重启,多从节点全量复制

解决:更换复制拓扑如下图:

175610_poHK_3371837.png

1.我们将原来master与slave中间加一个或多个slave,再在slave上加若干个slave,这样可以分担所有slave对master复制的压力。(这种架构还是有问题:读写分离的时候,slave1也发生了故障,怎么去处理?)

2.如果只是实现高可用,而不做读写分离,那当master宕机,直接晋升一台slave即可。

2.单机器复制风暴:机器宕机后的大量全量复制,如下图:

180134_ChpF_3371837.png

当machine-A这个机器宕机重启,会导致该机器所有master下的所有slave同时产生复制。(灾难)

解决:

1.主节点分散多机器(将master分散到不同机器上部署)

2.还有我们可以采用高可用手段(slave晋升master)就不会有类似问题了。

转载于:https://my.oschina.net/u/3371837/blog/1789452

  • 1
    点赞
  • 0
    评论
  • 7
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

<p> <strong><span>Redis是一个key-value</span></strong><a href="https://baike.baidu.com/item/%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F"><strong><span>存储系统</span></strong></a><strong><span><span>。和</span>Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(</span></strong><a href="https://baike.baidu.com/item/%E9%93%BE%E8%A1%A8"><strong><span>链表</span></strong></a><strong><span>)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些</span></strong><a href="https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B"><strong><span>数据类型</span></strong></a><strong><span><span>都支持</span>push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。</span></strong> </p> <p> <strong><span>Redis的出现,很大程度补偿了</span></strong><a href="https://baike.baidu.com/item/memcached"><strong><span>memcached</span></strong></a><strong><span><span>这类</span>key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。</span></strong> </p> <p> <strong><span>Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。</span></strong> </p> <p> <span>  </span></p><p> <strong><span> </span></strong> </p> <p> <strong><span>本课程主要讲解以下内容:</span></strong> </p> <p> <span>1. </span><strong><span>Redis的基本使用</span></strong> </p> <p> <span>2. </span><strong><span>Redis数据库数据类型</span></strong> </p> <p> <span>3. </span><strong><span>Redis数据库数据管理</span></strong> </p> <p> <span>4. </span><strong><span>Redis主从复制</span></strong> </p> <p> <span>5. </span><strong><span>Redis数据库的持久性</span></strong> </p> <p> <span>6. </span><strong><span>Redis的高可靠性和集群</span></strong> </p> <p> <span>7. </span><strong><span>Redis的优化和性能测试</span></strong> </p> <p> <span>8. </span><strong><span>Redis服务器的维护和管理</span></strong> </p> <p> <span>9. </span><strong><span>Redis服务器的常见问题排错</span></strong> </p> <p> <strong><span> </span></strong> </p> <img src="https://img-bss.csdn.net/201908300910404009.png" alt="" />
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值