在分布式系统中,时间同步至关重要。对于 Milvus 这种支持大规模向量检索的分布式数据库,如何确保操作的有序性、减少网络延迟带来的问题,是保障数据一致性和检索结果可靠性的核心。本篇文章将详细介绍 Milvus 的时间同步机制。
时间同步概述
Milvus 中的事件主要分为两大类:
- 数据定义语言(DDL)事件:如创建/删除集合、创建/删除分区等。
- 数据操作语言(DML)事件:如插入、搜索等。
每个事件都带有一个时间戳,以便标记事件的发生时间。但在分布式环境中,时间戳必须统一,否则会出现因时间差异或网络延迟而导致的数据不一致问题。以下示例展示了两个用户在不同时间点执行的事件及其影响:
时间戳 | 用户 1 | 用户 2 |
---|---|---|
t0 | 创建了一个名为 C0 的集合 | / |
t2 | / | 在 C0 集合中进行搜索 |
t5 | 将数据 A1 插入集合 C0 | / |
t7 | / | 在集合 C0 中进行搜索 |
t10 | 将数据 A2 插入集合 C0 | / |
t12 | / | 在集合 C0 中进行搜索 |
t15 | 从集合 C0 中删除数据 A1 | / |
t17 | / | 在集合 C0 中进行搜索 |
理想情况下,用户 2 在不同时间点应看到以下数据:
- t2:集合 C0 为空。
- t7:集合 C0 中包含数据 A1。
- t12:集合 C0 中包含数据 A1 和 A2。
- t17:集合 C0 中只包含数据 A2(数据 A1 已被删除)。
在单节点系统中,这种有序性容易实现。然而,Milvus 作为分布式系统,面临两个关键问题:
- 时间不同步:多个节点的系统时钟可能存在偏差,导致不同节点上的时间不一致。
- 网络延迟:网络延迟可能导致某些事件处理延迟,影响数据的实时一致性。
为了解决这些问题,Milvus 采用了时间同步系统(timetick)。
时间戳服务(TSO)
Milvus 引入了时间戳甲骨文(Timestamp Oracle,TSO)服务,用于统一分布式系统中的时间戳。与传统本地时钟不同,Milvus 中的所有事件时间戳均由 TSO 服务分配。
TSO 时间戳格式
Milvus 的 TSO 时间戳由一个 uint64
值表示,包括物理部分和逻辑部分:
- 物理部分(46 位):以毫秒为单位的 UTC 时间。
- 逻辑部分(18 位):用于在同一毫秒内生成多个时间戳。
这种结构不仅确保时间戳唯一性,还可以在系统内实现一致的时间同步。
时间同步系统(timetick)
Milvus 的时间同步机制通过 timetick 系统实现,其核心流程如下,以数据插入操作为例:
-
消息流:代理在接收到数据插入请求后,会将插入信息分配到不同的消息流(MsgStream),每条插入消息(InsertMsg)在发送前都会分配一个时间戳。
-
时间戳递增:在同一消息流中,来自同一代理的 InsertMsgs 的时间戳是递增的。然而,不同代理的 InsertMsgs 时间戳不保证顺序。
-
时间同步:Milvus 使用一个时间同步系统(timetick)来确保不同代理的消息处理有序。当从消息流中读取信息时,系统确保消耗所有较小时间戳的消息,以保证数据一致性。
时间同步的运行机制
每个代理会定期向根协调器报告消息流中最新 InsertMsg 的最大时间戳值。根协调器会选择消息流中的最小时间戳(即 timetick),并插入到消息流中。消费者组件在读取到此时间戳时,即可确定所有较小时间戳的消息都已被处理。
时间同步示例
如下图所示,消息流会根据时间刻度(timetick)分批处理消息,以确保输出符合时间顺序要求。
该机制不仅确保了 Milvus 中操作的时间一致性,也保障了分布式环境下的数据有序性,提升了系统的实时性和可靠性。
结语
Milvus 通过时间同步系统(timetick)和 TSO 服务解决了分布式环境中的时间不同步和网络延迟问题,保障了数据一致性与可靠性。在大规模数据场景中,良好的时间同步机制至关重要。Milvus 的时间同步系统为各类分布式应用提供了可靠的数据存储与检索支持。