MySQL 的主从架构

数据库主从概念、优点及用途

主从数据库中主是主库的意思,从是从库的意思。数据库主库对外提供读写操作,从库对外提供读操作。

MySQL 的主从架构_第1张图片

数据库为什么需要主从架构呢?

  • 高可用,实时灾备,用于故障切换。比如主库挂了,可以切从库
  • 读写分离,提供查询服务,减少主库压力,提升性能
  • 备份数据,避免影响业务

数据库主从复制原理

  1. 主数据库有个 binlog 二进制文件,记录了所有增删改的 SQL 语句(binlog 线程)
  2. 从数据库把主数据库的 binlog 文件的 SQL 语句复制到自己的中继日志 relay log 中(I/O 线程)
  3. 从数据库的 relay log 重做日志文件,再执行一次这些 SQL 语句(SQL 执行线程)

MySQL 的主从架构_第2张图片

上述主从复制过程分了五个步骤进行:

  1. 主库的更新 SQL(update、insert、delete)被写到 binlog
  2. 从库发起连接,连接到主库
  3. 此时主库创建一个 binlog dump thread,把 binlog 的内容发送到从库
  4. 从库启动之后,创建一个 I/O 线程,读取主库传过来的 binlog 内容并写入到 relay log
  5. 从库还会创建一个 SQL 线程,从 relay log 里面读取内容,从 ExecMasterLog_Pos 位置开始执行读取到的更新事件,将更新内容写入 slave 的 db 中

主主、主从、主备的区别?

  • 数据库主主:两台都是主数据库,同时对外提供读写操作。客户端可以访问任意一台。数据存在双向同步。

MySQL 的主从架构_第3张图片

  • 数据库主从:一台是主数据库,对外提供读写操作。一台是从数据库,对外提供读的操作。数据从主库同步到从库。

MySQL 的主从架构_第4张图片

  • 数据库主备:一台是主数据库,对外提供读写操作。一台是备库,只作为备份使用,不对外提供读写,一旦主机挂了它就取而代之。数据从主库同步到备库。

MySQL 的主从架构_第5张图片

从库和备库,就是 slave 库的功能不同,因此叫法才不一样。一般 slave 库都会对外提供读的功能,因此大家日常听得比较多就是主从。

MySQL 是怎么保证主从一致的?

我们学习数据库的主从复制原理后,了解到从库在拿到并执行主库的 binlog 日志后,就可以保持与主库数据一致了。

这是为什么呢?哪些情况下又会导致数据不一致呢?

长连接

主库和从库在同步数据的过程中为了防止中断导致数据丢失,主库与从库之间维持了一个长连接,主库内部有一个线程,专门服务于从库的这个长连接。

binlog 日志格式

binlog 日志有三种格式,分别是 statement、row 和 mixed。

如果是 statement 格式,binlog 里记录的是 SQL 的原文。如果主库和从库选的索引不一致,就有可能会导致数据不一致。

假设主库执行 SQL 语句(其中 a 和 create_time 都有索引)。

delete from t where a > '666' and create_time < '2022-03-01' limit 1;

我们知道,MySQL 选择 a 索引和选择 create_time 索引,最后 limit 1 出来的数据有可能是不一样的。

所以就会存在这种情况:在 statement 格式下,主库在执行这条 SQL 语句时,使用的是索引 a,而从库在执行这条 SQL 语句时,使用的是索引 create_time,最后主从数据就不一致了。

那么如何解决这个问题呢?

可以把 binlog 日志格式修改为 row。

row 格式下的 binlog 日志,记录的不是 SQL 原文,而是两个 event:Table_map 和 Delete_rows。

Table_map event 说明要操作的表;Delete_rows event 用于定义要删除的行为,记录删除的具体行数。row 格式的 binlog 记录的就是要删除的主键 id 信息,因此不会出现主从不一致的问题。

如果 SQL 语句要删除 10 万行的数据呢?

使用 row 格式就会很占空间,况且 10 万条数据都在 binlog 里面,写 binlog 的时候也很耗 I/O,但是 statement 格式的 binlog 又有可能会导致数据的不一致。

因此 MySQL 提供了一个折中的方案,mixed 格式的 binlog。所谓 mixed 格式其实就是 row 和 statement 格式的混合使用,当 MySQL 判断可能会出现数据不一致时,就使用 row 格式,否则就使用 statement 格式。

