🚀 免費嘗試 Zilliz Cloud,完全托管的 Milvus,體驗速度提升 10 倍!立即嘗試

milvus-logo
LFAI
  • Home
  • Blog
  • 向量資料庫中的資料插入和資料持久性

向量資料庫中的資料插入和資料持久性

  • Engineering
April 06, 2022
Bingyi Sun

Cover image 封面圖片

本文作者:孫秉義倪安琪轉載。

在 Deep Dive 系列的上一篇文章中,我們介紹了世界上最先進的向量資料庫Milvus 是如何處理資料的。在這篇文章中,我們將繼續檢視資料插入所涉及的組件,詳細說明Milvus的資料模型,並解釋Milvus是如何實現資料持久化的。

跳到

Milvus 架構重溫

Milvus architecture. Milvus 架構

SDK 透過負載平衡器將資料請求傳送到代理,也就是入口網站。然後,代理與協調器服務互動,將 DDL(資料定義語言)和 DML(資料操作語言)請求寫入訊息儲存中。

工作節點(包括查詢節點、資料節點和索引節點)從訊息儲存中消耗這些請求。具體來說,查詢節點負責資料查詢;資料節點負責資料插入和資料持久化;索引節點主要處理索引建立和查詢加速。

底層是物件儲存,主要利用 MinIO、S3 和 AzureBlob 來儲存日誌、delta binlog 和索引檔案。

資料插入請求的入口

Proxy in Milvus. Milvus 中的 Proxy

Proxy 是資料插入請求的入口。

  1. 最初,代理接受 SDK 的資料插入請求,並使用哈希演算法將這些請求分配到幾個資料桶中。
  2. 接著,代理請求資料協調員 (data coord) 分配區段 (segments),這是 Milvus 用來儲存資料的最小單位。
  3. 之後,代理程式會將所要求的區段資訊插入訊息儲存區,以避免這些資訊遺失。

資料坐標與資料節點

Data coord 的主要功能是管理通道和段的分配,而 Data node 的主要功能是消耗和持久化插入的資料。

Data coord and data node in Milvus. Milvus 中的資料協調器和資料節點

功能

資料協調器的功能如下:

  • 分配區段空間資料協調器分配成長中的區段空間給代理,以便代理可以使用區段中的可用空間插入資料。

  • 記錄分段分配和分段中已分配空間的到期時間由 data coord 分配的每個分段中的空間不是永久性的,因此,data coord 也需要記錄每個分段分配的到期時間。

  • 自動沖洗區段資料如果區段已滿,資料協調器會自動觸發資料沖洗。

  • 為資料節點分配通道一個集合可以有多個vnchanels。資料協調器決定哪些 v 通道由哪些資料節點使用。

資料節點在以下方面提供服務:

  • 消耗資料 資料節點從資料協調器分配的通道消耗資料,並為資料建立序列。

  • 資料持久化 在記憶體中快取插入的資料,並在資料量達到特定臨界值時,自動將插入的資料刷新到磁碟。

工作流程

One vchannel can only be assigned to one data node. 一個 vchannel 只能指定給一個資料節點

如上圖所示,集合有四個 v 通道 (V1、V2、V3 和 V4),而有兩個資料節點。資料協調器很可能會指派一個資料節點消耗來自 V1 和 V2 的資料,而另一個資料節點則消耗來自 V3 和 V4 的資料。單一 vchannel 不能指派給多個資料節點,這是為了防止重複消耗資料,否則會造成同一批資料重複插入同一區段。

Root coord 和 Time Tick

Root coord 管理 TSO (時間戳 Oracle),並在全球發佈 Time Tick 訊息。每個資料插入請求都有一個由根坐標指定的時間戳。Time Tick 是 Milvus 的基石,它就像 Milvus 中的時鐘,標誌著 Milvus 系統處於哪個時間點。

在 Milvus 中寫入資料時,每個資料插入請求都帶有時間戳。在資料消耗時,每個時間資料節點消耗時間戳在一定範圍內的資料。

An example of data insertion and data consumption based on timestamp. 一個基於時間戳的資料插入和資料消耗的例子

上圖是資料插入的過程。時間戳的值用數字 1,2,6,5,7,8 表示。資料由兩個代理程式寫入系統:p1 和 p2。在資料消耗期間,如果 Time Tick 的目前時間是 5,資料節點只能讀取資料 1 和 2。然後在第二次讀取時,如果 Time Tick 的目前時間變成 9,資料節點就可以讀取資料 6、7、8。

資料組織:集合、分割、分片 (通道)、區段

Data organization in Milvus. Milvus 中的資料組織

請先閱讀這篇文章,瞭解 Milvus 中的資料模型,以及 collection、shard、partition 和 segment 的概念。

總而言之,Milvus 中最大的資料單位是集合,集合可比喻為關係資料庫中的資料表。一個集合可以有多個分塊(每個分塊對應於一個通道),每個分塊中也可以有多個分區。如上圖所示,通道(分片)是垂直的長條,而分區則是水平的長條。每個交叉點都是區段的概念,也就是資料分配的最小單位。在 Milvus 中,索引建立在段上。在查詢過程中,Milvus 系統也會平衡不同查詢節點的查詢負載,而這個過程是以區段為單位進行的。分段包含數個binlog,當分段資料消耗完畢後,會產生一個 binlog 檔案。

區段

在 Milvus 中,有三種狀態不同的段落:成長中的段落、封閉中的段落和被沖洗的段落。

