• 今天解决了一个主从延迟导致超发的问题


    主从同步过程

    MySQL主从同步由主节点dump线程、从节点 I/O 线程、从节点SQL线程三个线程配合完成。

    1、从节点上的 I/O 进程主从去连接主节点,并带上同步的开始位置即指定日志文件的位置之后的日志内容

    2、主节点接收到来自从节点的 I/O 请求后,通过主节点dump线程读取指定日志位置之后的日志信息,返回给从节点。同时也返回binlog file的以及binlog position

    3、从节点的 I/O 线程接收到内容后,将接收到的日志内容写到本地的relay log中,并将读取到的binlog文件名和位置保存到master-info文件中

    4、从节点的SQL线程检测到relay log中新增加了内容后,将relay log回放写入到数据库中

    在这里插入图片描述

    主从复制模式

    1、异步模式

    主库写入binlog完成后提交事务。

    2、半同步模式

    保证至少有从库将日志写入relay log后应答成功才提交事务。

    3、全同步模式

    MySQL 主从复制默认是异步的模式

    主从延迟问题

    从上文可知主从同步无论哪种模式都是先写入从库的relay日志后再有SQL线程回放写入从库,所以或多或少的都会出现主从延迟问题。所以会导致一定时间内主从的不一致问题,开发中常见的读写分离存在主从延迟问题就是这个原因导致。

    主从延迟问题解决

    1、mysql层面。可以增加机器性能、减少网络延迟、降低数据安全措施例如关闭从节点binlog日志或者刷盘策略放开等增加从库写入的速度、还可以配置多个SQL线程等。

    2、业务层面。可以使用缓存后双写避免马上去读从库,也可以加延迟读取以减少延迟带来的业务问题,也可以直接读取主库。

    开头问题解决方案

    1、修改sql,增加一个判断条件兜底,保证不多发,update code set state=已领取 where state=未领取,这样可以确保一条号码不会被多次领取,但是需要处理领取失败的情况。可以在读取未领取号码时多读取几条,一条领取失败就领取下一条直到成功或者领完。

    2、使用缓存,将数据预读到缓存中,读的时候从缓存中读取,这样就可以避免去读从库,但是需要处理缓存和主库一致性问题。将号码放到redis队列中,每次从队列里去一条,用完后再读取到redis。

  • 相关阅读:
    Ubuntu安装freeSwitch
    Algorithm Review 5
    云e办(后端)——全局异常处理
    使用 AHK 在 VS Code 中根据上下文自动切换输入法状态
    教你如何进行Prometheus 分片自动缩放
    基于PHP的图书管理系统的设计与实现
    redis的原理和源码-事务机制
    PySpark
    xshell使用vi命令:bash:vim:command not found
    YOLO目标检测——昏暗车辆数据集+已标注VOC格式标签下载分享
  • 原文地址:https://blog.csdn.net/I_am_hardy/article/details/127947765