数据库主从延迟的原因以及解决方案

主从延迟是怎么定义的呢?与主从数据同步相关的时间点有三个:

  • 主库执行完一个事务,写入 binlog,我们把这个时刻记为 T1
  • 主库同步数据给从库,从库接收完这个 binlog 的时刻,记录为 T2
  • 从库执行完这个事务,这个时刻记录为T3

所谓主从延迟,其实就是指同一个事务,在从库执行完的时间和在主库执行完的时间的差值,即 T3 - T1。

哪些情况下会导致主从延迟呢?

  • 如果从库所在的机器比主库的机器性能差,就会导致主从延迟,这种情况比较好解决,只需让主从库选择一样规格的机器就好
  • 如果从库的压力大,也会导致主从延迟。比如因为主库是直接影响业务的,大家可能使用会比较克制,因此一般查询都直接打到从库上了,结果导致从库查询会消耗大量的 CPU,影响同步速度,最后导致主从延迟。这种情况,可以搞一主多从的架构,即多接几个从库分摊读的压力。另外,还可以把 binlog 接入到 Hadoop 这类系统,让它们提供查询的能力
  • 大事务也会导致主从延迟。如果一个事务执行就要 10 分钟,那么主库执行完后,给到从库执行,最后这个事务可能就会导致从库延迟 10 分钟。所以在日常开发中,我们特别强调不要一次性执行太多 SQL 语句,需要分批进行,其实也是为了避免大事务。另外,大表的 DDL 语句也会导致大事务
  • 网络延迟也会导致主从延迟,这种情况只能优化网络,比如将 20M 带宽升级到 100M 等
  • 如果从数据库过多也会导致主从延迟,因此要避免复制的从节点数量过多。从数据库一般以 3~5 个为宜
  • 低版本的 MySQL 只支持单线程复制,如果主库并发高,来不及传送到从库,就会导致延迟。可以换用更高版本的 MySQL ,使用多线程复制

数据库高可用方案

  • 双机主备高可用
  • 一主一从
  • 一主多从
  • MariaDB 同步多主机集群
  • 数据库中间件

双机主备高可用

MySQL 的主从架构_第6张图片

  • 架构描述:两台机器 A 和 B,A 为主库,负责读写,B 为备库,只备份数据。如果 A 库发生故障,B 库成为主库负责读写。故障修复后,A 成为备库,主库 B 同步数据到备库 A
  • 优点:一个机器故障了可以自动切换,操作比较简单
  • 缺点:只有一个库在工作,读写压力大,不能实现读写分离,并发也有一定限制

一主一从

MySQL 的主从架构_第7张图片

  • 架构描述:两台机器 A 和 B,A 为主库,负责读写,B 为从库,负责读数据。如果 A 库发生故障,B 库成为主库负责读写。故障修复后,A 成为从库,主库 B 同步数据到从库 A
  • 优点:从库支持读,分担了主库的压力,提升了并发度。一个机器故障了可以自动切换,操作比较简单
  • 缺点:一台从库,并发支持还是不够,并且一共只有两台机器,还是存在同时故障的几率,不够高可用

一主多从

MySQL 的主从架构_第8张图片

  • 架构描述:一台主库多台从库,A 为主库,负责读写,B、C、D 为从库,负责读数据。如果 A 库发生故障,B 库成为主库负责读写,C、D 负责读。故障修复后,A 也成为从库,主库 B 同步数据到从库 A
  • 优点:多个从库支持读,分担了主库的压力,明显提升了并发读
  • 缺点:只有一台主机写,因此并发写不高

MariaDB 同步多主机集群

MySQL 的主从架构_第9张图片

  • 架构描述:由代理层实现负载均衡,多个数据库可以同时进行读写操作。各个数据库之间可以通过 Galera Replication 方法进行数据同步,理论上每个库的数据是完全一致的
  • 优点:读写的并发度都得到明显提升,可以实现任意节点读写,可以自动剔除故障节点,具有较高的可靠性
  • 缺点:数据量不支持特别大。要避免大事务卡死。如果集群节点中有一个变慢,其他节点也会跟着变慢

数据库中间件

MySQL 的主从架构_第10张图片

  • 架构描述:Mycat 分片存储,每个分片配置一主多从的集群
  • 优点:解决高并发高数据量的高可用方案
  • 缺点:维护成本比较大

你可能感兴趣的:(MySQL,数据库)