读写分离
如何实现MySQL的读写分离
基于主从复制架构,简单来说,就是搞一个主库,挂多个从库,然后单单只写入主库,主库就会自动把数据给同步到从库。
MysQL主从复制的原理?
主库将变更写入binlog日志,然后从库连接到主库之后,从库有一个IO线程,将主库的binlog日志拷贝到本地,写一个relay中继日志中。接着从库中有一个SQL线程会从中继日志读取binlog,然后执行binlog日志中的内容,也就是在自己本地再执行一边SQL日志,这样就可以保证自己跟主库数据是一样的。
这里需要注意一点,就是从库同步主库数据的过程是串行化,也就是主库并行的操作,在从库也会串行执行。由于从库从主库拷贝日志以及串行执行 SQL 的特点,所以在高并发场景下,从库的数据一定会比主库慢一些,会有延时。可能会出现,刚写入主库的数据可能读取不到,需要过一下才能读取到。
这里还有一个问题,如果主库突然宕机,然后数据还没同步到从库,那么有些数据在从库上是没有,数据就丢失了
所以MySQL实际上在这一块有两个机制,一个是半同步复制,用来解决主库数据丢失问题;一个是并行复制,用来解决主从同步延时问题。
-
半同步复制 也叫
semi-sync
复制,指的就是主库写入binlog日志后,会强制将此时数据同步到从库,从库将日志写入到自己的本地relay log后,会返回一个ack给主库,主库接受到至少一个从库的ack之后才会认为写操作完成了。 -
并行复制 从库开启多个线程,并行读取relay log中不同库的日志,然后并行重放不同库的日志,这是库级别的并行。
MySQL主从同步的延时问题(重点)
比如:先插入一条数据,再把它查出来,然后更新这条数据。在生产环境高峰期,写并发达到了 2000/s,这个时候,主从复制延时大概是在小几十毫秒。线上会发现,每天总有那么一些数据,我们期望更新一些重要的数据状态,但在高峰期时候却没更新。
我们可以使用命令
show slave status
查看Seconds_Behind_Master
,可以看到从库复制主库落后了几ms。
一般来说,如果主从延迟比较严重,有以下的解决方案:
- 分库,将一个主库拆分多个主库,每个主库写并发就少一些
- 打开MySQL支持的并行复制,多个库并行复制。如果某个库的写入并发特别高,并行复制没什么用
- 重写代码,因为插入的数据立马查询可能查询不到
- 如果确实存在必须先插入然后立马查询,之后立马又要执行操作,那么对这个查询设置直连主库,不推荐,这样使得读写分离意义丧失。
Enjoy Reading This Article?
Here are some more articles you might like to read next: