经常我们会听到 MySQL 读写分离,MySQL 主从复制,那么读写分离和主从复制究竟是什么?它们的工作机制又是什么样的呢?接下来我就简单的说说。
MySQL 读写分离
读写分离:其实说起来很简单,就是设计一个主库,然后挂上多个从库。当我们的业务需要写数据时,就直接写到主库里面去,然后主库会自动把数据给同步到从库上去;当我们的请求过来读数据,我们就直接从从库里面读数据,这个就是读写分离。
读写分离的目的:做读写分离最大的目的就是为了减小数据库的读写压力,比如一台数据库同时有2000个读请求与100个写请求,那么这个数据库压力就很大了,可能读写都很慢,但是你改成了一个主库与四个从库,主库100个写请求,每个从库500个读请求,那么这些请求处理就相当快速了。
MySql 主从复制
说了读写分离,我们继续说主从复制的工作机制,当有一个写请求过来时:
1.主库执行写请求,同时主库将变更写到 binlog 日志中,同时主库有一个 IO 线程通知从库有变更。
2.从库接收到主库通知之后,从库有一个IO线程,将主库的binlog日志拷贝到自己本地,写入一个中继日志( relay log )中。
3.从库中有一个 SQL 线程会从中继日志读取 binlog 日志。
4.从库执行 binlog 日志中的内容,也就是在自己本地再次执行一遍 SQL ,这样就可以保证自己跟主库的数据是一样的。
这里有一个非常重要的点,就是从库同步主库数据的过程是串行化的,也就是说主库上并行的操作,在从库上会串行执行。所以这就是一个非常重要的点了,由于从库从主库拷贝日志以及串行执行 SQL 的特点,在高并发场景下,从库的数据一定会比主库慢一些,是有延时的。所以经常出现,刚写入主库的数据可能是读不到的,要过几十毫秒,甚至几百毫秒才能读取到。而且这里还有另外一个问题,就是如果主库突然宕机,然后恰好数据还没同步到从库,那么有些数据可能在从库上是没有的,有些数据可能就丢失了。
所以 mysql 为了解决上面的问题,实际上在主从复制中还有两个机制,一个是半同步复制,用来解决主库数据丢失问题;一个是并行复制,用来解决主从同步延时问题。
半同步复制( semi-sync 复制):指的就是主库写入 binlog 日志之后,就会强制主库立即将数据同步到从库,从库将日志写入自己本地的 relay log 之后,接着会返回一个 ack 给主库,主库接收到至少一个从库的 ack 之后才会认为写操作完成了。
并行复制:指的是从库开启多个线程,并行读取 relay log 中不同库的日志,然后并行重放不同库的日志(这是库级别的并行)
最后工作流程图如下: