当前位置: 首页 > article >正文

Redis: 主从复制故障分析及解决方案

常见故障及解决方案


1 )主从数据一致性的问题

  • 说到数据一致性,在主从模式下无非就两两种情况
    • 一种就是主多从少
    • 另外一种是主少从多
  • 主多从少
    • 一般就是在网络延迟的情况下
    • 从服务器还没有把主服务器的数据全部复制过来
    • 这个时候可以等延迟结束以后,让从服务器进行部分重同步
    • 也就是我们所说的增量复制
    • 但如果你比较着急,你想让它立刻执行部分重同步,可以人为的干预
    • 在从节点输入 PSYNC 指令空格跟上主节点master的run_id 空格
    • 然后再追加上你需要复制的起始偏移量 offset 就可以实现部分重同步
    • 这个是通过指令让它触发的,还有一种情况比较简单,粗暴就是
      • 直接人为的断开,让它重新跟主节点连接,也会触发部分重同步
    • 在 Redis@2.8 版本之前,如果我们的主从断开重新连接
      • 每一次这样的断开重连它都会做一个全量复制,这无疑是一个非常降低性能的问题
      • Redis 为了解决这个问题,在 2.8 版本之后添加了一个特性
      • 就是说主从断开重连的时候,它可以去进行一个逻辑判断处理
      • 再决定现在要进行全量复制,还是增量复制
      • 其实就是主服务器,在内存里边给每个从服务器维护了一份同步日志和一个同步标识
      • 这个同步日志就是 backlog,这个同步标识就是offset
      • 每个从服务器在跟主服务器进行同步的时候,会携带同步标识和上次同步的位置
      • 这样的话就可以判断出我这次的连接是要做全量复制,还是增量复制
  • 主少从多
    • 这种情况一般是比较少见的
    • 因为这种模式是从服务器开启了写操作导致的
    • 比如说我们的从服务器它是读写模式
    • 那我可能从从服务器这边写入的一些数据就会导致主从不一致
    • 这种情况也比较简单,把从服务器的数据全部是清空,让它跟主服务器进行全量复制即可

2 )数据延迟的问题

  • 我们先来定义一下这个延迟是通过哪些属属性,哪些配置决决定
  • 在 info replication 命令返回的信息中有一个偏移量
  • 其实就是根据这个偏移量来决定当前数据的一个健康状态,数据是否有延迟
  • 主节点在写入命令的时候,比如,写入了一个三千的字节长度的偏移量
  • 而我们的从节点此时只复制了一千,他们的一个差值是比较大的时候
  • 就说明这个数据延迟就挺高了,对于这种,我们的解决办法

2.1 可以编写一个外部程序来监听从节点

  • 当延迟比较高的时候,我们就可以报警,然后通知客户端
  • 让客户端在访问的时候,切换到主节点去访问,或者说其他的一些可靠的节点

2.2 修改配置文件

  • 把配置文件中看到的这个 slave-server-stale-data 配置项改为no,它的默认值是yes
  • 当我们改为no的时候,除了 INFO 和 SLAVOF 命令之外,所有其他的请求它都会返回一个错误
  • 这个错误大概的意思就是说我正在同步,同步完之后再给你提供服务

3 )脏数据问题

  • 说到脏数据,我们首先得定义一下这个脏数据是怎么产生的?
  • Redis 内部的它的删除机制有惰性,定时,主动三种
  • 这是因为 Redis 的删除机制,导致了过期数据,没有被及时删除,产生了脏数据

3.1 惰性

  • 我现在有一个 key 已经过期了,但是没有人访问,或者说没有客户端访问,我就不会去删除它
  • 在访问的时候,我才会去判断它有没有过期过期了才会删除,这就是惰性
  • 这就会导致一个已过期的 key 如果没有被访问,它就会永远留在内存中
  • 于是 Redis 就搞了一个定时删除,定时删除就是来解决惰性删除这个问题的

3.2 定时

  • 它内部有一个定时任务,隔一段时间采样一批 key 判断一下有没有过期,过期就把它删掉

3.3 主动

  • 主动删除指的是当前的数据存储已经超过了 Redis 最大内存上限,然后触发主动删除
  • 因为 Redis 删除机制的原因导致可能会有过期数据产生,就说白了有脏数据产生
  • 还有一种脏数据产生的方式是从节点可写导致的

3.4 从节点写操作

  • 从节点一般都是只读模式,如果说你开启了读写模式
  • 这个数据在从节点误写入,可能也会导致它变为一个脏数据

解决方案

  • 对于脏数据的一个解决方案有以下几点
  • 首先,可以采取忽略,这是最简单的一种解决方案
    • 比如说在某些业务场景下,例如 12306 这个查询双十一抢购查询库存
    • 当我们去查询这些信息的时候,我并没有去做一个写操作
    • 这样的业务场景,它是允许拟出现一定的错误,它有一定的容错的
    • 可以选择忽略,如果说我现在要去下单呢
    • 比如说我就要去买一张车票,或者说我现在就要去秒杀抢购这个商品
    • 那这个时候数据一定要是准确的,我们可以采用强制读主的方式
  • 第二,强制读主
    • 比如说我已经知道了,从节点可能会有脏数据。
    • 我就选择性强制读主来解决这个问题
  • 第三,从节点只读模式
    • 这样可以规避从节点写入脏数据的问题
  • 注意,Redis 删除策略产生的过期数据问题,在 3.2 版本解决了
    • 从节点每次在获取key的时候,它会去判断一下这个key是否过期来决定最后是否要返回这个数据

