“后端分布式”包括两类:“分布式存储”和“分布式计算”。结合实际工作中遇到的问题,以寻找答案的方式剖析技术。很多时候,我们不是在创造新技术,而是应用技术。为了更有效地利用技术,我们需要了解某些技术的原理和工作方法。从用户的角度分析问题的技术原理,以及开源技术产品和框架作为一类技术实现的参考。主要目的是解释原理,如果具体实施的技术细节没有什么特别之处,它应该尽可能短。
交易和复制
最近涉及数据分发相关项目,涉及MySQL数据库的数据分发。简而言之,有必要在异地数据中心实现多点可写性,并确保分布式数据达到最终一致性。以前,向MySQL分发数据只是读写分离。数据库本身的主从副本可用于编写主库并读取从库。现在您需要双重写入主库并在短暂延迟后达到最终一致性。乍一看这个问题更复杂,但最终它是数据的最终一致性。
回到最简单的情况,当只有一个MySQL数据库时,如何保证数据一致性?知道数据库知道这是由数据库的事务特性保证的。该交易包括四个主要特征:
原子性原子性
一致性一致性
隔离隔离
耐久力
交易的ACID的四个特征不是本文的重点,因此我们不会开始进行学术解释。如果您不理解,可以阅读以下参考文献[3]中的相关文章。在这里我只想问一个问题,单个数据库事务可以保证数据的一致性,那么当MySQL作为主从架构部署时,如何确保主从之间数据的一致性?
MySQL引入了一个名为binlog的新日志文件,以提供主从复制,其中包含一组导致数据更改的事件日志。请求库从库中发送binlog并通过日志事件将数据恢复到从库,因此库中的数据源是binlog。这样,MySQL主库只需要使binlog与本地数据保持一致,以保证主从数据一致(暂时忽略网络传输引起的主从不一致)。我们知道通过数据库事务特性来确保本地数据的一致性,以及如何实现数据库事务?我们来看下面的图片:后端分布式系列:分布式存储 - MySQL数据库事务和复制
MySQL本身不提供事务支持,而是打开存储引擎接口,该接口由特定的存储引擎实现。具体来说,支持MySQL事务的存储引擎是InnoDB。存储引擎实现事务的一般方式基于重做日志和撤消日志。简单来说,重做日志记录事务的修改数据,撤销日志记录事务之前的原始数据。因此,当执行事务时,实际过程简化如下:
首先记录undo/redo日志,确保将日志刷新到磁盘以进行持久存储。
更新数据记录,缓存操作和异步刷新。
提交事务并在重做日志中写入提交记录。
如果在MySQL执行期间故障中断,您可以通过重做日志重做事务或通过撤消日志回滚以确保数据一致性。这些都是由事务存储引擎完成的,但binlog不在事务存储引擎的范围内,而是由MySQL Server记录。然后,您必须确保binlog数据和重做日志之间的一致性,因此打开binlog后的实际事务执行更进一步,如下所示:
首先记录undo/redo日志,确保将日志刷新到磁盘以进行持久存储。
更新数据记录,缓存操作和异步刷新。
将事务日志保留为binlog。
提交事务并在重做日志中写入提交记录。