摘要:分布式事务是分布式数据库最难攻克的技术之一,分布式事务为分布式数据库提供一致性数据访问的支持,保证全局读写原子性和隔离性,提供一体化分布式数据库的用户体验。本文主要分享分布式数据库中的时钟解决方案及分布式事务管理技术方案。混合逻辑时钟(HLC)能够实现本地获取,避免了中心时钟的性能瓶颈和单点故障,同时维护了跨实例的事务或事件的因果(happen before)关系。算法
演讲嘉宾简介:
何登成(花名:圭多),阿里云智能数据库产品事业部资深技术专家,DTCC的老朋友。从2005年开始一直坚守在数据库内核研发领域,前后在神州通用、网易和阿里从事数据库内核产品研发工做,目前带领团队打造阿里新一代分布式数据库POLARDB-X。数据库
直播回放
连接:https://yq.aliyun.com/live/1045服务器
议题PPT下载,戳这里!
https://yq.aliyun.com/downloa...并发
本次的分享主要围绕如下两个方面:app
1、时钟方案
2、分布式事务管理分布式
1、时钟方案
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、一、二、3...。事务开始后加1,新事务开再加1。整个分布式环境下,三个节点彻底独立,相互之间没有关系。若是事务跨多个节点,涉及到多个节点交互,产生一个事务的时候,本地时钟要加1。发message出去的时候,要把message的主体发出去,还要将本地的时间发给另外一个节点。收到一个message节点后要处理这条消息,从收到的消息里面将对时间和本地的逻辑时间作一个取值,取最大的值设为本地时间。若是A节点发布较快,第一个事务完成之后,要作第二个事务,这时与B节点有交流,A加1,而后将时钟带到B节点,B节点直接从0跳到2。如此就在两个时钟之间创建了联系,经过创建联系,将两个节点之间的逻辑时钟拉平,这时候就构建它们之间的happen before的关系,表明A节点的事务是在B节点的新事务开始以前完成的。分布式数据库中,若是两个事务没有操做一样的节点,则两个事务是无关的事务。无关的事务能够认为是没有前后顺序的。可是当一个事务横跨多个节点的时候,将多个节点之间的关系创建起来,就变成有关系的事务,构建的是事务间的因果序。所谓因果序,若是一样来了两个事务,一个事务操做AB节点,另一个事务操做BC节点,由于它们在B节点上创建了一个联系。经过B节点的关系,将事务的顺序维护起来。
纯逻辑时钟能够起到因果一致性和因果序的能力。那逻辑时钟最大的问题是什么呢?最极端的状况下,节点和节点之间永远不产生联系,两个节点之间的逻辑时钟的差距会愈来愈大。这时若是两个节点之间作查询或者备份,须要强制将它们创建关系,那么两节点之间的gap会变得很是大。
混合时钟
虽然机器和机器之间物理时钟有偏移,但若是有NTP校准或者Google的Truetime这种时钟服务器话,其物理时钟的差距是很是小的。混合时钟把分布式下的时钟切成两部分,上半部分用物理时钟来填充,下半部分用逻辑时钟来填充。填充在一块儿变成了一个HLC时钟,既混合逻辑时钟。它既有物理时钟的部分,又有逻辑时钟的部分。因为物理时钟服务器之间的差距不会特别大,因此能够比较物理时钟大小。而物理时钟又有必定的误差,在必定的误差范围内,可使用逻辑时钟作校准。下图是混合逻辑时钟的一个示例。当发送一个消息的时候,首先应该把逻辑时钟的物理时钟部分与当前的时钟作一个比较。若是当前的物理时钟是4点,新事务产生后,由于物理时钟没变,新事务加在逻辑时钟的部分(加1)。若是物理时钟从4点变成4:01,则将物理时钟推动。物理时钟若是不推动,就加逻辑时钟。若是物理时钟发生了变化就把物理时钟往上推动,将逻辑时钟部分置零。
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中能够发现每个事务的提交都要等待一段时间,就是要等这段时钟误差。
2、分布式事务管理
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到物理时钟部分,使逻辑时钟更大,这样能够容许更多的事务在当前时钟内发生。