4 ) 数据安全性相关的问题

  • 数据安全性指的是我们为了提升Redis的性能有可能会做出关闭主节点持久化的一个操作
  • 因为每一次主节点跟从节点同步的时候,主节点要 BGSAVE RDB
  • 我们直接把主节点持化化关闭上,这样的话就不会再去做 BGSAVE RDB的操作
  • 所有的数据直接会持久化在从节点上,但是它也会带来一定的问题
  • 假设现在我有一个主节点,主节点关闭了持久化
  • 那就意味着主节点只有内存中有数据,磁盘上是没有数据的
  • 主节点如果说故障了,重启之后,此时主节点的数据是不是就是空?
  • 然后我们的从节点跟主节点重新建立连接发现 run_id 发生了变化,它要发起一个复制请求
  • 把一个空的数据复制过来,覆盖了自己,从节点的数据也就变成空了

解决方案

  • 非常简单,要么你就把主节点持久化开启
  • 或者说你要提升性能主节点的持久化必须得关闭,那你就不要让它自动重启
  • 因为我们刚才提到了主节点是在重启起来之后,主节点建立连接被覆盖为空了
  • 我们的主节点不要添加第三方的这种自动重启的能力
  • 比如说跟docker或者脚本监控着我们的Redis服务
  • 故障重启了一重启,那不就丢失了么

5 )性能优化相关的问题

  • 性能优化,主要解决的就是访问的问题,提升访问速度的
  • 我们看下,如何规避全量复制,如何规避复报风暴

5.1 如何规避全量复制

  • 首先全量复制,现在从节点要把主节点上所有的数据全部都复制过来,被称为全量复制
  • 它可能出现的场景有这么几个
    • 1 )第一次全量复制
      • 指的就是当一个从节点挂载到主节点的时候,肯定要做一次全量复制。
      • 可以选择在低峰时段去进行挂载从节点,比如说在凌晨三点
    • 2 )选取从节点为主节点
      • 比如说我从节点上现在已经有主节点的数据了
      • 我就直接把它选取为主节点,就避免了全量复制的这个过程的产生
      • 这个操作,可以人为的去做,或者哨兵也可以帮我们自动完成这个操作
    • 3 )增大复制缓冲区
      • 复制缓冲区默认是 1M,我们可以增大缓冲区的大小
      • 这样的话,提高 offset 偏移量的命中率,来降低全量复制的可能性

5.2 如何规避复制风暴

  • 复制风暴指的是多个从节点其中的同一时间向主节点发起了复制请求,主节点压力比较大

  • 复制风暴又会根据 Redis 的架构模式分为两种情况

    • 第一种情况是单主节点复制风暴
    • 另外一种情况:单机多主节点复制风暴
  • 单主节点复制风暴

    • 就是我现在有一个主节点,然后下边挂了很多的从节点
    • 比如说就挂了十个吧,主节点故障重启了,十个从节点发起了复制请求
    • 主节点压力很大,怎么解决呢?
    • 第一,选举从节点为主节点
      • 因为从节点上已经有主节点的数据了
      • 我们直接选举从节点为主节点,就可以避免全量复制的一次操作
    • 第二个解决方案就是用树状复制结构
      • 比如说我现在原来是一个主节点,下边挂了十个从节点
      • 现在我一个主节点下边,我可以挂两个从节点
      • 我再让这两个从节点分别去挂载四个其他的从节点来解决这个问题
  • 单机多主复制风暴

    • 它的出现是因为咱们都知道 Redis 的操作,实际上是单线程的
    • 它是发挥不了 CPU多核的这个特性
    • 所以说有的人为了节省资源,它就会在一个机器上装多个 Redis
    • 并且这多个 Redis 都是主节点的情况下才会出现单机多主复制风暴
    • 它的解决方案非常简单
      • 就是别省钱
      • 把这些主节点分散在多台机器上,就可以解决这个问题

http://www.kler.cn/news/327421.html

相关文章:

  • [Cocoa]_[初级]_[绘制文本如何设置断行方式]
  • 【星海saul随笔】Ubuntu基础知识
  • 构建高效的足球青训后台:Spring Boot应用
  • Web3.0 应用项目
  • 【网络安全 | 渗透工具】自动化 .env/.git文件检测
  • 【Linux 从基础到进阶】Spark 大数据计算引擎使用
  • React表单:formik、final-form和react-hook-form
  • PHP反序列化5(回调函数call_user_func_array)
  • 计算机毕业设计python+spark知识图谱音乐推荐系统 音乐数据分析可视化大屏 音乐爬虫 LSTM情感分析 大数据毕设 深度学习 机器学习
  • C#核心(3)类中的成员变量和访问修饰符
  • Oracle 闪回版本(闪回表到指定SCN)
  • 袋鼠云数据资产平台:数据模型标准化建表重构升级
  • 【YashanDB知识库】客户端字符集与数据库字符集兼容问题
  • 基于ESP8266—AT指令连接阿里云+MQTT透传数据(1)
  • Ceph RocksDB 深度调优
  • 韦东山FreeRTOS笔记
  • 1.7 编码与调制
  • Ubuntu上安装Miniconda并自定义环境存储路径
  • 什么是嵌入式?行业前景如何?
  • Parallels Desktop19官方中文版10月最新
  • MySQL中的InnoDB存储引擎
  • 车载诊断技术:汽车健康的守护者
  • 【艾思科蓝】Vue.js组件开发实战:从零构建高效可复用组件
  • 《OpenCV 计算机视觉》—— 图像拼接
  • 基于SpringBoot+Vue+MySQL的考勤管理系统
  • Python办公自动化案例:批量修改Word文件中的段落格式
  • 【算法——KMP】
  • 论文阅读【时间序列】ModerTCN (ICLR2024)
  • Qt Linguist手册-翻译员
  • uni-app如果自定义tabbar实现底部样式有凸起效果,背景带圆角