Milvus 在流式數據場景下的性能表現-基於 Kafka 的實現

Milvus 作爲一款開源的特徵向量相似度搜索引擎,其開源半年以來,在全球已經有數百家企業或組織用戶。這些用戶涉及各個領域,包括金融、互聯網、電商、生物製藥等。在部分用戶的生產場景中,其數據大多是持續地、動態地生成,且要求這些動態生成的數據入庫後能很快被檢索到。

大數據處理可分爲批式大數據(又稱爲“歷史大數據”)處理和流式大數據(又稱爲“實時大數據”)處理兩類。在大多數情況下,流數據在處理持續生成的動態新數據方面具有顯著優勢。流數據是指由多個數據源持續生成的數據,通常同時以較小規模的數據記錄的形式發送,約幾千字節。流數據可爲各種形式的數據,例如網購數據、社交網站信息、地理空間服務,以及通過遙感器測控得到的數據。

 

| Milvus 應用

在用戶需求的驅動下, Milvus 不斷增加其功能,探索更多的應用場景。Milvus 動態數據管理策略,使得用戶可以隨時對數據進行插入、刪除、搜索、更新等操作,無需受到靜態數據帶來的困擾。在插入或更新數據之後,幾乎可以立刻對插入或更新過的數據進行檢索, Milvus 能夠保證搜索結果的準確率和數據一致性。同時在源源不斷的數據導入過程中, Milvus 依然能夠保持優秀的檢索性能。由於這些特性, Milvus 可以很好地適用於流式大數據的場景。

在很多用戶場景中,結合了批式大數據和流式大數據兩種處理方式,從而構建一種混合模式,來同時維持實時處理和批處理。比如在推薦系統的實現中,無論是文章、音樂、視頻等推薦或者是電商平臺的商品推薦,都存在許多歷史數據。平臺給用戶做推薦時,部分歷史數據依舊有被推薦的價值,因此這些歷史數據需要經過去重、過濾等處理然後存入 Milvus 中。除了歷史保留的數據,在推薦系統中每天還會產生新的數據,包括新的文章、熱點以及新的商品等,這些數據也要及時的導入庫中並且要求能夠很快被檢索到,這些持續產生的數據就是流式數據。

隨着越來越多的用戶有動態插入數據、實時檢索的需求,本文將介紹一下基於 Kafka 實現的 Milvus 在流式數據場景下的參數配置和檢索的性能。

 

| 場景模擬

Kafka 是一個開源的流處理平臺,這裏將介紹基於 Kafka 實現的 Milvus 在流式數據下的兩個應用示例。

示例一

該系統中使用 Kafka 接收各個客戶端產生的數據來模擬生成的流式數據。當 Kafka 消息隊列中有數據時,數據接收端持續從 Kafka 隊列中讀取數據並立即插入 Milvus 中。 Milvus 中插入向量的數據量是可大可小的,用戶可一次插入十條向量,也可一次插入數十萬條向量。該示例適用於數據實時性要求較高的場景。全過程如圖所示:

配置:

  • index_file_size : 在 Milvus 中,數據是分文件存儲的,每個數據文件大小在建立集合的時候由參數 index_file_size 值來定義。數據寫入磁盤後,成爲原始數據文件,保存的是向量的原始數據,每當原始數據文件大小達到 index_file_size 值後,便會觸發建立索引,索引建立完成後會生成一個索引數據文件。

    Milvus 進行檢索時,將在索引文件中去檢索。對於未建立索引的數據,將會在原始數據文件中檢索。由於未建立索引的部分,檢索會比較慢,因此 index_file_size 不宜設置得過大,本示例中該值設置爲 512。(若 index_file_size 過大,會使得未建立索引的數據文件較大,降低檢索性能。)

  • nlist : 該值表示 Milvus 建立索引後,每個數據文件裏的向量被分爲多少個“簇”。本示例中將該值設置爲 1024。

  • Milvus 在不斷插入數據的過程中,會不停的建立索引。爲了保證檢索的效率,這裏選擇了用 GPU 資源建立索引,用 CPU 資源進行檢索。

性能:

本示例中,在持續導入數據之前,向集合中插入了一億條 128 維的向量,並建立 IVF_SQ8 索引,來模擬歷史數據。此後持續的向該集合中隨機的間隔 1-8 秒插入 250-350 條向量。隨後進行多次檢索,檢索性能如下:

在上述性能記錄中,第一次檢索時間指的是每次有新增數據導入後的檢索時間,第二次檢索時間是在第一次檢索後沒有新的數據導入前的檢索時間。

