DTCC 2019 | 深度解码阿里数据库实现 数据库内核——基于HLC的分布式事务实现深度剖析

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 摘要:分布式事务是分布式数据库最难攻克的技术之一,分布式事务为分布式数据库提供一致性数据访问的支持,保证全局读写原子性和隔离性,提供一体化分布式数据库的用户体验。本文主要分享分布式数据库中的时钟解决方案及分布式事务管理技术方案。

摘要:

分布式事务是分布式数据库最难攻克的技术之一,分布式事务为分布式数据库提供一致性数据访问的支持,保证全局读写原子性和隔离性,提供一体化分布式数据库的用户体验。本文主要分享分布式数据库中的时钟解决方案及分布式事务管理技术方案。混合逻辑时钟(HLC)可以实现本地获取,避免了中心时钟的性能瓶颈和单点故障,同时维护了跨实例的事务或事件的因果(happen before)关系。

演讲嘉宾简介:

何登成(花名:圭多),阿里云智能数据库产品事业部资深技术专家,DTCC的老朋友。从2005年开始一直坚守在数据库内核研发领域,先后在神州通用、网易和阿里从事数据库内核产品研发工作,目前带领团队打造阿里新一代分布式数据库POLARDB-X。

1_e_1560244716_token_C8FPxG2IPHtDmtLKn5YCeZdF7OAlefKwHu_rPykj_C7WC_pIYtZvEJLNIk_rmWqFTi8_jpeg

直播回放

链接https://yq.aliyun.com/live/1045

议题PPT下载,戳这里!

https://yq.aliyun.com/download/3566

本次的分享主要围绕以下两个方面:

一、时钟方案
二、分布式事务管理

一、时钟方案

1.数据库为什么需要时钟

数据库归根结底是为了将每一个事务进行排序。在单机上情况下,事务排序可以非常简单的实现,但是在分布式下如何进行事务排序?数据库通过事务对外提供数据相关操作的ACID。数据库对事务顺序的标识决定了事务的原子性和隔离性。原子性指一个事务是完整的,既发生或不发生,代表每个事务都是独立的。隔离性指事务之间是相互隔离的。时钟有各种方式来标识一个事务的顺序,如Oracle每一个日志都有日志序列号LSN,事务ID,以及时间戳。目前许多商业和开源数据库产品都支持MVCC,MVCC通过支持数据的多版本,允许读写相同数据,实现并发,在读多写少的场景下极大的提升了性能。多版本出现之后,其本身就隐含了事务的顺序。当一个事务开始之后,需要确定哪个版本的数据是可见的和不可见的,所以这就涉及到了多体系,多版本和版本回收等问题。一个很经典的场景,淘宝或天猫的购物场景,有一条商品记录,用户每买一个商品,就是对商品数量记录做一次扣减。商品记录版本会变的一个非常长,把所有的版本都保存起来是不合理的,否则整个存储容量就不断增加。那如何进行版本回收?在回收的时候也需要有顺序,确定应该回收哪些版本?

2.分布式数据库下的时钟

分布式数据库下的时钟和单机数据库下的时钟有什么区别?首先,单机数据库的排序非常简单,通过日志序列号或事务ID就可以表示事务的顺序。在分布式数据库下,因为数据库运行在多台服务器上,每个数据库实例有独立的时钟或日志(LSN),每一个本地的时钟不能反映全局的顺序。服务器之间会有时钟偏移,最理想情况是一个分布式数据库部署100个节点,100个节点的时钟是完全同步的。但实际情况下,在机房做越轨需要做时钟校对,因为服务器和服务器之间时钟点有快慢之差,所以分布式数据库下的时钟无法做全局设置的反映。

3.时钟解决方案

时钟解决方案有很多,如使用统一的中心节点,或者使用独立的服务器产生分布式时钟。还有一种解决方案是逻辑时间,Lamport时钟是逻辑时钟。逻辑时钟指的是没有任何一个中心节点来产生时间,每一个节点都有自己本地的逻辑时间。比如有十个Oracle数据库,每个节点有自己的LSN,如果节点的事务比较多,事务ID跑的就比较快。如果节点事务比较少,事务ID就跑得比较慢。下图展示了目前主流的几种时钟解决方案,其中TIDB是国人的骄傲,TIDB使用的是中心时钟。除此之外,Postgres-XL使用了GTM,也属于中心时钟。Oracle使用的是逻辑时钟SCN。Cockraoch DB 是模仿Spanner做的分布式数据库,使用的是混合逻辑时钟。还有最知名的Google Cloud Spanner,Spanner对硬件依赖比较高,使用的是Truetime。Truetime本质上是一个原子钟,通过原子钟授时确保两个服务器之间时钟偏移在很小的范围之内。