成長中的區段

成長中的區段是一個新建立的區段,可以分配給代理插入資料。段的內部空間可以是已使用、已分配或已釋放。

Three status in a growing segment 成長中的區段有三種狀態

  • 已使用:成長中區段的這部分空間已被資料節點消耗。
  • 已分配:成長中區段的這部分空間已由代理程式請求,並由資料協調器分配。已分配的空間會在一段時間後過期。
  • Free: 成長中區段的這部分空間未被使用。可用空間的值等於該區段的整體空間減去已使用和已分配空間的值。因此,段的可用空間會隨著已分配空間的到期而增加。

封閉區段

封閉網段是一個封閉的網段,不能再分配給代理插入資料。

Sealed segment in Milvus Milvus 中的封閉網段

成長中的網段在下列情況下會被封閉:

  • 如果成長中的區段已使用的空間達到總空間的 75%,該區段將被封閉。
  • Milvus 使用者手動呼叫 Flush() 來持久化集合中的所有資料。
  • 成長中的區段如果經過一段長時間仍未封存,就會被封存,因為太多成長中的區段會導致資料節點過度佔用記憶體。

刷新的區段

已刷分段是已寫入磁碟的分段。為了資料的持久性,Flush 指的是將區段資料儲存到物件儲存區。只有當封閉區段中分配的空間到期時,區段才能被刷新。當被刷新時,封存的區段會變成被刷新的區段。

Flushed segment in Milvus Milvus 中被刷新的段

通道

通道被分配為 :

  • 當資料節點啟動或關閉;或
  • 當代理要求分配的段空間時。

通道分配有幾種策略。Milvus 支援其中 2 種策略:

  1. 一致性散列

Consistency hashing in Milvus Milvus 的一致性散列

Milvus 的預設策略。此策略利用散列技術為每個通道在環上分配一個位置,然後沿時鐘方向搜尋與通道最近的資料節點。因此,在上圖中,頻道 1 被分配給資料節點 2,而頻道 2 則被分配給資料節點 3。

然而,這個策略有一個問題,就是資料節點數量的增減 (例如:一個新的資料節點開始運作或一個資料節點突然關閉) 會影響頻道分配的過程。為了解決這個問題,data coord 會透過 etcd 監控資料節點的狀態,以便在資料節點的狀態發生任何變化時,立即通知 data coord。然後,data coord 會進一步決定將頻道適當地分配給哪個資料節點。

  1. 負載平衡

第二種策略是將相同集合的頻道分配給不同的資料節點,確保頻道平均分配。此策略的目的是達到負載平衡。

資料分配:時間與方式

The process of data allocation in Milvus Milvus 的資料分配過程

資料分配的過程從用戶端開始。它首先向代理發送帶有時間戳t1 的資料插入請求。然後,代理向資料協調器傳送段分配請求。

收到分段分配請求後,資料協調器檢查分段狀態並進行分段分配。如果已建立區段的目前空間足以容納新插入的資料列,資料協調器就會分配這些已建立的區段。但是,如果目前區段的可用空間不足,資料協調器就會分配新的區段。每次請求時,資料協調器可以傳回一個或多個區段。與此同時,資料協調器也會將已分配的區段儲存在元伺服器中,以便資料持久化。

之後,資料協調器會將已分配區段的資訊 (包括區段 ID、行數、到期時間t2 等) 傳回給代理。代理將這些已分配區段的資訊傳送給訊息存放區,以便正確記錄這些資訊。請注意,t1 的值必須小於t2 的值。t2 的預設值是 2,000 毫秒,可以在data_coord.yaml 檔案中設定參數segment.assignmentExpiration 來改變。

Binlog 檔案結構與資料持久化

Data node flush 資料節點刷新

資料節點訂閱訊息儲存,因為資料插入請求會保存在訊息儲存中,資料節點因此可以消耗插入訊息。資料節點會先將插入請求放置在插入緩衝區中,隨著請求的累積,在達到臨界值後,這些請求就會被刷新到物件儲存區中。

Binlog 檔案結構

Binlog file structure. binlog 檔案結構

Milvus 的 binlog 檔案結構與 MySQL 相似。binlog 用來提供兩個功能:資料復原和索引建立。

binlog 包含許多事件。每個事件都有事件標頭和事件資料。

包括 binlog 建立時間、寫入節點 ID、事件長度和 NextPosition(下一個事件的偏移量)等元資料都寫在事件標頭中。

事件資料可分為固定和可變兩部分。

File structure of an insert event. 插入事件的檔案結構

INSERT_EVENT 事件資料中的固定部分包含StartTimestamp,EndTimestamp, 和reserved

可變部分實際上是儲存插入的資料。插入資料會以 parquet 格式排序,並儲存在此檔案中。

資料持久化

如果 schema 中有多個欄位,Milvus 會將 binlog 儲存在欄位中。

Binlog data persistence. binlog 數據的持久性

如上圖所示,第一列是 binlog 的主索引鍵。第二列是時間戳列。其餘為模式中定義的列。MinIO 中 binlog 的檔案路徑也顯示在上圖中。

關於 Deep Dive 系列

隨著 Milvus 2.0正式宣布全面上市,我們安排了這個 Milvus Deep Dive 系列部落格,提供對 Milvus 架構和原始碼的深入詮釋。本系列部落格涵蓋的主題包括

Like the article? Spread the word

繼續閱讀