時間同步
本主題介紹 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
。只有資料
A2
att17
(因為資料A1
在此點之前已從集合中刪除)。
當只有一個單一節點時,這種理想的情況很容易實現。然而,Milvus 是分散式向量資料庫,為了確保不同節點的所有 DML 與 DDL 作業都能保持順序,Milvus 需要解決以下兩個問題:
如果上面例子中的兩個使用者在不同的節點上,他們的時間時鐘是不同的。例如,如果使用者 2 比使用者 1 晚 24 小時,那麼使用者 1 的所有作業要到隔天才會被使用者 2 看見。
可能存在網路延遲。如果使用者 2 在
t17
對資料集C0
進行搜尋,Milvus 應該可以保證t17
之前的所有作業都成功處理並完成。如果在t15
的刪除作業因為網路延遲而延遲,使用者 2 在t17
進行搜尋時,很有可能仍然可以看到應該被刪除的資料A1
。
因此,Milvus 採用時間同步系統 (timetick) 來解決問題。
時間戳oracle (TSO)
為了解決上一節提到的第一個問題,Milvus 和其他分散式系統一樣,提供時間戳oracle (TSO) 服務。這表示 Milvus 中的所有事件都必須從 TSO 而非本機時鐘分配時間戳。
TSO 服務由 Milvus 的根協調器提供。用戶端可以在單個時間戳分配請求中分配一個或多個時間戳。
TSO 時間戳是一種uint64
值,由物理部分和邏輯部分組成。下圖展示了時間戳的格式。
TSO_Timestamp.
如圖所示,開頭的 46 位元是實體部分,也就是以毫秒為單位的 UTC 時間。最後的 18 位元是邏輯部分。
時間同步系統 (timetick)
本節以資料插入操作為例,說明 Milvus 的時間同步機制。
當 proxy 收到 SDK 的資料插入請求時,會依照主鍵的哈希值將插入訊息分成不同的訊息流 (MsgStream
)。
每條插入訊息 (InsertMsg
) 在傳送到MsgStream
之前,都會被指定一個時間戳。
MsgStream
是訊息佇列的包裝,在 Milvus 2.0 預設是 Pulsar。
timesync_proxy_insert_msg
一個一般原則是,在MsgStream
, 來自同一個 proxy 的InsertMsgs
的時間戳必須是遞增的。但是,對於來自不同代理的InsertMsgs
,則沒有這樣的規則。
下圖是InsertMsgs
在MsgStream
中的範例。該片段包含五個InsertMsgs
,其中三個來自Proxy1
,其餘來自Proxy2
。
msgstream
來自Proxy1
的三個InsertMsgs
的時間戳是遞增的,來自Proxy2
的兩個InsertMsgs
的時間戳也是遞增的。但是,Proxy1
和Proxy2
InsertMsgs
之間沒有特定的順序。
一種可能的情況是,當從Proxy2
讀取時間戳為110
的訊息時,Milvus 發現時間戳為80
的訊息仍在Proxy1
的MsgStream
中。因此,Milvus 引進了時間同步系統 timetick,以確保從MsgStream
讀取訊息時,必須消耗所有時間戳值較小的訊息。
時間同步
如上圖所示、
每個代理定期 (預設為每 200 ms) 將
MsgStream
中最新InsertMsg
的最大時間戳值報告給根坐標。無論
InsertMsgs
屬於哪個代理伺服器,Root Coord 都會找出這個Msgstream
的最小時間戳值。然後,root coord 將這個最小時間戳插入Msgstream
。這個時間戳也稱為 timetick。當消費者元件讀取由根坐標插入的 timetick 時,它們會了解所有時間戳值較小的插入訊息已被消耗。因此,可以在不中斷訂單的情況下安全地執行相關請求。
下圖是Msgstream
插入時間刻度的範例。
時間標記
MsgStream
會根據時間刻度分批處理訊息,以確保輸出訊息符合時間戳記的要求。在上面的範例中,它會在 消耗除了 的 以外的所有記錄,因為它是在最新的 TimeTick 之後。Timestamp: 120
Proxy2
InsertMsgs