4.逻辑时钟

逻辑时钟在分布式环境下如何实现?如下图,有A、B和C,3个节点,每个节点会有自己的逻辑时间,逻辑时间可以简单的理解为单调递增的自然数,0、1、2、3...。事务开始后加1,新事务开再加1。整个分布式环境下,三个节点完全独立,相互之间没有关系。如果事务跨多个节点,涉及到多个节点交互,产生一个事务的时候,本地时钟要加1。发message出去的时候,要把message的主体发出去,还要将本地的时间发给另一个节点。收到一个message节点后要处理这条消息,从收到的消息里面将对时间和本地的逻辑时间做一个取值,取最大的值设为本地时间。如果A节点发布较快,第一个事务完成以后,要做第二个事务,这时与B节点有交流,A加1,然后将时钟带到B节点,B节点直接从0跳到2。如此就在两个时钟之间建立了联系,通过建立联系,将两个节点之间的逻辑时钟拉平,这时候就构建它们之间的happen before的关系,代表A节点的事务是在B节点的新事务开始之前完成的。分布式数据库中,如果两个事务没有操作同样的节点,则两个事务是无关的事务。无关的事务可以认为是没有先后顺序的。但是当一个事务横跨多个节点的时候,将多个节点之间的关系建立起来,就变成有关系的事务,构建的是事务间的因果序。所谓因果序,如果同样来了两个事务,一个事务操作AB节点,另外一个事务操作BC节点,因为它们在B节点上建立了一个联系。通过B节点的关系,将事务的顺序维护起来。

纯逻辑时钟可以起到因果一致性和因果序的能力。那逻辑时钟最大的问题是什么呢?最极端的情况下,节点和节点之间永远不产生联系,两个节点之间的逻辑时钟的差距会越来越大。这时如果两个节点之间做查询或者备份,需要强制将它们建立关系,那么两节点之间的gap会变得非常大。

  1. 混合时钟

虽然机器和机器之间物理时钟有偏移,但如果有NTP校准或者Google的Truetime这种时钟服务器话,其物理时钟的差距是非常小的。混合时钟把分布式下的时钟切成两部分,上半部分用物理时钟来填充,下半部分用逻辑时钟来填充。填充在一起变成了一个HLC时钟,既混合逻辑时钟。它既有物理时钟的部分,又有逻辑时钟的部分。由于物理时钟服务器之间的差距不会特别大,所以可以比较物理时钟大小。而物理时钟又有一定的偏差,在一定的偏差范围内,可以使用逻辑时钟做校准。下图是混合逻辑时钟的一个示例。当发送一个消息的时候,首先应该把逻辑时钟的物理时钟部分与当前的时钟做一个比较。如果当前的物理时钟是4点,新事务产生后,因为物理时钟没变,新事务加在逻辑时钟的部分(加1)。如果物理时钟从4点变成4:01,则将物理时钟推进。物理时钟如果不推进,就加逻辑时钟。如果物理时钟发生了变化就把物理时钟往上推进,将逻辑时钟部分置零。

  1. HLC和中心时钟的差别

基于中心时钟的方案的时间是通过事务ID来判断的,从而为所以事物排序。分布式数据库中,需要消除中心节点。一种方法是纯逻辑时钟,但逻辑时钟之间无法比较大小。另一种方法是混合逻辑时钟(HLC),它为数据库定义了一类因果关系的事务。混合逻辑时钟没有中心节点,用本地的物理时间加上逻辑时间。本地产生的事务不保序,但是如果事务跨了节点,其因果联系是有顺序的。如下图T1,T2和T3代表提交时间,T1是一个分布式事务,T2是一个单机事务,T3是一个分布式事务。因为T1 是一个分布式事务,在数据库节点上进1是比进2先执行,所以在整个时钟里面,进1小于进2,进1也小于进3。通过这种方式,将有关系的事务的顺序排好。

7.中心式 VS. 分布式 VS. Truetime

