阿里数据库底层怎么用HLC搞分布式事务,细节和原理深挖
- 问答
- 2026-01-16 06:32:51
- 1
根据阿里云官方技术博客(如阿里云数据库ApsaraDB公众号、阿里云开发者社区)以及相关技术分享(如阿里资深工程师的技术沙龙内容),阿里在自研分布式数据库(如PolarDB-X、OceanBase等)中,为了解决分布式场景下的事务时序和一致性难题,深度应用并优化了混合逻辑时钟(HLC)机制。
核心问题:为什么需要HLC?
在单机数据库中,确定两个事务谁先谁后非常简单,数据库自身维护一个单调递增的事务ID或时间戳就足够了,但在分布式数据库中,数据分散在多台不同的服务器(称为节点)上,每个节点都有自己的本地物理时钟,这就带来了两个致命问题:
- 物理时钟不同步:尽管我们会使用NTP(网络时间协议)等工具来同步不同机器的时钟,但同步必然存在误差,可能是几毫秒,甚至更多,如果单纯依靠物理时钟来给事务分配时间戳,很可能出现“时间倒流”的诡异现象:即一个在物理时间上稍晚发生的事务,因为其所在节点的时钟更快,反而获得了一个更早的时间戳,这会破坏事务的序列化顺序,导致数据不一致。
- 并发事务的因果关系:即使物理时钟完全同步,也会有问题,假设事务A在节点1上提交,然后触发了在节点2上发起的事务B,从因果关系上看,A一定发生在B之前,但如果节点2的时钟在A提交的瞬间恰好“滴答”了一下,使得B获得的物理时间戳可能比A的还要早一点点,这同样破坏了因果律。
不能直接使用不可靠的物理时钟作为分布式事务的全局时序标准,HLC就是为了解决这个问题而被引入的。
HLC的原理:物理时钟 + 逻辑计数器
HLC的设计非常巧妙,它不是一个全新的时钟,而是对现有物理时钟的一个“增强补丁”,一个HLC时间戳通常是一个二元组 (pt, l)。
pt:代表物理时间部分,它取自当前节点的本地物理时钟(通常是Unix毫秒时间戳)。l:代表逻辑计数部分,是一个整数,用于在物理时间相同的情况下,进一步区分先后顺序。
HLC的核心运作规则可以概括为:

-
本地事件:当节点上发生一个本地事件(比如收到一个客户端请求)时,节点会先读取当前的物理时间
c_pt。c_pt大于当前HLC的物理部分h_pt,说明时间正常流逝了,那么就将HLC的物理部分更新为c_pt,并将逻辑部分l重置为0,新的HLC时间戳就是(c_pt, 0)。c_pt小于或等于h_pt,说明本地时钟没有进步(可能慢了或跳变了),此时不能后退物理部分,HLC会保持h_pt不变,但将逻辑部分l加1,新的HLC时间戳就是(h_pt, l+1)。
-
接收远程消息:这是HLC保证因果关系的关键,当一个节点从其他节点收到一条消息时,消息中会携带发送方在发送时刻的HLC时间戳
(m_pt, m_l)。- 节点同样先读取当前的物理时间
c_pt。 - HLC会取三个值中的最大值:
- 当前HLC的物理部分
h_pt - 消息携带的发送方HLC物理部分
m_pt - 当前的本地物理时间
c_pt将最大值作为新的物理部分new_pt。
- 当前HLC的物理部分
- 如果新的
new_pt来自于本地时钟或者当前HLC的进步,那么逻辑部分l重置为0。 - 如果新的
new_pt等于消息的m_pt且大于当前的h_pt,那么逻辑部分取m_l。 - 如果新的
new_pt等于当前的h_pt且等于消息的m_pt(即物理部分大家都没变),那么逻辑部分取max(当前l, m_l) + 1。
- 节点同样先读取当前的物理时间
通过这套规则,HLC时间戳在任何情况下都只增不减,并且完美地捕捉了事件之间的因果关系:如果事件A发生在事件B之前,那么A的HLC时间戳一定小于B的HLC时间戳。
阿里数据库如何用HLC搞分布式事务?

在阿里的分布式数据库架构中,HLC扮演着“全局时序协调员”的角色。
-
分配全局快照:在支持快照隔离(SI)或更高级别隔离级别的事务中,每个事务在开始时都需要一个全局一致的快照版本号,用于决定它能看到哪些数据,事务管理器会为这个新事务分配一个当前的HLC时间戳作为其开始时间戳,由于HLC的时间戳是单调递增且因果一致的,所有节点在看到这个时间戳时,都认同这是一个“过去”的时间点,从而能够提供出一致的数据快照视图。
-
确定提交顺序:当事务执行完毕准备提交时,协调者节点会为其分配一个提交时间戳,这个时间戳同样来自HLC,这个提交时间戳就是该事务修改数据最终的版本号,所有节点在应用这个事务的修改时,都会用这个HLC时间戳来标记数据行,由于HLC的单调性,后提交的事务永远有更大的时间戳,这保证了数据的版本历史是线性增长的,不会出现混乱。
-
解决冲突与悲观锁:在悲观事务模型中,如果两个事务试图修改同一行数据,后发起的事务会被先到的事务阻塞,当先到的事务提交后,它会释放锁,并带上它的HLC提交时间戳,后到的事务在获取锁后,它的开始时间戳可能需要根据收到的这个HLC时间戳进行调整(通过HLC的消息接收规则),以确保它能看到前一个事务的修改,从而维护可序列化。
-
与TrueTime的结合:根据部分资料提及,阿里在一些场景下可能将HLC与更精确的时钟源(如通过硬件支持的精确时钟,类似于Google的Spanner使用的TrueTime)结合,HLC的物理部分
pt可以不仅仅依赖于误差较大的NTP时钟,而是使用更可靠的时钟源,这样可以极大地减少逻辑部分l的使用频率,使得时间戳的“颗粒度”更细,性能更高。
总结来说,阿里数据库底层利用HLC,巧妙地规避了分布式系统物理时钟不可靠的缺陷,以一种轻量级的方式生成了全局单调递增、且保持因果关系的事务时间戳,这套机制是保障其分布式事务ACID特性(特别是隔离性I和一致性C)的基石之一,使得跨多个节点的数据操作能够像在单机上一样有序、一致地进行。
本文由太叔访天于2026-01-16发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/81636.html
