我是如何一步步让公司的MySQL支撑亿级流量的

本文详细阐述了主从复制在MySQL中的工作原理,包括异步复制过程,以及如何通过数据冗余、缓存和查询主库等方式避免主从延迟对业务的影响。此外,还讨论了如何通过DB中间件简化DB访问,并提到了TDDL作为应用程序内部解决方案的特点。
摘要由CSDN通过智能技术生成
  • 拷贝目标DB为从库,负责数据查询

所以主从读写分离的关键:

  • 数据的拷贝

即主从复制

  • 屏蔽主从分离带来的访问DB方式的变化

让开发人员使用感觉依旧在使用单一DB

2 主从复制

=====================================================================

MySQL的主从复制依赖于binlog,即记录MySQL上的所有变化并以二进制形式保存在磁盘上二进制日志文件。

主从复制就是将binlog中的数据从主库传输到从库,一般异步:主库操作不会等待binlog同步完成。

2.1 主从复制的过程


  • 从库在连接到主节点时会创建一个I/O线程,以请求主库更新的binlog,并把接收到的binlog写入relay log文件,主库也会创建一个log dump线程发送binlog给从库

  • 从库还会创建一个SQL线程,读relay log,并在从库中做回放,最终实现主从的一致性

使用独立的log dump线程是异步,避免影响主库的主体更新流程,而从库在接收到信息后并不是写入从库的存储,是写入一个relay log,这是为避免写入从库实际存储会比较耗时,最终造成从库和主库延迟变长。

  • 主从异步复制的过程

基于性能考虑,主库写入流程并没有等待主从同步完成就返回结果,极端情况下,比如主库上binlog还没来得及落盘,就发生磁盘损坏或机器掉电,导致binlog丢失,主从数据不一致。不过概率很低,可容忍。

主库宕机后,binlog丢失导致的主从数据不一致也只能手动恢复。

主从复制后,即可:

  • 在写入时只写主库

  • 在读数据时只读从库

这样即使写请求会锁表或锁记录,也不会影响读请求执行。高并发下,可部署多个从库共同承担读流量,即一主多从支撑高并发读。

从库也能当成个备库,以避免主库故障导致数据丢失。

那无限制地增加从库就能支撑更高并发吗?

NO!从库越多,从库连接上来的I/O线程越多,主库也要创建同样多log dump线程处理复制的请求,对于主库资源消耗较高,同时受限于主库的网络带宽,所以一般一个主库最多挂3~5个从库。

2.2 主从复制的副作用


比如发朋友圈这一操作,就存在数据的:

  • 同步操作

如更新DB

  • 异步操作

如将朋友圈内容同步给审核系统

所以更新完主库后,会将朋友圈ID写入MQ,由Consumer依据ID在从库获取朋友圈信息再发给审核系统。

此时若主从DB存在延迟,会导致在从库取不到朋友圈信息,出现异常!

  • 主从延迟对业务的影响示意图

2.3 避免主从复制的延迟


这咋办呢?其实解决方案有很多,核心思想都是 尽量不去从库查询数据。因此针对上述案例,就有如下方案:

2.3.1 数据冗余

可在发MQ时,不止发送朋友圈ID,而是发给Consumer需要的所有朋友圈信息,避免从DB重新查询数据。

推荐该方案,因为足够简单,不过可能造成单条消息较大,从而增加消息发送的带宽和时间。

2.3.2 使用Cache

在同步写DB的同时,把朋友圈数据写Cache,这样Consumer在获取朋友圈信息时,优先查询Cache,这也能保证数据一致性。

该方案适合新增数据的场景。若是在更新数据场景下,先更新Cache可能导致数据不一致。比如两个线程同时更新数据:

  • 线程A把Cache数据更新为1
  • 另一个线程B把Cache数据更新为2
  • 然后线程B又更新DB数据为2
  • 线程A再更新DB数据为1

最终DB值(1)和Cache值(2)不一致!

2.3.3 查询主库

可以在Consumer中不查询从库,而改为查询主库。

使用要慎重,要明确查询的量级不会很大,是在主库的可承受范围之内,否则会对主库造成较大压力。

若非万不得已,不要使用该方案。因为要提供一个查询主库的接口,很难保证其他人不滥用该方法。

主从同步延迟也是排查问题时容易忽略。

有时会遇到从DB获取不到信息的诡异问题,会纠结代码中是否有一些逻辑把之前写入内容删除了,但发现过段时间再去查询时又能读到数据,这基本就是主从延迟问题。

所以,一般把从库落后的时间作为一个重点DB指标,做监控和报警,正常时间在ms级,达到s级就要告警。

主从的延迟时间预警,那如何通过哪个数据库中的哪个指标来判别? 在从从库中,通过监控show slave

status\G命令输出的Seconds_Behind_Master参数的值判断,是否有发生主从延时。

这个参数值是通过比较sql_thread执行的event的timestamp和io_thread复制好的

event的timestamp(简写为ts)进行比较,而得到的这么一个差值。

但如果复制同步主库bin_log日志的io_thread线程负载过高,则Seconds_Behind_Master一直为0,即无法预警,通过Seconds_Behind_Master这个值来判断延迟是不够准确。其实还可以通过比对master和slave的binlog位置。

3 如何访问DB

=======================================================================

使用主从复制将数据复制到多个节点,也实现了DB的读写分离,这时,对DB的使用也发生了变化:

  • 以前只需使用一个DB地址

  • 现在需使用一个主库地址,多个从库地址,且需区分写入操作和查询操作,再结合“分库分表”,复杂度大大提升。

为降低实现的复杂度,业界涌现了很多DB中间件解决DB的访问问题,大致分为:

3.1 应用程序内部


如TDDL( Taobao Distributed Data Layer),以代码形式内嵌运行在应用程序内部。可看成是一种数据源代理,它的配置管理多个数据源,每个数据源对应一个DB,可能是主库或从库。

当有一个DB请求时,中间件将SQL语句发给某个指定数据源,然后返回处理结果。

优点

简单易用,部署成本低,因为植入应用程序内部,与程序一同运行,适合运维较弱的小团队。

缺点

缺乏多语言支持,都是Java语言开发的,无法支持其他的语言。版本升级也依赖使用方的更新。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

读者福利

分享一份自己整理好的Java面试手册,还有一些面试题pdf

不要停下自己学习的脚步

字节跳动的面试分享,为了拿下这个offer鬼知道我经历了什么

字节跳动的面试分享,为了拿下这个offer鬼知道我经历了什么

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

读者福利

分享一份自己整理好的Java面试手册,还有一些面试题pdf

不要停下自己学习的脚步

[外链图片转存中…(img-7G9DZp26-1713691242397)]

[外链图片转存中…(img-tpChqST9-1713691242397)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值