如下图,中心式时钟的优点一目了然,它可以保证全局一致的时间。分布式数据库下的时钟的优点是无中心化的性能和无HA瓶颈,因为不需要中心的授时服务。分布式数据库下的时钟主要有两个能力,第一个能力是可以做到计算和存储的水平扩展。另外,因为分布式数据库把一个业务的workload拆分到了不同的机器上,从而单点故障带来的影响减小了。把核心数据库拆成了几百份,任何一个单点数据库故障带来的整个系统可用性的下跌是非常小的。这说明了为什么现在的分布式和互联网+结合在一起比较火,一个很重要的原因是分布式降低了单点故障对业务带来的的可用性的影响。不仅仅是互联网公司,包括金融类的银行也想往分布式走,一个方面是为了解决容量和扩展性的问题,另外一方面也是为了解决高可用问题。中心式的缺点是会有单点的single point of failure。分布式时钟虽然消除了单点的影响,但是时钟是不可以排序的,无法实现真正的外围一致性。外围一致性指的是每两个事务都可以排序。而分布式时钟只能对有关联的事务进行排序,实现因果顺序。Google的Truetime的优点是保证全局一致时间,简化应用开发。缺点首先是需要专有的硬件,如果Truetime的原子钟授时的话,也会有一定的时钟偏差,这个时钟偏差物理上无法克服。Google Spanner的paper中可以发现每一个事务的提交都要等待一段时间,就是要等这段时钟偏差。

二、分布式事务管理

1.两阶段提交

分布式事务管理是为了保证全局读写原子性和隔离性。一个事务要跨两个节点,这时候存在失败的可能性。假如一个节点成功一个节点失败,那么看到的结果就是不一致的,这丧失了事务的原子性。还有一种是两个节点上都提交成功,但是因为两个节点本身的时间不一样,导致提交的时间也不一样。如果用MVCC去读这个事务,能看到一半,另一半可能看不到,这样就无法保证事务的原子性。对于事务的原子性问题,目前相关技术已经非常成熟,既两阶段提交。如果要保证一个分布式事务成功或者失败,可以利用两个阶段提交技术,先做一个prepare事务,如果所有的prepare都可以,再做commit。

2.其它分布式事务管理技术

常见的分布式事务管理技术分为三类。第一类是两个阶段提交技术,包含prepare阶段和commit阶段。第二类基于MVOCC,其中FOUNDATION DB是苹果开源的分布式数据库,使用的是MVOCC,可以理解为OCC(optimistic concurrency control)。OCC指在事务提交时检查是否有冲突,基于冲突有设置冲突检测算法和权重算法,最后选择毁掉或者提交哪个事务。对于锁,在事前和在更新的时候加锁,提交的时候检查冲突。在冲突不剧烈的情况下,因为没有加锁开销,整个吞吐非常高。在冲突剧烈的情况下,大量的abort事务会反复回滚。第三类技术主要针对确定性事务,如FAUNA技术。

美国的一位教授提出了确定性事务,并基于确定性事务模型创办了一家公司,创建了一个分布式数据库(FAUNA)。确定性事务指事务是完整的,而不是交互型的。比如,在淘宝这种互联网企业处理的都是非确定性事务。非确定性事务只begin事务,select事务等,每个操作都是交互的,既APP需要跟DateBase做交互。如果站在数据库的视角,数据库永远无法预测下一条语句,这类事物是非确定性的。确定性事务是把一个事务所有的逻辑一次性写好,然后发送给DateBase。DateBase收到事务的时候,清楚这个事务需要操作哪些表,读取哪些记录并进行哪些操作。从数据库的视角来说事务是完全确定的。拿到一个确定性事务,可以事先将这些事务排好序。两个事务之间如果操作相同的记录,就排个先后,如果不操作相同的记录,就并发的发出去。使用这种方式可以做到既不用加锁,也不用在事后提交的时候做冲突检测。但是它的要求是事务不能是交互型的。

3.HLC和两阶段提交

混合逻辑时钟(HLC)格式如下。如果有64个字节,首先预留5字节保证兼容性,在做系统设计的话,通常需要预留一些字节或以防出现一些问题时没东西可用。中间再留43字节做物理时钟。后面的16字节做逻辑时钟。如果时钟精确到毫秒级,43字节的物理时钟意味着279年,表示数据库不断运行,279年不挂,一般来说这不太可能。如果物理时钟到天级,一天才能变一位,那物理时钟就失去了意义。16字节是65536,65536意味着一毫秒内可以发起65536个事务,。一般开始和结束的时候都要消耗两个时钟,除以二,既一毫秒内可处理3万多的事务,单节点一秒内可以做到3千多万事务。

4.HLC时钟偏移的问题

