原文出处:Java 技术驿站 『chenssy』

前面两篇博客已经详细介绍了主从复制的原理,相信各位对 Redis 的主从复制有了一个比较深入的了解,这篇博客主要介绍主从复制的应用以及它的一些问题。

读写分离

我们都知道对于读多写少的场景,我们可以使用读写分离的方式来提供整体的并发量,对于 Redis 也一样,由于从节点是主节点的副本,我们可以利用主节点提供写服务,一个或者多个从节点提供读服务,这样就最大化 Redis 的读负载能力。当然,这样并不是说主从架构下的读写分离没有问题,恰恰是有大问题,在这种情况下,业务需要面对如下几个问题:

数据延迟

读到过期数据

从节点故障

数据延迟

在命令传送阶段,Redis 主从节点同步命令的过程是异步的,所以势必会导致主从节点的数据不一致性,如果我们的应用对数据的不一致性接受程度不是很高,则我们可以从以下几个方面优化:

优化主从节点的网络环境(比如主从节点部署在同机房)

监控从节点的延迟性,如果延迟过大,则通知应用不从该节点读取数据,这种方案需要改造客户端,工作量不小,一般不推荐

从节点的 slave-serve-stale-data 参数便与其有关,它控制着从节点对读请求的响应情况,如果为 yes(默认值),则从节点可以响应客户端的命令,如果为 NO,则只能响应 info、slaveof 等少数命令。所以如果应用对数据一致性要求较高,则应该将该参数设置为 NO。

读到过期数据

Redis 内部对过期数据的删除有两种方案:惰性删除、定时删除。

惰性删除:服务器不会主动删除数据,只有当客户端查询某个数据时,服务器判断该数据是否过期,过期则删除

定时删除:服务器内部维护着一个定时任务,会定时删除过期的数据

在主从复制的架构模式下,我们知道,所有的写操作都发生在主节点,删除数据时也是在主节点删除,然后将删除命令同步给从节点,由于主从节点的延迟性,主节点删除了某些数据,从节点不一定也删除了,所以在从节点是比较容易读到过期的数据。不过幸好,在 Redis 3.2 版本中,增加了对数据是否过期的判断,如果读到的数据过期了,则不会返回给客户端了,所以将 Redis 升级到 3.2 版本后即可解决该问题。

对于惰性删除和定时删除小编会在后续博文中详细介绍。

从节点故障

如果从节点出现故障了,在没有哨兵的情况下,客户端是无法进行切换的,所以我们需要对客户端进行改造,它内部需要维护一个可用的 Redis 节点列表,当某个节点出现故障不可用后,立刻切换到其他可用节点,当然这种工作量会比较大,得不偿失。

规避全量复制

全量复制要经过如下几个过程:建立连接 ---> 生成 RDB 文件 ---> 发送 RDB 文件 ---> 清空旧数据 ---> 加载新数据,五个过程,工作量巨大,是一个非常消耗资源的操作,所以我们需要尽可能的规避。在博客[【死磕 Redis】--- 主从复制(二):全量复制和部分复制]()中,我们了解到有如下几种情况会发生全量复制:

第一次复制

节点运行 ID 不匹配

复制偏移量 offset 不在复制积压缓冲区中

第一次复制

这种情况是无法避免的,所以如果我们要对数据量较大且流量较高的主节点添加从节点的话,最好是选择在低峰值进行操作。

节点运行 ID 不匹配

主节点重启时,他的 runid 会发生改变,在进行复制的时候,发现主从节点的 runid 不一致,则进行全量复制,对于这种情况一般都应该在架构上面规避,比如提供故障转移的功能。还有一种情况就是我们修改了主节点的配置,需要重启才能够生效,这个时候如果重启主节点发生全量复制就得不偿失了,可以选择安全重启的方式(debug reload),在这种情况,主节点重启的 runid 是不会发生改变的。

复制偏移量 offset 不在复制积压缓冲区中

当主从节点因网络中断而重新连接,从节点会发送 psync 命令进行部分复制请求,主节点除了校验 runid 是否一致外还会判断请求的 offset 是否在缓冲区中,如果不在这进行全量复制。复制积压缓冲区默认大小为 1MB,这对于高流量的主节点而言势必显得有点儿小了,所以为了避免全量复制,我们需要根据中断时长来调整复制积压缓冲区的大小,调整为 复制积压缓冲区大小 > 平均中断时长 * 平均写命令字节数,这样就可以避免因为复制积压缓冲区不足而导致的全量复制

