订单缓存方案上线之后,我们以为又开启了岁月安好的日子,但是,在一周后的某一天,DBA直接跑来了,DBA直接说:“leader让我直接找你,是这样的,上次加了缓存优化后,效果确实不错,但是我发现订单查询sql在今天的12:00至12:05之间有大量的慢sql,查询时间超过了2.5s。”
创新互联是一家专注于成都网站建设、网站设计与策划设计,光明网站建设哪家好?创新互联做网站,专注于网站建设10多年,网设计领域的专业建站公司;建站业务涵盖:光明等地区。光明做网站价格咨询:18980820575
这个时候,我们立马开启了排查问题模式,首先,check了一下上次加的缓存,发现缓存正常,然后接着根据DBA提供的信息搜索日志,此时,发现在这个时间段订单请求量突增,大概是平常订单请求量的2到3倍,然后经过了解,发现在这个时间段内,营销系统那边做了一些活动,导致订单请求量突增。
说白了就是做了促销活动后,大量下单的用户会不断刷新订单来查询订单的信息,比如看一下订单是否开始配送,此时大量的请求会打到了MySQL上去,此时单库又抗不了这么读请求,就导致了数据库负载很高,从而严重降低了MySQL的查询效率。
现在我们缓存也加过了,但是数据库负载还是很高,此时该怎么办呢?
其实也很简单,既然单个库扛不住,那就搞2个库一起来抗呗,因为对于外卖订单来说是典型的读多写少的场景,所以,在这个场景下,我们可以搞个一主两从的架构来进行优化,就像这样:
也就是写数据走主库,而读数据走从库,可以看到,此时由于我们搞了2个从库,这2个从库可以一起来抗大量的读请求。
非常关键的一点就是,从库会通过主从复制,从主库中不断的同步数据,以此来保证从库的数据和主库是一模一样的,所以想要实现读写分离,那么,就先要了解主从复制是怎么玩儿的。
我们以mysql一主两从架构为例,也就是一个master节点下有两个slave节点,在这套架构下,写请求统一交给master节点处理,而读请求交给slave节点处理。
为了保证slave节点和master节点的数据一致性,master节点在写入数据之后,同时会把数据复制一份到自己的各个slave节点上。
在复制的过程中一共会使用到三个线程,一个是binlog dump线程,位于master节点上,另外两个线程分别是I/O线程和SQL线程,它们都分别位于slave节点上,如下图:
结合图片,我们一起来看下主从复制的核心流程:
(1)当master节点接收到一个写请求时,这个写请求可能是增删改操作,此时会把写请求的操作都记录到binlog日志中。
(2)master节点会把数据复制给slave节点,如图中的slave01节点和slave02节点,这个过程,首先得要每个slave节点连接到master节点上,当slave节点连接到master节点上时,master节点会为每一个slave节点分别创建一个binlog dump线程,用于向各个slave节点发送binlog日志。
(3)binlog dump线程会读取master节点上的binlog日志,然后将binlog日志发送给slave节点上的I/O线程。
(4)slave节点上的I/O线程接收到binlog日志后,会将binlog日志先写入到本地的relaylog中,relaylog中就保存了binlog日志。
(5)slave节点上的SQL线程,会来读取relaylog中的binlog日志,将其解析成具体的增删改操作,把这些在master节点上进行过的操作,重新在slave节点上也重做一遍,达到数据还原的效果,这样就可以保证master节点和slave节点的数据一致性了。
mysql的主从复制,分为全同步复制、异步复制、半同步复制和增强半同步复制 这四种。
首先,全同步复制,就是当主库执行完一个事务之后,要求所有的从库也都必须执行完该事务,才可以返回处理结果给客户端;因此,虽然全同步复制数据一致性得到保证了,但是主库完成一个事物需要等待所有从库也完成,性能就比较低了。
而异步复制,当主库提交事物后,会通知binlog dump线程发送binlog日志给从库,一旦binlog dump线程将binlog日志发送给从库之后,不需要等到从库也同步完成事务,主库就会将处理结果返回给客户端。
因为主库只管自己执行完事务,就可以将处理结果返回给客户端,而不用关心从库是否执行完事务,这就可能导致短暂的主从数据不一致的问题了,比如刚在主库插入的新数据,如果马上在从库查询,就可能查询不到。
而且,当主库提交事物后,如果宕机挂掉了,此时可能binlog还没来得及同步给从库,这时候如果为了恢复故障切换主从节点的话,就会出现数据丢失的问题,所以异步复制虽然性能高,但数据一致性上是较弱的。
mysql主从复制,默认采用的就是异步复制这种复制策略。
半同步复制,顾名思义就是在同步和异步中做了折中选择,我们可以结合着MySQL官网来看下是半同步主从复制的过程,来看下这样图:
当主库提交事务后,至少还需要一个从库返回接受到binlog日志,并成功写入到relaylog的消息,这个时候,主库才会将处理结果返回给客户端。
相比前2种复制方式,半同步复制较好地兼顾了数据一致性以及性能损耗的问题。
同时,半同步复制也存在以下几个问题:
当主库成功提交事物并处于等待从库确认的过程中,这个时候,从库都还没来得及返回处理结果给客户端,但因为主库存储引擎内部已经提交事务了,所以,其他客户端是可以到从主库中读到数据的。
但是,如果下一秒主库突然挂了,就像这样图一样:
此时,下一次请求过来,因为主库挂了,就只能把请求切换到从库中,因为从库还没从主库同步完数据,所以,从库中当然就读不到这条数据了,和上一秒读取数据的结果对比,就造成了幻读的现象了。
最后,增强半同步复制,是mysql 5.7.2后的版本对半同步复制做的一个改进,原理上几乎是一样的,主要是解决幻读的问题。
主库配置了参数rpl_semi_sync_master_wait_point = AFTER_SYNC 后,主库在存储引擎提交事物前,必须先收到从库数据同步完成的确认信息后,才能提交事务,以此来解决幻读问题。
可以参考下MySQL官网是怎么描述增强半同步主从复制过程的:
主库写入的速度是很快的,因为主库是多线程并发写入的,但是,从库是单线程从主库拉取数据的,所以从库从主库复制数据的速度,就比较慢了,从而产生了主从延迟的问题。
mysql 从 5.6版本开始,就支持多线程复制,但是5.6版本是基于库级别去操作,也就是说会给每个数据库开启一个线程,不同库处理时在同一时间内是互不影响的;但是,当业务的压力集中到一个库时,又会回到和单线程复制一样的状况了。
直到mysql 5.7版本,开始引入了基于组提交(group_commit)的概念,这个时候才 真正 支持多路复制功能,官方称为enhanced multi-threaded slave(简称MTS),所以,推荐大家尽可能选择MySQL 5.7之后的版本。
而主库挂载的从库数量过多,也会导致主从复制延迟的问题,一般我们是建议一个主库挂载从库的数量,在3~5个比较合适。
另外,我们执行的SQL语句中,如果慢SQL语句过多,也会导致主从复制延迟,比如,我们工作中会遇到批量插入的场景,如果一批插入的数据量过大,就容易造成执行时间过长。
假如,从执行完一份 批量插入数据的SQL语句开始,到在从库上能查到这些数据的这个过程中,如果耗费了10秒,就导致主从库之间就延迟10秒了;所以,SQL优化会是一个常态化的工作,可以通过慢SQL日志或监控平台监控慢SQL,如果单个数据写入时间过长的话,可以将一批数据分片分批次写入。
最后,如果出现网络延迟或者机器的性能比较差,也会导致主从复制延迟的问题,这种情况没什么可说的,及时优化网络提升机器性能就行了。
1)生成订单
2)查询订单
本文题目:你还不知道怎么做数据库读写分离么,用这个中间件让你性能提10倍
网站路径:http://www.shufengxianlan.com/qtweb/news30/72280.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联