mysql主从读写分离

场景

mysql主从复制的常见使用场景,当我们的读写流量过大的情况下,尤其是读流量过大的情况下,mysql主从读写分离就很有必要了。

我们使用主库写入,读取从库来分离读写流量,而这时候读流量不断增加,那我们只需要扩展从库就可以了。

主从复制的原理

数据库是怎么完成主从复制的呢,这里就要说到binlog了,这是存储数据库行为的二进制日志文件。从库会有一个io线程来读取这个binlog,读取之后写入一个叫做relay log的日志文件中,而主库也会创建一个log dump的线程来发送binlog给从库;同时,从库会创建一个sql线程将relay log中的内容写入从库。来实现主库数据到从库数据的一致性。

log dump线程是异步操作,也就是当你有数据写入主库的时候,不会等到数据同步到从库之后再返回写入成功,而是直接返回写入成功。

从库获取数据先写入relay log是因为直接写入从库可能很耗时,导致主从同步的延迟变长。

既然写入主库之后就返回成功,然后同步数据,那这时候就有可能发送主从数据不一致的问题,因为如果主库的数据还没有写入到binlog文件中的时候主库宕机了,那么就会导致binlog文件缺失,从而从库数据和主库数据不一致的问题,但是这种情况很少很少,而基于性能来考虑,这种情况还在我们可接受范围之内

主从读写分离的优缺点

主从读写分离固然可以让我们更好的应对大量的读写请求,但是读请求量非常大的情况下,并不是盲目的扩展从库就可以了,因为大量的从库会有大量的io线程来读取binlog,这样主库的压力就会变大。

还有主从数据库的同步肯定会有一些延迟,考虑以下情况,我之前的一个项目,用到了分红功能,后台审核之后会给用户发放分红,这是一个异步操作,我们会在审核之后把分红数据的id放到队列中,然后取出队列中的分红id到从库之中查询分红数据,那么这时候从库要是没有同步到数据,就会出现查到的数据状态不对或者数据不存在的问题。那么分红就进行不下去了。

怎么办呢,我们后来采用了直接将所有分红数据放到队列之中的方法,这样取出来就不用再次查询了,但是这样的弊端就是队列中的数据量会变大,但是这在我们的可接受范围之内。

除此之外还有其他的办法,比如将数据放到缓存之中,取出来id到缓存中查询,但是这样缓存也会很大。而且要保证缓存数据的一致性,那么像更新这种操作就会很危险,建议只有创建操作使用缓存。

还有一种方法是取出来查询的时候直接查询主库,但是这样主从读写分离就失去了意义。

总结一下三种方法:

  • 数据冗余到队列中,免去再次查询的步骤
  • 数据放到缓存中,直接查询缓存保证一致性
  • 直接查询主库,不查询从库

这里我们分析了主从读写分离的执行过程和优缺点,今天就到这里啦