分布式事务的实现原理详解
副标题[/!--empirenews.page--]
事务是数据库系统中非常有趣也非常重要的概念,它是数据库管理系统执行过程中的一个逻辑单元,它能够保证一个事务中的所有操作要么全部执行,要么全不执行;在 SOA 与微服务架构大行其道的今天,在分布式的多个服务中保证业务的一致性就需要我们实现分布式事务。 在这篇文章中,我们将介绍 事务的实现原理、分布式事务的理论基础以及实现原理。 事务 在文章的开头,我们已经说过事务是数据库管理系统执行过程中的一个逻辑单位,它能保证一组数据库操作要么全部执行,要么全不执行,我们能够通过事务将数据库从一个状态迁移到另一个状态,在每一个状态中,数据库中的数据都保持一致性。 database-and-transaction 数据库事务拥有四个特性,原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability): transaction-basics 我们经常将这上述的四大特性简写为 ACID,而数据库事务的实现原理其实也就是实现这四大特性的原理。 实现原理 在之前的文章 『浅入深出』MySQL 中事务的实现 中其实已经对如何实现事务的 ACID 这几个基本属性给出了比较详细的介绍和分析,在这里就简单介绍几个比较重要的实现细节,关于展开的内容,可以阅读上述文章。 事务日志 为了实现确保事务能在执行的任意过程中回滚(原子性)并且提交的事务会永久保存在数据库中,我们会使用事务日志来存储事务执行过程中的数据库的变动,每一条事务日志中都包含事务的 ID、当前被修改的元素、变动前以及变动后的值。 Transaction-Log 当我们有以上的事务日志之后,一旦需要对事务进行回滚就非常容易了,数据库会根据上述日志生成一个相反的操作恢复事务发生之前的状态;事务日志除了能够对事务进行回滚保证原子性之外,还能够实现持久性,当一个事务常食对数据库进行修改时,它其实会先生成一条日志并刷新到磁盘上,写日志的操作由于是追加的所以非常快,在这之后才会向数据库中写入或者更新对应的记录。 在 MySQL 最常见的存储引擎 InnoDB 中,事务日志其实有两种,一种是回滚日志(undo log),另一种是重做日志(redo log),其中前者保证事务的原子性,后者保证事务的持久性,两者可以统称为事务日志。 并发控制 数据库作为最关键的后端服务,很难想象只能串行执行每一个数据库操作带来的性能影响,然而在并发执行 SQL 的过程中就可能无法保证数据库对于隔离性的要求,归根结底这就是一致性、隔离性与性能之间的权衡。 tradeoff-and-concurrency 为了避免并发带来的一致性问题、满足数据库对于隔离性要求,数据库系统往往都会使用并发控制机制尽可能地充分利用机器的效率,最常见的几种并发控制机制就是锁、时间戳和 MVCC: concurrency-contro 作为悲观并发控制机制,锁使用在更新资源之前对资源进行锁定的方式保证多个数据库的会话同时修改某一行记录时不会出现脱离预期的行为,而时间戳这种方式在每次提交时对资源是否被改变进行检查。 分布式事务 从广义上来看,分布式事务其实也是事务,只是由于业务上的定义以及微服务架构设计的问题,所以需要在多个服务之间保证业务的事务性,也就是 ACID 四个特性;从单机的数据库事务变成分布式事务时,原有单机中相对可靠的方法调用以及进程间通信方式已经没有办法使用,同时由于网络通信经常是不稳定的,所以服务之间信息的传递会出现障碍。 tx-and-distributed-tx 模块(或服务)之间通信方式的改变是造成分布式事务复杂的最主要原因,在同一个事务之间的执行多段代码会因为网络的不稳定造成各种奇怪的问题,当我们通过网络请求其他服务的接口时,往往会得到三种结果:正确、失败和超时,无论是成功还是失败,我们都能得到唯一确定的结果,超时代表请求的发起者不能确定接受者是否成功处理了请求,这也是造成诸多问题的诱因。 communication-reliability-and-transaciton 系统之间的通信可靠性从单一系统中的可靠变成了微服务架构之间的不可靠,分布式事务其实就是在不可靠的通信下实现事务的特性。无论是事务还是分布式事务实现原子性都无法避免对持久存储的依赖,事务使用磁盘上的日志记录执行的过程以及上下文,这样无论是需要回滚还是补偿都可以通过日志追溯,而分布式事务也会依赖数据库、Zookeeper 或者 ETCD 等服务追踪事务的执行过程,总而言之,各种形式的日志是保证事务几大特性的重要手段。 2PC 与 3PC 两阶段提交是一种使分布式系统中所有节点在进行事务提交时保持一致性而设计的一种协议;在一个分布式系统中,所有的节点虽然都可以知道自己执行操作后的状态,但是无法知道其他节点执行操作的状态,在一个事务跨越多个系统时,就需要引入一个作为协调者的组件来统一掌控全部的节点并指示这些节点是否把操作结果进行真正的提交,想要在分布式系统中实现一致性的其他协议都是在两阶段提交的基础上做的改进。 two-phase-commit (编辑:好传媒网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |