引言
对于支持 OLTP 的数据库系统来说,事务都是必不可少的一个核心特性。在数据库系统从单机架构向分布式架构演进的过程中,系统复杂性大幅提升,对事务的支持面临极大的挑战。
分布式系统通常采用数量更多,价格更便宜的硬件,用户可以在有效控制成本的情况下,更从容地应对业务的高速增长。但是一分钱一分贷,价格低了,在稳定性和可靠性上就没那么靠谱了。在大规模的集群里,主机设备故障、硬盘罢工等问题,基本都是家常便饭。甚至也有一些外部因素会对系统产生影响,比如被人挖断光缆,导致服务大面积瘫痪的事,也实实在在地发生过。
因此,相对复杂的组网模式,也就成为分布式系统面临的一大难点:存在更多的风险可能性。这些需要从软件的架构及实现层面进行弥补,任何对环境存在过度假设的方案,都是无意义的。与此同时,除了应对各种可能的异常,数据库系统还要确保在分布式环境下,提供完整的事务能力、完备的ACID 特性,以及满足实际业务需要的高性能,这些都是需要软件提供商们直面的挑战。
作为新一代分布式关系型数据库,SequoiaDB 对这些问题进行了深入的研究并最终产品化,在客户的线上业务系统中取得了良好的应用效果。本系列文章,将对其分布式事务的基本实现机制及关键技术点进行介绍,着重介绍其中的高性能设计、完备的强一致性保证等内容。
概述
一个完整的事务流程,通常包括事务的开启、事务操作的执行,以及事务的结束(提交或回滚)。由于 SequoiaDB 的分布式特性,其事务通常需要集群中的多个节点(协调节点、一个或多个数据节点)通过网络消息进行交互与协同。协调节点作为数据库集群与业务进行交互的入口,同时也承担着全局的事务管理器的功能,它在接收到客户端请求时,选择目标数据节点,进行事务消息的下发,收集各节点的事务状态,并控制全局的事务提交或回滚。
正如前面讲到的问题,任何一个节点都有可能在关键时刻掉链子。为了应对各种节点异常的情况,数据节点除了在协调节点的统一指挥下进行步调一致的操作之外,也需要具备一定的自治能力。在协调节点失效或者自身异常的情况下,能够主动和其它节点进行确认,并处理自己的未决事务,以在全局范围内确保数据一致。
下面我们将按照一个事务的基本流程,对 SequoiaDB 中的分布式事务进行介绍。
开启事务

对于软件系统,网络交互是一个开销比较大的操作,而对于存在多节点间网络交互的分布式系统来说,其对性能的影响就更加明显,甚至直接成为整个系统的性能瓶颈。因此,设计一套简洁、高效的消息框架,对保障系统的高性能,具有至关重要的意义。在这一点上,SequoiaDB 实现了消息打包、批量发送及处理的能力,最大限度地减少了消息交互,从而有效地节省了网络带宽,减小了处理时延。
比如,在开启事务阶段,数据节点不需要进行特定操作,因此协调节点完成自己的操作之后,立即返回成功。当客户端执行下一个事务操作时,协调节点就会将事务开始的消息和数据操作的消息打包到一起,发送给数据节点处理。
数据节点在开启事务时会进行必要的检查,如节点是否为主节点,当前会话上的事务是否处于不一致状态。如果检查通过,则会将协调节点下发的事务 ID 设置到会话中。完成事务开启后,就会进行后续的事务操作。
事务操作
在事务开启后即可在事务内进行数据操作,如在一个或多个表上进行 CRUD 操作。该事务内对数据的变更,在其它事务中是否可见,以及对锁的竞争行为,取决于隔离级别的配置。
如前文所述,如果是第一次向一个数据节点发送事务操作请求,那么会对开启事务和数据操作消息打包发送。在数据节点上,接收到该消息包后,会依次解析并处理其中的消息。如果数据节点之前已经接收过协调节点发送过来的该事务的消息,则新消息中只会包含新事务操作的消息。

结束事务(提交或回滚)
在完成所有事务中的操作后,需要决定事务是提交还是回滚。结束事务是两阶段提交协议应用的阶段。两个阶段是指:
准备阶段(Pre-Commit):在这一阶段,协调节点询问所有参与的数据节点是否准备好提交;参与的数据节点如果已经准备好提交则回复可以进行提交,并进入等待提交状态(Wait-Commit),否则回复不可以进行提交。

提交阶段(Commit):协调节点如果在上一阶段收到所有参与的数据节点回复都可以进行提交,则在此阶段向所有参与的数据节点发送提交指令,所有参与的数据节点立即执行提交操作;否则协调者向所有参与的数据节点发送回滚指令,参与的数据节点立即执行回滚操作。

PRE_COMMIT
COMMIT
写一条事务提交的事务日志
将会话线程中的事务状态切换为 COMMIT
删除该事务的事务控制块
释放该事务持有的所有锁
释放该事务所占有的事务日志空间
提交性能优化
在基本的两阶段提交协议基础之上,SequoiaDB 针对某些场景进行了进一步的高性能设计。如果事务中操作的数据存在于同一个数据组上,此时就不需要进行多个分区组中事务的确认,可以将两阶段提交简化为一阶段直接进行提交。这样能够有效减少网络通信及协调确认流程,大大提高性能。
小结
往期技术干货巨杉Tech | 分布式数据库Sysbench测试最佳实践
巨杉Tech | 基于Kafka+Spark+SequoiaDB实时处理架构快速实战
巨杉Tech | SparkSQL+SequoiaDB 性能调优策略
巨杉Tech | 使用 etlAlchemy 工具迁移数据实战
巨杉Tech | SequoiaDB 巨杉数据库高可用容灾测试
巨杉Tech | 使用 SequoiaDB + Docker + Nodejs 搭建 Web 服务器
巨杉学习笔记 | SequoiaDB MySQL导入导出工具使用实战