橫向比較,發現第一次檢索時間大於第二次,是因爲第一次檢索時會將新導入的數據從磁盤加載到內存。

縱向比較來看,在數據持續導入過程中,第一次檢索耗時持續增長。這是因爲在持續導入數據的過程中,新增數據文件會和之前未建立索引的數據文件合併,檢索時會將新合併的數據文件從磁盤加載到內存。隨着導入數據的增多,合併好的這個新文件會越來越大,從磁盤加載到內存的耗時也將增加。其次,導入的這部分數據都未建立索引,隨着未建立索引的數據增多,在這部分數據中檢索的時間也會逐步增加。第二次檢索耗時也越來越長,但其耗時增長幅度相較於第一次較小。是因爲第二次檢索沒有將數據從磁盤加載到內存的過程,耗時增長只是因爲未建立索引的數據越來越多。數據在導入到約 100 萬條的時候(每個數據文件是 512 MB , 向量 128 維,所以每個數據文件約 100 萬條向量),觸發了建索引的閾值。當索引建立完成,檢索時均是在索引文件中進行檢索的,所以這個時候的第二次檢索時間又回到動態導入數據前的性能。

在本示例持續導入數據的過程中(累計導入約 100 萬),每隔 5 秒採樣查詢一次,並記錄其查詢時間。整個過程查詢性能趨勢如下圖所示,縱座標表示查詢耗時,橫座標表示整個查詢過程的時刻,以秒爲單位。

在這個折線圖中,大部分點(圖中處於上方的這些點)對應上述表格中的第一次檢索時間。從圖可以看出,導入數據後的第一次檢索時間有較大幅度上升的趨勢。少數點(圖中處於下方的這些點)對應上述表格中的第二次檢索時間,第二次檢索時間有一個稍微上升的趨勢。在該示例中,因爲數據頻繁導入,所以檢索時更多的是在有新數據導入後去檢索的情況。從上述圖中還可以看到,當導入數據總量達到建索引的閾值時,建立完索引之後的查詢時間又恢復到動態導入數據之前的水平。

同時經測試,新插入的數據,在一兩秒後即能被檢索到。

 

示例二

該系統中使用 Kafka 接收各個客戶端產生的數據來模擬生成的流式數據,當 Kafka 隊列中有數據到達時,讀取 Kafka 中的數據,當數據積累到一定量(本示例中爲 10 萬)的時候,批量插入 Milvus 中,這樣能夠減少插入次數,提高整體檢索性能。該示例適用於對數據實時性要求不那麼高的場景。該過程流程如圖:

配置:該示例的配置同示例一。

性能:在導入新的數據之前,查詢耗時約 0.027 秒。在後續導入過程中,每次批量插入 10 萬條數據。數據導入過程中,數據導入後的第一次檢索時間以及第二次檢索時間和示例一的表中顯示時間差不多。由於沒有頻繁的數據導入操作,所以在檢索時,大多數時候的檢索時間都對應上述表中的第二次檢索時間。

在本示例持續批量導入數據的過程中(累計導入約 100 萬),每隔 5 秒採樣查詢一次,並記錄其查詢時間。整個過程查詢性能趨勢如下圖所示,縱座標表示查詢耗時,橫座標表示整個查詢過程的時刻,以秒爲單位。

在該該折線圖中可以看到,由於插入頻率降低,所以大多數檢索時對應示例一表格中的第二次檢索時間。只有在每次導入十萬數據後,檢索耗時相對較長。同樣的,在建完索引之後,查詢時間也恢復到導入數據之前的水平。

從上述兩個示例的性能表現折線圖來看,在有頻繁的檢索操作,同時對新增數據的實時性要求不高的情況,累計批量數據插入是更優的選擇。

 

| 結語

隨着用戶的增多,Milvus 被提出了更多的需求,在用戶需求的驅動中,Milvus 將不斷的完善和豐富自身的功能。Milvus 致力於在非結構化數據處理的道路上,爲用戶提供更多的價值。同時也希望更多志同道合的夥伴加入 Milvus 開源社區,一起參與、見證 Milvus 的成長。

 

| 歡迎加入 Milvus 社區

github.com/milvus-io/milvus | 源碼

milvus.io | 官網

milvusio.slack.com | Slack 社區

zhihu.com/org/zilliz-11/columns | 知乎

zilliz.blog.csdn.net | CSDN 博客

space.bilibili.com/478166626 | Bilibili

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章