在复杂应用开发中,ACID事务可以确保数据完整性,但是在支持现在的高并发场景的时候,却显得力不从心。目前的分布式数据库是如何支持这一特性的呢?
什么是ACID事务
事务有四个关键属性 - Atom原子性,Consistency一致性,Isolation隔离性和Durability耐久性 - 通常缩写为ACID。
原子性是指事务中的所有工作都被视为一个原子单位 - 要么全部是被执行的,要么都不执行。
一致性确保数据库始终处于一致的内部状态。例如,对于存在二级索引的表,主表和所有索引表在更新后应保持一致。
隔离是确定一个事务所做的更改如何/何时对另一个事务可见。从严格的角度来看,Serializable和Snapshot Isolation是最严密的两个隔离级别。
耐久性是确保交易结果永久存储在系统中。即使在断电或系统故障的情况下,修改结果也必须能够保存。
分布式场景下ACID事务的三个主要类型
(一)单行ACID(Single-Row ACID)
所有操作仅影响数据库一个记录行(single row)的事务称为单行ACID事务。由于单行数据通常只限定在分布式数据库中单个节点的边界内,因此在分布式数据库领域中更容易实现单行ACID事务。但是,大多数NoSQL DB都不支持这种事务,因为它们的最终一致性存储引擎对数据读取的正确性没有保证。
(二)单片ACID(Single-Shard ACID)
单行ACID只限定在单个服务器节点内,对其改进的方式是单片ACID,其中涉及需要事务操作的所有数据记录行都位于分布式数据库的单个分片中。由于单个分片总是位于单个服务器节点内部,因此这种风格也不涉及跨多个节点协调事务操作,因此更容易在分布式数据库中实现。例如,MongoDB最近宣布他们希望在将来版本中支持单片交易。
(三)分布式ACID
一些流行的自动分片分布式数据库,通过设计创建集群,数据会分散在集群的多个节点上。这种跨多个节点实现多片和多行数据记录的事务称为分布式ACID事务 。在可以横向扩展的DB中实现分布式ACID事务需要使用事务管理器,该事务管理器可以协调各种操作,然后根据需要提交/回滚事务(两段事务)。
现状和一些思考
对于关系型数据库来说,ACID是基本特性。但是对于目前流行的分布式的非关系数据库来说,目前采取的策略是要么完全抛弃ACID事务,要么只支持有严格限制性的单行风格(single-row flavor)。Nosql数据库通常以牺牲这种ACID属性换得性能的提升,这些提升主要体现在更低延迟和更高吞吐量。
在笔者之前经历的项目中,一般多用伪分布式ACID来实现对数据强一致性的需求。即不依赖某一特定分布式数据库本身的自动分片特性,改由自己开发的数据分片中间件,通过将大数据化小的手段,来保证单片上的数据强一致性。这种方式在现阶段不但更容易实现,且对底层的分布式数据库选型有一定的宽容度,对后端的异构数据库也有很好的容忍性。
本文仅代表个人观点,不足之处敬请谅解,欢迎与笔者交流。您也可以关注下方微信公众号,及时获得更新通知。
欢迎关注《架构之禅》微信公众号
领取专属 10元无门槛券
私享最新 技术干货