读写分离的实现是基于主从复制架构:一主多从,只写主库,主库会自动将数据同步到从库。
1 为什么要读写分离?
主库将变更写binlog日志,然后从库连接到主库后,从库有个I/O线程,将主库的binlog日志拷贝到本地,写入一个中继日志。
接着从库中有一个SQL线程会从中继日志读取binlog,然后执行binlog日志中的内容。即在本地再次执行一遍SQL,确保跟主库的数据相同。
2 MySQL主从复制原理
MySQL的每个增删改的会改变数据的操作,除了更新数据外,对这个增删改操作还会写入一个日志文件,记录这个操作的日志,即binlog。
mysql 5.7新版本的并行复制,多个SQL线程,每个线程从relay日志里读一个库的
日志,重放。
从库同步主库数据的过程是串行化的,即主库上并行的操作,在从库上会串行执行。
由于从库从主库拷贝日志以及串行执行SQL的特点,在高并发下就有延时,从库数据一定比主库慢,所以经常出现,刚写入主库的数据读不到,要过几十甚至几百ms才能读到。
从库串行化过程:
读取binlog日志
写relay日志、应用日志变更到自己本地数据
从库的IO线程,读取主库的binlog日志时,老版本是单线程;
5.6.x之后的新版本支持多线程读取
另外的问题,若主库突然宕机,恰好数据还没同步到从库,那么有些数据可能在从库上是没有的,可能就这么丢失了。
所以MySQL实际上在这有两个机制
3 半同步复制
semi-sync,解决主库数据丢失问题。
主库写入binlog日志后,会强制立即将数据同步到从库
从库将日志写入自己的relay log后,会返回ack给主库
主库接收到至少一个从库的ack后才会认为写操作完成
4 并行复制
解决主从同步延时问题。
从库开启多线程,并行读取relay log中不同库的日志,然后并行重放不同库的日志,这是库级别的并行。
5 MySQL主从同步适用场景
建议一般在读远远多于写,且读的时候一般对数据时效性要求没那么高的时候采用。所以我们可以考虑的就是,你可以用MySQL的并行复制,但问题是那是库级别的并行,所以有时候作用不是很大。
此时,通常来说,我们会对于那种写后立马就要保证可以查到的场景,采用强制读主库的方式,确保你肯定可以读到数据。其实用一些数据库中间件也是没问题的。
一般若主从延迟较为严重:
分库 : 将一个主库拆分,每个主库的写并发就降低了,主从延迟即可忽略不计
打开MySQL支持的并行复制,多个库并行复制,若某个库的写入并发特别高,写并发达到了2000/s,并行复制还是没意义。二八法则,很多时候比如说,就是少数的几个订单表,写入了2000/s,其他几十个表10/s
重构代码 : 重构代码,插入数据后,直接更新,不查询
若确实存在必须先插入,立马要求查询,然后立马就反过来执行一些操作,对这个查询设置直连主库(不推荐,这么搞导致读写分离的意义丧失)
作者: qq_33589510
链接: https://blog.csdn.net/qq_33589510/article/details/95791086
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
到此这篇关于“MySQL读写分离及主从同步延时解决方案”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持Go语言编程网!
相关文章: