MySQL 读写分离

记录下读写分离的使用方式与常见问题。

读写分离

读写分离是通过分离数据库的读写操作,通过横向扩展的能力来提高读性能

如图所示,Master称为主库,仅处理数据库的写操作Slaver称为从库,仅处理数据库的读操作

读写分离的实现可划分为两类:基于客户端实现基于中间件实现

与分库分表的实现思路相似。

两种实现的原理都在于请求的动态路由,根据请求的分类"读、写或事务"来动态的路由到指定的数据库实例。

基于客户端实现

基于客户端实现是通过嵌入业务层来实现请求路由的功能,

优点是性能好

缺点是升级困难问题排查难客户端复杂

由于路由功能完全内嵌在业务应用,日志也会分散在不同的业务应用,因此,问题的上报与排查都需要业务方深入合作。

基于中间件实现

基于中间件实现是通过中间件拦截请求转发(动态路由)到指定的数据库实例,

与基于客户端实现相反,

优点是升级方便问题排查容易客户端无感知

缺点是性能损耗大业务方可能存在读异常引入新的单点问题

路由功能的实现与业务应用无关,中间件可以做到无感知的升级,而且由于路由日志集中在中间件,排查问题更加容易。

MySQL主从同步

MySQL主从同步是利用同步binlog日志同步以及操作重放实现的数据同步。

binlog:MySQL数据库的二进制日志,用于记录用户对数据库变更操作的SQL语句

步骤

① 当Slaver连接到Master时,Master会为Slaver开启binlog dump线程

binlog dump线程用于读取binlog信息同步到Slaver

② Slaver会创建I/O 线程以及来处理binlog dump线程的数据,写入relay log

relay log是为了避免同步数据过程中的异常,导致数据的丢失,在半同步复制中有介绍。

③ Slaver还会创建SQL 线程用来解析relay log重放操作写入数据,完成数据同步。

同步过程中,SQL解析执行一定是单线程的,否则,会造成执行顺序错乱影响数据一致性。


主从同步是通过异步线程同步数据,属于最终一致性的实现方案,因此,必然存在主从不一致的问题。

异步模式

异步模式是最基础的同步方式,必然存在延迟。

为了解决异步模式的延时问题,MySQL提出了下面几种方法来解决这个问题。

半同步模式(semi-sync)

半同步模式是通过强制写入relay log来保证至少有一台从库完成了数据同步

仅保证写入relay log的延迟,无法保证写入数据的延迟,因此,半同步模式不能彻底解决问题。

对于一主一从的读写分离的情况下,此方法可以使同步延迟的问题忽略不记。

但在一主多从的读写分离的情况下,此方法就不一定会生效了,可能存在某个从库没有即使同步数据。

全同步模式

全同步模式是在半同步的基础之上保证全部从库同步数据。

这里的保证是relay log的写入还是数据的写入?

仍然是relay log(I/O线程与SQL线程不应该再次通信),只要日志flush到磁盘就不会出现数据丢失的情况。

并行模式

并行模式是通过增加SQL线程来实现并行读取relay log实现库级别的并行

主从延迟解决方案

背景

并发写入数据可能造成主从延迟增大。

解决

① 增加数据缓存,更新数据的同时写入缓存(读全部从缓存取数据)。

② 开启半同步、同步复制,降低时延问题,但会影响写入性能。

③ 强制路由到主库

④ 优化业务逻辑,对于异步操作通过使用延迟队列重试的机制来解决延迟问题。