一、MySQL为什么要读写分离
达到mysql的请求时2000/s,数据库就开始报警了,磁盘IO开始变慢,CPU负载过高,内存使用过高。当达到4000/s,5000/s直接把MySQL打死啦。
读写分离:扩展读的能力,一般挂4-5个从库。
二、怎样实现读写分离
MySQL原生就支持主从复制,主库——>从库。
mysql主从复制的原理:
说一些经验数据:产生所谓的主从延迟,主要看主库的写并发,主库的写并发达到1000/s。从库的延迟会有几ms。如果主库的写并发达到2000/s,从库的延迟会有几十ms。如果主库的写并发达到4000、6000、8000。主库都快死了。此时,从库的延迟会达到几秒。也就是说主库的写并发越高,从库的延迟就越大。
而且这里还有1个问题,如果主库突然宕机,恰好数据还没同步到从库。那么,有些数据可能在从库上是没有的,有些数据可能就丢失啦。所以mysql在这一块有两个机制。一个是半同步复制,用来解决主库数据丢失问题。一个是并行复制,用来解决主从同步延时问题。
① 半同步复制:semi-sync复制,指的就是主库写入binlog日志后,此时就会强制立即将数据同步到从库。从库将日志写入自己本地的relay log,然后返回1个ack给主库。主库接收到至少1个从库ack之后,才会认为写操作完成啦。
② 并行复制:指的是从库开启多个线程,并行读取relay log中不同库的日志,然后并行重复不同库的日志,这是库级别的并行。
三、解决主从延迟问题方案
1、MySQL主从延迟导致的线上问题
插入1条数据,查出来这条数据,更新这条数据。因为高峰期叨叨了2000/s的写并发,主从延时大概几十ms。导致读到了这个空,然后更新的时候,不能对着空数据更新。更新语句如下:update xx set xx where id=1。如果为空则为update xx set xx where id=null。
线上,会发现,每天总会有那么一些数据,高峰期的时候,频繁。我们期望是刷新一些重要的状态。结果状态没更新。
一般来说,主从复制延迟较为严重。如何解决主从延迟带来的问题。
1、分库,将一个主库拆分为4个主库,每个主库的写并发就500/s。此时,主从延迟可以忽略不计。
2、打开mysql支持的并行复制,多个库并行复制,如果说主库的写入并发就是特别高,单库的写并发达到了2000/s。并行复制还是没有意义。2/8法则,比如说少数的几个订单表,写入了2000/s。其他几十个表10/s。
3、重写代码:刚刚举得那个例子,插入之后直接更新,不要查询。
4、如果的确存在先插入,立马就要查询到,然后立马就要反过来执行一些操作。对这个查询设置直连主库。但是不推荐这种方式,这样搞就丢失了读写分离的意义啦。