HLC和事务的吞吐有关系,因为它有物理时钟,能够展示不同的节点之间的时钟差。如果真的出现了时钟偏移怎么办?下图提供了一个简单的公式。没有偏差的情况下,理论上节点可以做到3千万的TPS,当然在工程上是做不到的。如果两个节点时钟之间偏移量是5毫秒,那么在5毫秒之内只能通过逻辑时钟去弥补。如果原来6万个逻辑时钟在1毫秒内就能做完,现在则需要5毫秒,导致整个事务的吞吐下降了600万。所以时钟偏移会导致peakTPS大幅下降。下图给出了几种解决方案。比较简单的是允许设置最大时钟偏移,如果整个机房或者集群中两个节点之间最大偏移超过了100毫秒,就把该异常节点清除。目前来看,机房都有NTP授时服务,所以发生如此大时钟偏移的概率非常小。另一种方式是不清除异常节点,但是可以允许逻辑时钟overflow到物理时钟部分,使逻辑时钟更大,这样可以允许更多的事务在当前时钟内发生。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
18天前
|
存储 安全 数据管理
新型数据库技术:基于区块链的分布式数据存储系统
传统数据库系统面临着中心化管理、数据安全性和可信度等方面的挑战。本文介绍了一种基于区块链技术的新型数据库系统,通过分布式存储和去中心化的特性,提高了数据的安全性和可信度,同时实现了高效的数据管理和共享。该系统在多个领域如金融、医疗和物联网等具有广阔的应用前景。
|
2月前
|
缓存 安全 Java
阿里云数据库 SelectDB 内核 Apache Doris 2.0.6 版本正式发布
阿里云数据库 SelectDB 内核 Apache Doris 2.0.6 版本正式发布
|
18天前
|
关系型数据库 Apache 流计算
手把手教你实现 OceanBase 数据到阿里云数据库 SelectDB 内核版 Apache Doris 的便捷迁移|实用指南
本文介绍了如何将数据从 OceanBase 迁移到阿里云数据库 SelectDB 内核版 Apache Doris。提供 3 种数据同步方法 1. 使用 DataX,下载 DataX 并编写配置文件,通过 OceanBaseReader 和 DorisWriter 进行数据迁移。 2. 利用 Apache Doris 的 Catalog功 能,将 OceanBase 表映射到 Doris 并插入数据。 3. 通过Flink CDC,设置 OceanBase 环境,配置 Flink 连接器,实现实时数据同步。
手把手教你实现 OceanBase 数据到阿里云数据库 SelectDB 内核版 Apache Doris 的便捷迁移|实用指南
|
2天前
|
关系型数据库 分布式数据库 数据库
|
4天前
|
存储 监控 Apache
查询提速11倍、资源节省70%,阿里云数据库内核版 Apache Doris 在网易日志和时序场景的实践
网易的灵犀办公和云信利用 Apache Doris 改进了大规模日志和时序数据处理,取代了 Elasticsearch 和 InfluxDB。Doris 实现了更低的服务器资源消耗和更高的查询性能,相比 Elasticsearch,查询速度提升至少 11 倍,存储资源节省达 70%。Doris 的列式存储、高压缩比和倒排索引等功能,优化了日志和时序数据的存储与分析,降低了存储成本并提高了查询效率。在灵犀办公和云信的实际应用中,Doris 显示出显著的性能优势,成功应对了数据增长带来的挑战。
查询提速11倍、资源节省70%,阿里云数据库内核版 Apache Doris 在网易日志和时序场景的实践
|
10天前
|
存储 负载均衡 Go
【Go 语言专栏】使用 Go 语言实现分布式数据库操作
【4月更文挑战第30天】本文探讨了使用Go语言实现分布式数据库操作,强调其在并发性能、网络编程、语法简洁和跨平台性上的优势。关键技术和步骤包括数据分片、数据同步、负载均衡及故障转移。通过实例分析和挑战解决,展示了Go语言在大规模数据处理中的高效与可靠性,为开发者提供指导。
|
10天前
|
SQL 监控 关系型数据库
TiDB 分布式数据库快速入门详解
这些示例展示了TiDB的一些基本操作。实际使用时,你可能需要根据具体的业务需求和环境进行调整和优化。
|
11天前
|
存储 SQL Apache
阿里云数据库内核 Apache Doris 基于 Workload Group 的负载隔离能力解读
阿里云数据库内核 Apache Doris 基于 Workload Group 的负载隔离能力解读
阿里云数据库内核 Apache Doris 基于 Workload Group 的负载隔离能力解读
|
11天前
|
存储 安全 数据管理
新一代数据库技术:融合区块链与分布式存储的未来趋势
传统数据库技术在数据安全性和分布式处理方面存在局限,而新一代数据库技术正日益融合区块链和分布式存储,为数据管理带来革命性变革。本文探讨了这一趋势的发展方向,以及如何利用新技术实现更高效的数据管理与保护。
|
11天前
|
弹性计算 运维 Serverless
Serverless 应用引擎产品使用之在阿里函数计算中,使数据库和阿里云函数计算位于同一个内网中如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
974 0
Serverless 应用引擎产品使用之在阿里函数计算中,使数据库和阿里云函数计算位于同一个内网中如何解决