时间同步
本主题介绍 Milvus 的时间同步机制。
概述
Milvus 中的事件一般可分为两类:
数据定义语言(DDL)事件:创建/删除集合、创建/删除分区等。
数据操作语言(DML)事件:插入、搜索等。
任何事件,不管是 DDL 还是 DML 事件,都标有一个时间戳,可以显示该事件发生的时间。
假设有两个用户在 Milvus 中发起了一系列 DML 和 DDL 事件,时间顺序如下表所示。
时间戳 | 用户 1 | 用户 2 |
---|---|---|
t0 | 创建了一个名为C0 的集合。 | / |
t2 | / | 在C0 库中进行搜索。 |
t5 | 将数据A1 插入数据集C0 . | / |
t7 | / | 在文集C0 中进行搜索。 |
t10 | 将数据A2 插入数据集C0 . | / |
t12 | / | 对数据集进行搜索C0 |
t15 | 从数据集中删除数据A1 C0 . | / |
t17 | / | 对数据集进行搜索C0 |
理想情况下,用户 2 应该能够看到
一个空的集合
C0
在t2
.数据
A1
,网址t7
。数据
A1
和A2
均位于t12
。只有
t17
上的数据A2
(因为在此之前,数据A1
已从集合中删除)。
当只有一个节点时,这种理想情况很容易实现。但是,Milvus 是一个分布式向量数据库,为了确保不同节点中的所有 DML 和 DDL 操作都能保持有序,Milvus 需要解决以下两个问题:
上面例子中的两个用户如果在不同的节点上,他们的时间时钟是不同的。例如,如果用户 2 比用户 1 晚 24 小时,那么用户 1 的所有操作在第二天之前都不会被用户 2 看到。
可能存在网络延迟。如果用户 2 在
t17
上对集合C0
进行搜索,Milvus 应能保证t17
之前的所有操作都被成功处理并完成。如果t15
上的删除操作因网络延迟而延迟,那么用户 2 在t17
上进行搜索时,很可能仍能看到本应删除的数据A1
。
因此,Milvus 采用了时间同步系统(timetick)来解决这些问题。
时间戳甲骨文(TSO)
为了解决上一节提到的第一个问题,Milvus 和其他分布式系统一样,提供了时间戳甲骨文(TSO)服务。这意味着 Milvus 中的所有事件都必须分配一个来自 TSO 而不是本地时钟的时间戳。
TSO 服务由 Milvus 的根协调器提供。客户端可以在单个时间戳分配请求中分配一个或多个时间戳。
TSO 时间戳是一种uint64
值,由物理部分和逻辑部分组成。下图展示了时间戳的格式。
TSO_Timestamp.
如图所示,开头的 46 位是物理部分,即以毫秒为单位的 UTC 时间。最后 18 位是逻辑部分。
时间同步系统(timetick)
本节以数据插入操作为例,解释 Milvus 的时间同步机制。
当代理收到 SDK 的数据插入请求时,它会根据主键的哈希值将插入信息分成不同的信息流 (MsgStream
) 。
每条插入信息 (InsertMsg
) 在发送到MsgStream
之前都会被分配一个时间戳。
MsgStream
Timesync_proxy_ins 是消息队列的封装器,在 Milvus 2.0 中默认为 Pulsar。timesync_proxy_insert_msg
一般原则是,在MsgStream
中,来自同一代理的InsertMsgs
的时间戳必须是递增的。但是,来自不同代理的InsertMsgs
的时间戳却没有这样的规则。
下图是InsertMsgs
在MsgStream
中的示例。该代码段包含五个InsertMsgs
,其中三个来自Proxy1
,其余来自Proxy2
。
msgstream
来自Proxy1
的三个InsertMsgs
的时间戳是递增的,来自Proxy2
的两个InsertMsgs
的时间戳也是递增的。但是,Proxy1
和Proxy2
InsertMsgs
之间没有特定的顺序。
Proxy1
一种可能的情况是,当从Proxy2
读取时间戳为110
的信息时,Milvus 发现时间戳为80
的信息仍在MsgStream
中。因此,Milvus 引入了时间同步系统 timetick,以确保从MsgStream
读取信息时,必须消耗掉所有时间戳值较小的信息。
时间同步
如上图所示、
每个代理定期(默认情况下每 200 毫秒)向根协调器报告
MsgStream
中最新InsertMsg
的最大时间戳值。根协调器会识别该
Msgstream
上的最小时间戳值,无论该InsertMsgs
属于哪个代理。然后,根协调器将这个最小时间戳插入Msgstream
。这个时间戳也称为 timetick。当消费者组件读取根协调器插入的时间戳时,它们就会明白所有时间戳值较小的插入信息都已被消耗。因此,可以在不中断订单的情况下安全地执行相关请求。
下图是Msgstream
插入时间刻度的示例。
时间戳
MsgStream
根据时间刻度分批处理报文,以确保输出的报文符合时间戳的要求。