JSON 切碎Compatible with Milvus 2.6.2+

JSON 切碎可將傳統的基於行的存儲轉換為優化的列存儲,從而加速 JSON 查詢。在維持 JSON 資料建模彈性的同時,Milvus 執行幕後列式最佳化,大幅改善存取與查詢效率。

JSON 切碎對大多數 JSON 查詢場景都很有效。在下列情況下,性能優勢會更加明顯

  • 更大、更複雜的 JSON 文件- 隨著文件大小的增加,性能提升也更大

  • 讀取繁重的工作負載- 經常對 JSON 鍵進行篩選、排序或搜尋

  • 混合查詢模式- 跨不同 JSON 鍵的查詢可從混合儲存方法中獲益

如何運作

JSON 切碎過程分為三個不同階段,以優化資料,方便快速檢索。

階段 1:擷取與關鍵分類

當有新的 JSON 文件寫入時,Milvus 會持續取樣並進行分析,以建立每個 JSON key 的統計資料。這項分析包括關鍵字的出現比率和類型穩定性(其資料類型在各文件中是否一致)。

根據這些統計資料,JSON 金鑰會被分類為下列類別,以便進行最佳儲存。

JSON 金鑰類別

關鍵類型

說明

類型鍵

存在於大多數文件中,且總是具有相同資料類型的關鍵(例如,所有整數或所有字串)。

動態鍵值

經常出現但具有混合資料類型的鍵 (例如:有時是字串,有時是整數)。

共用鍵

出現頻率低於可設定頻率臨界值的不常出現或巢狀的鍵

分類範例

考慮包含以下 JSON 鍵的 JSON 資料樣本:

{"a": 10, "b": "str1", "f": 1}
{"a": 20, "b": "str2", "f": 2}  
{"a": 30, "b": "str3", "f": 3}
{"a": 40, "b": 1, "f": 4}       // b becomes mixed type
{"a": 50, "b": 2, "e": "rare"}  // e appears infrequently

基於此資料,鍵將分類如下:

  • 類型鍵af (總是整數)

  • 動態鍵b (混合字串/整數)

  • 共用鍵e (不常出現的鍵)

第二階段:儲存優化

第 1 階段的分類決定了儲存配置。Milvus 使用針對查詢最佳化的列式格式。

Json Shredding Flow Json 切碎流程

  • 切碎列:對於鍵入動態鍵,資料會寫入專用列。這種列式儲存可在查詢時進行快速、直接的掃描,因為 Milvus 可以只讀取給定鍵所需的資料,而無需處理整個文件。

  • 共用列:所有共用鍵都一起儲存在單一精簡的二進位 JSON 列中。在此列上會建立一個共享鑰匙反向索引。此索引對於加速低頻關鍵值的查詢非常重要,它允許 Milvus 快速剪裁資料,有效地將搜尋空間縮小到只包含指定關鍵值的行。

第 3 階段:查詢執行

最後階段利用最佳化的儲存配置,為每個查詢謂語智慧地選擇最快的路徑。

  • 快速路徑:對於類型化/動態鍵 (例如json['a'] < 100) 的查詢會直接存取專用欄位。

  • 最佳化路徑:對共用鍵 (例如:json['e'] = 'rare')進行查詢時,可使用倒置索引快速找到相關文件

啟用 JSON 切碎

若要啟用此功能,請在milvus.yaml 配置檔案中設定common.enabledJSONShreddingtrue 。新資料將自動觸發粉碎程序。

# milvus.yaml
...
common:
  enabledJSONShredding: true # Indicates whether to enable JSON key stats build and load processes
...

一旦啟用,Milvus 將會在輸入時開始分析和重組您的 JSON 資料,而無需任何進一步的手動介入。

參數調整

對大多數用戶而言,一旦啟用 JSON 切碎,其他參數的預設值就足夠了。但是,您可以使用milvus.yaml 中的這些參數微調 JSON 切碎的行為。

參數名稱

說明

預設值

調整建議

common.enabledJSONShredding

控制是否啟用 JSON 切碎的建立和載入程序。

必須設定為true才能啟用該功能。

common.usingjsonShreddingForQuery

控制 Milvus 是否使用切碎資料加速。

true

設定為false,作為查詢失敗時的恢復措施,回復原始查詢路徑。

queryNode.mmap.jsonShredding

決定 Milvus 在載入切碎資料時是否使用 mmap。

詳情請參閱使用 mmap

true

此設定一般為效能最佳化。只有在您的系統有特定記憶體管理需求或限制時,才調整它。

dataCoord.jsonShreddingMaxColumns

將儲存在切碎列中的 JSON 金鑰的最大數量。

如果經常出現的金鑰數量超過此限制,Milvus 會優先將最常出現的金鑰粉碎,其餘的金鑰會儲存在共用列中。

1024

這對大多數情況來說已經足夠。對於有上千個常見鑰匙的 JSON,您可能需要增加這個限制,但請監控儲存空間的使用。

dataCoord.jsonShreddingRatioThreshold

JSON 金鑰必須具備的最小出現比率,才會被考慮粉碎到粉碎列中。

如果鍵的出現比率高於此臨界值,則該鍵被視為經常出現。

0.3

如果符合粉碎條件的鑰匙數量超過dataCoord.jsonShreddingMaxColumns 限制,則增加(例如增加到 0.5)。這會使臨界值更嚴格,減少符合粉碎條件的鑰匙數量。

如果您想要粉碎更多出現次數少於預設 30% 閾值的金鑰,請降低(例如,至 0.1)。

效能基準

我們的測試顯示,在不同的 JSON 金鑰類型和查詢模式下,效能都有顯著的改善。

測試環境與方法

  • 硬體:1 核心/8GB 集群

  • 資料集:來自JSONBench的 100 萬個文件

  • 平均文件大小:478.89 位元組

  • 測試持續時間:100 秒測量 QPS 與延遲

結果:鍵入

本測試測量查詢大多數文件中存在的鍵時的效能。

查詢表達

鍵值類型

QPS (未粉碎)

QPS (有切碎)

效能提升

json['time_us'] > 0

整數

8.69

287.50

33x

json['kind'] == 'commit'

字串

8.42

126.1

14.9x

結果:共用鍵

此測試的重點在於查詢屬於 「共用」 類的稀疏嵌套鍵。

查詢表達

鍵值類型

QPS (未粉碎)

QPS (有切碎)

效能提升

json['identity']['seq'] > 0

嵌套整數

4.33

385

88.9x

json['identity']['did'] == 'xxxxx'

巢狀字串

7.6

352

46.3x

關鍵洞察

  • 共用關鍵查詢顯示出最顯著的改進(快達 89 倍)

  • 類型關鍵查詢提供一致的 15-30 倍效能提升

  • 所有查詢類型都能從 JSON Shredding 中獲益,而不會造成效能退步

常見問題

  • 如何驗證 JSON 破碎處理是否正常運作?

    1. 首先,使用Birdwatcher工具中的show segment --format table 指令檢查資料是否已建立。如果成功,輸出將在Json Key Stats欄位下包含shredding_data/shared_key_index/

      Birdwatcher Output Birdwatcher 輸出

    2. 接下來,在查詢節點上執行show loaded-json-stats ,驗證資料是否已載入。輸出將顯示每個查詢節點已載入切碎資料的詳細資訊。

  • 如果遇到錯誤該怎麼辦?

    如果建立或載入程序失敗,您可以透過設定common.enabledJSONShredding=false 快速停用該功能。要清除任何剩餘任務,請使用Birdwatcher 中的remove stats-task <task_id> 指令。如果查詢失敗,請設定common.usingjsonShreddingForQuery=false 以恢復原始查詢路徑,繞過粉碎資料。

  • 如何在 JSON 切碎和 JSON 索引之間進行選擇?

    • JSON 切碎非常適合文件中經常出現的鍵,尤其是複雜的 JSON 結構。它結合了列式儲存和倒轉索引的優點,非常適合您查詢許多不同鍵的重讀情境。但是,不建議用於非常小的 JSON 文件,因為性能增益微乎其微。關鍵值佔 JSON 文件總大小的比例越小,粉碎的性能優化效果就越好。

    • JSON 索引更適合針對特定的基於關鍵值的查詢進行有針對性的優化,並且具有較低的存儲開銷。它適用於較簡單的 JSON 結構。請注意,JSON 切碎並不涵蓋對陣列內部鍵的查詢,因此您需要 JSON 索引來加速這些查詢。

    詳情請參閱JSON 欄位概述