随着业务的持续发展以及数据量的增加,独立于数据库体系之外的分库分表中间件由于自身限制,无法满足部分业务场景,因此分布式数据库应运而生。
大规模并行处理(Massively Parallel Processing,MPP),是指在集群中的每个节点都有独立的存储、内存以及CPU资源并且采取Master-Slave架构。集群中Slave阶段负责存储具体的业务数据,并且数据是按照一定的业务规则(例如在建表的时候按照某业务ID的Hash值)分布到不同的节点中。集群节点之间通过网络进行连接,协同工作,完成具体的数据请求。在具体的应用请求中,Master节点主要存储权限、数据位置等元数据信息;Slave节点通过访问本地资源并处理相关请求后统一汇总到Master节点,再返回到客户端中。常见的Master-Slave架构如图3-6所示。
图3-6 常见的Master-Slave架构
MPP技术是一种无共享(Shared Nothing)的分布式架构,而基于MPP架构的数据库,例如Greenplum,则具有较高的性能、可用性以及扩展性等。在OLAP的场景中,基于MPP架构的分布式数据库可以支持例如数据仓库、BI系统等多种应用场景。
基于MPP架构构建的数据库,即分布式数据库。分布式数据库依旧属于关系型数据库范畴,不是NoSQL,所以它支持事务级ACID特性。由于分布式系统中涉及不同节点的通信,会产生网络的延迟或者异常等特殊情况,因此,分布式系统往往采用两阶段提交(Two-Phase Commit,2PC)、补偿事务、本地消息表、MQ 事务消息这4种方式保证事务特性。
两阶段提交主要分为两个阶段,即准备阶段和运行阶段,并通过引入一个协调者来发起整个过程。在准备阶段,协调者通过向参与者发送请求,确认参与者事务(这里指参与者本地的事务)是否执行成功,参与者返回执行结果。在这个过程中该分布式事务的参与者都将等待最后一个参与者返回的事务执行结果(注意是执行结果,此时本地事务未提交),当全部返回之后再进入下一个阶段。在执行阶段,如果参与者都执行成功,则协调者通知让参与者提交事务,否则每个参与者回滚事务。
大多数分布式数据库采用的就是2PC来保证分布式事务的一致性。
补偿事务即常说的TCC机制,它主要分为三个阶段,即Try(业务检查)阶段、Confirm(确认执行)阶段以及Cancel(业务取消)阶段。在Try阶段,主要进行相应的检查,以确保所需要的资源及相关业务系统的状态已经准备完成,一旦检查成功则进入Confirm阶段;Confirm阶段是具体的事务的提交;Cancel阶段则是最后的补偿阶段,用来处理在Try阶段出现异常情况导致整体执行失败而进行的操作,它采取与Try阶段相反的操作,保证事务顺利回滚。
在TCC机制中,假设Confirm以及Cancel阶段是不会出现错误的,如果出现异常则需要引入重试机制或者人工介入。
2PC与TCC的区别是,前者主要应用在数据库层,而TCC机制主要面向应用处理场景。这代表着TCC需要应用开发人员在应用测试实现相应的业务逻辑,很明显TCC对于应用的侵入性较强。
本地消息表其实是一种设计思想,它最初是由eBay提出的。这个机制主要分为三个部分,消息生产者、消息层、消息消费者。这三个部分保证分布式事务的一致性。
在一个分布式事务中,首先,消息生产者将业务数据以及该业务数据对应的消息状态写入消息层中,消息生产者需要保证这个消息一定会被写到消息层中;消息层负责存储对应的业务数据以及消息状态;然后消息消费者通过定时读取消息中的业务数据完成业务逻辑并更新消息状态。
消息层可以是消息中间件也可以是日志文件或者数据表。但是它的本质是将数据预先缓存之后再消费以达到事务的一致性。在后续的文章中我们可以看到类似的实现机制,即WAL(Write Ahead Log,预写式日志)。
MQ事务消息是本地消费表的一种具体实现形式,它通过引入支持事务的第三方消息队列中间件来保证事务的一致性。MQ事务消息主要分为三个部分,消息生产者、支持事务的消息集群、消息消费者。
消息生产者通过与消息集群进行2次通信(类似2PC)以确认消息生产者本地事务状态与消息发送到消息集群的状态是一致的;消息消费者通过读取消息集群的数据,也采用类似2PC的方式保证事务的一致性。
MQ事务消息取消了对于本地数据库事务的依赖,但是由于实现难度较大且主流的消息队列中间件并不支持事务,因此应用面较小。
无论是集中式数据库还是分布式数据库,它们都对存储的稳定性具有一定的要求,随着技术的发展,基于通用硬件构建的大数据存储技术应运而生。