面试题
你们有没有做 MySQL 读写分离?如何实现 MySQL 的读写分离?MySQL 主从复制原理的是啥?如何解决 MySQL 主从同步的延时问题?
面试官心理分析
高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少。所以针对这个情况,就是写一个主库,但是主库挂多个从库,然后从多个从库来读,那不就可以支撑更高的读并发压力了吗?
面试题剖析
如何实现 MySQL 的读写分离?
其实很简单,就是基于主从复制架构,简单来说,就搞一个主库,挂多个从库,然后我们就单单只是写主库,然后主库会自动把数据给同步到从库上去。
MySQL 主从复制原理的是啥?
主库将变更写入 binlog 日志,然后从库连接到主库之后,从库有一个 IO 线程,将主库的 binlog 日志拷贝到自己本地,写入一个 relay 中继日志中。接着从库中有一个 SQL 线程会从中继日志读取 binlog,然后执行 binlog 日志中的内容,也就是在自己本地再次执行一遍 SQL,这样就可以保证自己跟主库的数据是一样的。
这里有一个非常重要的一点,就是从库同步主库数据的过程是串行化的,也就是说主库上并行的操作,在从库上会串行执行。所以这就是一个非常重要的点了,由于从库从主库拷贝日志以及串行执行 SQL 的特点,在高并发场景下,从库的数据一定会比主库慢一些,是有延时的。所以经常出现,刚写入主库的数据可能是读不到的,要过几十毫秒,甚至几百毫秒才能读取到。
而且这里还有另外一个问题,就是如果主库突然宕机,然后恰好数据还没同步到从库,那么有些数据可能在从库上是没有的,有些数据可能就丢失了。
所以 MySQL 实际上在这一块有两个机制,一个是半同步复制,用来解决主库数据丢失问题;一个是并行复制,用来解决主从同步延时问题。
这个所谓半同步复制,也叫 semi-sync 复制,指的就是主库写入 binlog 日志之后,就会将强制此时立即将数据同步到从库,从库将日志写入自己本地的 relay log 之后,接着会返回一个 ack 给主库,主库接收到至少一个从库的 ack 之后才会认为写操作完成了。
所谓并行复制,指的是从库开启多个线程,并行读取 relay log 中不同库的日志,然后并行重放不同库的日志,这是库级别的并行。
MySQL 主从同步延时问题(精华)
以前线上确实处理过因为主从同步延时问题而导致的线上的 bug,属于小型的生产事故。
是这个么场景。有个同学是这样写代码逻辑的。先插入一条数据,再把它查出来,然后更新这条数据。在生产环境高峰期,写并发达到了 2000/s,这个时候,主从复制延时大概是在小几十毫秒。线上会发现,每天总有那么一些数据,我们期望更新一些重要的数据状态,但在高峰期时候却没更新。用户跟客服反馈,而客服就会反馈给我们。
我们通过 MySQL 命令:
show status
查看 Seconds_Behind_Master ,可以看到从库复制主库的数据落后了几 ms。
一般来说,如果主从延迟较为严重,有以下解决方案:
往期回顾:
【Java问答学堂】1期 为什么使用消息队列?消息队列有什么优点和缺点?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景?
【Java问答学堂】3期 如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?
【Java问答学堂】4期 如何保证消息的可靠性传输?(如何处理消息丢失的问题?)
【Java问答学堂】6期 如何解决消息队列的延时以及过期失效问题?
【Java问答学堂】7期 如果让你写一个消息队列,该如何进行架构设计?
【Java问答学堂】8期 es 的分布式架构原理能说一下么(es 是如何实现分布式的啊)?
【Java问答学堂】9期 es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?
【Java问答学堂】10期 es 在数据量很大的情况下(数十亿级别)如何提高查询效率啊?
【Java问答学堂】11期 es 生产集群的部署架构是什么?每个索引的数据量大概有多少?
【Java问答学堂】12期 项目中缓存是如何使用的?为什么要用缓存?缓存使用不当会造成什么后果?
【Java问答学堂】13期 redis 和 memcached 有什么区别?
【Java问答学堂】14期 redis 都有哪些数据类型?分别在哪些场景下使用比较合适?
【Java问答学堂】15期redis 的过期策略都有哪些?内存淘汰机制都有哪些?
【Java问答学堂】16期如何保证 redis 的高并发和高可用?redis 的主从复制原理能介绍
Kafka、ActiveMQ、RabbitMQ、RocketMQ的区别?【Java问答学堂】19期
如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?【Java问答学堂】21期
如何保证消息的可靠性传输?或者说,如何处理消息丢失的问题?【Java问答学堂】22期
如何解决消息队列的延时以及过期失效问题?【Java问答学堂】24期
如果让你写一个消息队列,该如何进行架构设计?【Java问答学堂】25期
ES 的分布式架构原理能说一下么(ES 是如何实现分布式的啊)?【Java问答学堂】26期
ES 写入数据的工作原理是什么啊?ES 查询数据的工作原理是什么啊?【Java问答学堂】27期
ES 在数据量很大的情况下(数十亿级别)如何提高查询效率啊?【Java问答学堂】28期
ES 生产集群的部署架构是什么?每个索引的数据量大概有多少?【Java问答学堂】29期
项目中缓存是如何使用的?为什么要用缓存?缓存使用不当会造成什么后果?【Java问答学堂】30期
Redis 和 Memcached 的区别?Redis 的线程模型是什么?【Java问答学堂】31期
Redis 都有哪些数据类型?分别在哪些场景下使用比较合适?【Java问答学堂】32期
Redis 的过期策略都有哪些?内存淘汰机制都有哪些?手写一下 LRU 代码实现?【Java问答】33期
如何保证 redis 的高并发和高可用?【Java问答】34期
Redis 集群模式的工作原理能说一下么?【Java问答】36期
了解什么是 Redis 的雪崩、穿透和击穿?Redis 崩溃之后会怎么样?【Java问答】37期
Redis 的并发竞争问题是什么?如何解决这个问题?【Java问答】39期
生产环境中的 Redis 是怎么部署的?【Java问答】40期
为什么要分库分表(设计高并发系统的时候,数据库层面该如何设计)?【Java问答】41期
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。