规避复制风暴

复制风暴指的是大量从节点对同一主节点或者同一台服务器的多个主节点短时间内发起全量复制的过程。复制风暴会导致主节点消耗大量的 CPU、内存、宽带,所以我们需要尽可能的规避复制风暴。

单一主节点

这种情况一般都发生在一个主节点挂载了多个从节点,所以规避的方案也比较简单:

减少挂载的从节点

将架构调整为树状结构,增加中间层,但是这样导致的后果是中间层越多,后面节点的数据延迟就越高,同时也增加了运维的难度

单一机器

Redis 的单线程运行的,所以会存在一台机器上面部署多个 Redis 服务,同时也有多个是主节点,所以规避方案:

将主节点分散在多台不同的机器上

当主节点所在机器故障后提供故障转移机制,避免机器回复后进行密集的全量复制

主从复制的相关配置

slaveof :Redis启动时起作用;作用是建立复制关系,开启了该配置的 Redis 服务器在启动后成为从节点。该注释默认注释掉,即 Redis 服务器默认都是主节点。

repl-timeout 60:与各个阶段主从节点连接超时判断有关,见前面的介绍。

主节点相关配置

repl-diskless-sync no:作用于全量复制阶段,控制主节点是否使用diskless复制(无盘复制)。所谓diskless复制,是指在全量复制时,主节点不再先把数据写入RDB文件,而是直接写入slave的socket中,整个过程中不涉及硬盘;diskless复制在磁盘IO很慢而网速很快时更有优势。需要注意的是,截至Redis3.0,diskless复制处于实验阶段,默认是关闭的。

repl-diskless-sync-delay 5:该配置作用于全量复制阶段,当主节点使用diskless复制时,该配置决定主节点向从节点发送之前停顿的时间,单位是秒;只有当diskless复制打开时有效,默认5s。之所以设置停顿时间,是基于以下两个考虑:(1)向slave的socket的传输一旦开始,新连接的slave只能等待当前数据传输结束,才能开始新的数据传输 (2)多个从节点有较大的概率在短时间内建立主从复制。

client-output-buffer-limit slave 256MB 64MB 60:与全量复制阶段主节点的缓冲区大小有关。

repl-disable-tcp-nodelay no:与命令传播阶段的延迟有关。

masterauth :与连接建立阶段的身份验证有关。

repl-ping-slave-period 10:与命令传播阶段主从节点的超时判断有关。

repl-backlog-size 1mb:复制积压缓冲区的大小。

repl-backlog-ttl 3600:当主节点没有从节点时,复制积压缓冲区保留的时间,这样当断开的从节点重新连进来时,可以进行全量复制;默认3600s。如果设置为0,则永远不会释放复制积压缓冲区。

min-slaves-to-write 3与min-slaves-max-lag 10:规定了主节点的最小从节点数目,及对应的最大延迟。

从节点相关配置

slave-serve-stale-data yes:与从节点数据陈旧时是否响应客户端命令有关。

slave-read-only yes:从节点是否只读;默认是只读的。由于从节点开启写操作容易导致主从节点的数据不一致,因此该配置尽量不要修改。

参考

《Redis 开发与运维》

