MySQL主从复制及延迟优化

97 阅读5分钟

主从复制

binlog(binary log 即二进制日志文件) 主要记录了MySQL数据库中数据的所有变化(DDL和DML)。因此,我们根据主库的binlog 日志就能够将主库的数据同步到从库中。

步骤:

  1. 主库在事务提交时,会把数据变更记录在二进制文件binlog中。
  2. 从库读取主库的binlog文件,写入到从库的中级日志relay log
  3. 从库的读取relay log同步数据本地。

复制方式:

  1. 异步复制: 这是一种MySQL标准复制机制,具体运作流程为:在主数据库(Primary Database)上完成事务处理后,系统即时向客户端反馈确认,其间并不涉及对从数据库(Secondary Database)事务执行状态的考量。此模式下,若主数据库发生故障且数据尚未同步至从数据库,可能会导致数据不一致乃至丢失的现象。
  2. 全同步复制: 当主数据库完成一个事务处理后,它将进入等待状态,直至所有从属数据库确认完成数据同步操作,才会向客户端反馈操作完成。此策略显著增强了数据安全性,但可能对系统整体性能产生负面影响。
  3. 半同步复制: 一个折中的策略是,在主数据库完成事务处理后,等待其中一个从属数据库成功完成数据复制,随后才向客户端确认事务处理结果。这种方式旨在平衡数据一致性与系统响应时间的需求。

读写分离: 在分布式系统架构的设计实践中,采用读写分离策略是一种广泛认可的方法论,旨在增强系统的整体处理性能与效率。该策略核心在于将数据的读操作与写操作分置于不同的节点或服务上,以此来实现负载均衡并优化资源利用。

好处:

  1. 提高性能: 将读写操作分开可以显著提高数据库系统的整体性能。
  2. 提高可拓展性: 允许系统按需增加从数据库实例,以应对读请求量的增长,从而提高系统的可拓展性。
  3. 增加可用性和容错性: 在主从复制架构的场景下,一旦主数据库发生故障,系统能够通过从从数据库中选择并晋升一个新的主库来实现故障转移,这一机制有效缩减了系统的中断时间,确保了服务的连续性和可用性。
  4. 负载均衡: 通过在多个从属数据库间分散读取请求,可以实现负载均衡策略,从而防止任何单一数据库出现过载情况,进而提升整个系统的响应能力和稳定性。

延迟优化

在真实的业务场景中,一般都采取MySQL的主从模式来应对高并发场景,主节点处理写请求,从节点处理读请求,主从节点之间通过MySQL的Binlog日志实现同步

由于网络及性能等原因,主从同步会存在一定的延迟,在对数据一致性要求较高的场景中就会引发问题,比如当我们插入一条数据到主库中,但从库还没来得及同步就有读请求来请求这条数据,这时是无法读取到的。

比如我们创建任务的一个事务中,首先先插入一个主任务,然后再查询主任务生成一些子任务。这时从库没能及时同步主库中的主任务,导致查询不到主任务。那么如何来解决这个问题呢?

强制读主库

可以实现,但是违背主从模式的初衷,不建议使用。

缓存

是一种解决方案,但会给缓存带来一定的负担。

在业务代码层面避免

对于新录入的数据行,所有非自动递增主键字段的信息均事先确定。数据插入主数据库后,即可即时获取其对应的自增主键值,并将此值赋予相应的领域模型对象。在涉及相同事务的读取操作中,可直接利用此预加载的领域模型对象,无需额外进行数据库查询交互,从而提升了处理效率。

这是一种十分高效解决方案,大部分业务场景都能使用。

主从一致

有一些场景中采用了一些特殊的手段来确保主从一致。比如在极客时间的《MySQL 45讲》中,作者提到过一些方案(其实用的不多)。

  1. Sleep方案: 主库更新之后,读从库之前先sleep 1秒,然后再读从库。
  2. 判断主从无延迟方案: 每次读从库之前,先判断seconds_behind_master 是否已经等于0。如果还不等,就需要等到参数变为0才能够读从库。
  3. 等主库位点方案:在读从库之前,确保从库已经同步了特定的主库位点(主库数据变更的位置)。这样可以保证从库的数据都是最新的。
  4. 等GTID方案: 和位点原理一样,MySQL 5.7.6 版本开始,允许在执行完更新类事务后,把该事务的GTID返回给客户端,在业务层代码在读从库之前校验从库是否已经应用了该GTID标识的事务。

GTID (Global Transaction Identifier) 为每个事务提供了一个全局唯一的标识符,使得主从复制过程中的数据变更能够更加精确和容易追踪。