redis 永不过期 java_死磕 Java相关推荐

  1. 死磕java_死磕 java同步系列之AQS终篇(面试)

    问题 (1)AQS的定位? (2)AQS的重要组成部分? (3)AQS运用的设计模式? (4)AQS的总体流程? 简介 AQS的全称是AbstractQueuedSynchronizer,它的定位是为 ...

  2. 死磕java_死磕 java同步系列之AQS起篇

    问题 (1)AQS是什么? (2)AQS的定位? (3)AQS的实现原理? (4)基于AQS实现自己的锁? 简介 AQS的全称是AbstractQueuedSynchronizer,它的定位是为Jav ...

  3. 死磕java_死磕Java——集合

    死磕Java--多线程下的集合 1.1.ArrayList 都知道ArrayList是线程不安全的,如果在多线程下使用了ArrayList会产生什么样的情况,简单看一段代码. public stati ...

  4. copyof java_死磕 java集合之CopyOnWriteArrayList源码分析

    简介 CopyOnWriteArrayList是ArrayList的线程安全版本,内部也是通过数组实现,每次对数组的修改都完全拷贝一份新的数组来修改,修改完了再替换掉老数组,这样保证了只阻塞写操作,不 ...

  5. phaser java_死磕 java同步系列之Phaser源码解析

    问题 (1)Phaser是什么? (2)Phaser具有哪些特性? (3)Phaser相对于CyclicBarrier和CountDownLatch的优势? 简介 Phaser,翻译为阶段,它适用于这 ...

  6. 死磕 java同步系列之redis分布式锁进化史

    问题 (1)redis如何实现分布式锁? (2)redis分布式锁有哪些优点? (3)redis分布式锁有哪些缺点? (4)redis实现分布式锁有没有现成的轮子可以使用? 简介 Redis(全称:R ...

  7. 死磕 java同步系列之终结篇

    简介 同步系列到此就结束了,本篇文章对同步系列做一个总结. 脑图 下面是关于同步系列的一份脑图,列举了主要的知识点和问题点,看过本系列文章的同学可以根据脑图自行回顾所学的内容,也可以作为面试前的准备. ...

  8. 死磕 java集合之终结篇

    概览 我们先来看一看java中所有集合的类关系图. 这里面的类太多了,请放大看,如果放大还看不清,请再放大看,如果还是看不清,请放弃. 我们下面主要分成五个部分来逐个击破. List List中的元素 ...

  9. 死磕 java集合之ArrayDeque源码分析

    问题 (1)什么是双端队列? (2)ArrayDeque是怎么实现双端队列的? (3)ArrayDeque是线程安全的吗? (4)ArrayDeque是有界的吗? 简介 双端队列是一种特殊的队列,它的 ...

最新文章

  1. 美国国防部作战指挥系统桌面虚拟化案例视频(中文配音版)
  2. python3 subprocess.Popen 报错 No such file or directory
  3. 【错误记录】Git 使用报错 ( git branch -a 仍能查询到已经删除的远程分支 )
  4. 爬虫开发10.scrapy框架之日志等级和请求传参
  5. 我的世界中国版服务器无限夜视,我的世界服务器游戏技巧 无限夜视的方法
  6. 软件测试 学习之路 linux vim编辑器
  7. 字节输入流-InputStream demo3
  8. 6000万条GitHub帖子告诉你:工作状态与表情符号强相关
  9. 成功在MP4封装的H264视频中提取能播放的裸流
  10. 教你几招——交换变量数值
  11. 遗传算法matlab_三分钟学会遗传算法
  12. 服务器主板的无线驱动,驱动天空 - 品牌主板 - 服务器主板 SERVER
  13. Qt开源作品16-通用无边框拖动拉伸
  14. uniapp微信小程序实现连接低功耗蓝牙打印功能
  15. 英语不好学不好编程?程序员记忆单词专属诀窍,效果简直要逆天
  16. AtCoder Beginner Contest 170 F. Pond Skater
  17. Kafka系列之:深入理解Kafka 主题、分区、副本、LEO、ISR、HW、Kafka的主写主读和分区leader选举
  18. 我国移动支付的安全问题与完善建议
  19. C语言:判断一个数是否为素数(3种方法,含注释)
  20. 工信部印发《关于电信设备进网许可制度若干改革举措的通告》(附解读)

热门文章

  1. python 难度-python上手难度算较低
  2. 自学python都需要哪些书-【经验分享】自学Python的学习顺序!附学习资料
  3. python爬虫有什么用处-python为什么叫爬虫 python有什么优势
  4. python主要用来开发什么-python主要用于什么开发?
  5. 软件测试用python一般用来做什么-Python用来做Web开发的优势有哪些
  6. python代码打好了怎么运行-python代码是怎样运行的
  7. ipad编程软件python-iPad可用的软件编程软件有吗?
  8. 大学生学python到底有没有有-大学生该不该学Python?太纠结了?
  9. python二次开发攻略-ABAQUS Python二次开发攻略
  10. python买什么书-有什么关于python的书值得阅读?