向量搜尋概觀 - Amazon MemoryDB

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

向量搜尋概觀

向量搜尋建立在建立、維護和使用索引的基礎上。每個向量搜尋操作都會指定單一索引,且其操作會侷限於該索引,也就是說,一個索引上的操作不受任何其他索引上的操作影響。除了建立和銷毀索引的操作之外,任何數量的操作都可以隨時針對任何索引發出,這表示在叢集層級,針對多個索引的多個操作可能會同時進行。

個別索引是存在於唯一命名空間中的具名物件,與其他 Valkey 和 Redis OSS命名空間分開:金鑰、函數等。每個索引在概念上都與傳統資料庫資料表類似,因為它分為兩個維度:資料欄和資料列。資料表中的每個資料列對應至金鑰。索引中的每個資料欄對應於該索引鍵的成員或部分。在本文件中,術語索引鍵、資料列和記錄完全相同,可互換使用。同樣地,術語欄、欄位、路徑和成員基本上是相同的,並且也可以互換使用。

沒有要新增、刪除或修改索引資料的特殊命令。而修改索引中索引索引鍵的現有 HASHJSON命令也會自動更新索引。

索引和 Valkey 和 Redis OSS鍵空間

索引在 Valkey 和 Redis OSS鍵空間的一個子集上建構和維護。多個索引可選擇不相交或重疊的鍵空間子集,不受限制。每個索引的鍵空間由建立索引時提供的鍵首清單定義。字首清單是選用的,如果省略,整個鍵空間將是該索引的一部分。索引也會輸入,其中只會涵蓋具有相符類型的金鑰。目前僅支援 JSON和 HASH索引。HASH 索引只會為其字首清單所涵蓋的HASH索引鍵編製索引,類似地,JSON索引只會為其字首清單所涵蓋的索引JSON鍵編製索引。索引鍵空間字首清單中沒有指定類型的索引鍵會被忽略,不會影響搜尋操作。

當 HASH或 JSON命令修改索引鍵空間內的索引鍵時,索引會更新。此程序涉及擷取每個索引的宣告欄位,並使用新值更新索引。更新程序是在背景執行緒中完成,這表示索引最終僅與其鍵空間內容一致。因此,在短時間內,在搜尋結果中不會顯示金鑰的插入或更新。在繁重的系統負載和/或大量資料突變期間,可見性延遲可能會變得更長。

建立索引是多步驟程序。第一個步驟是執行定義索引的 FT.CREATE 命令。成功執行建立會自動啟動第二個步驟 – 回填。回填程序會在背景執行緒中執行,並掃描索引字首清單中索引鍵的金鑰空間。找到的每個索引鍵都會新增至索引。最後掃描整個鍵空間,完成索引建立程序。請注意,在執行回填程序時,允許索引索引金鑰的突變,沒有限制,而且索引回填程序在所有金鑰都正確編製索引之前都不會完成。不允許在索引進行回填時嘗試查詢操作,並以錯誤終止。完成回填程序可以從該索引 ('backfill_status') 的FT.INFO命令輸出來決定。

索引欄位類型

索引的每個欄位 (資料欄) 都有特定類型,會在建立索引時宣告,以及索引鍵內的位置。對於HASH索引鍵,位置是 中的欄位名稱HASH。對於JSON金鑰,位置是JSON路徑描述。修改金鑰時,會擷取與宣告欄位相關聯的資料,將其轉換為宣告類型並儲存在索引中。如果資料遺失或無法成功轉換為宣告類型,則索引會省略該欄位。欄位有四種類型,如下所示:

  • 數字欄位包含單一數字。對於 JSON 欄位,必須遵循JSON數字的數值規則。對於 HASH, 欄位應包含以固定或浮點數標準格式寫入的數字ASCII文字。無論金鑰中的表示法為何,此欄位都會轉換為 64 位元浮點數,以供索引內儲存。數字欄位可與範圍搜尋運算子搭配使用。由於基礎數字存放在具有精確度限制的浮點中,因此適用浮點數字比較的一般規則。

  • 標籤欄位包含以單一 UTF-8 字串編碼的零個或多個標籤值。字串會使用分隔符號字元 (預設為逗號,但可以覆寫) 剖析為標籤值,並移除前後空白。任何數量的標籤值都可以包含在單一標籤欄位中。標籤欄位可用來篩選標籤值等價性的查詢,並以區分大小寫或區分大小寫的比較進行。

  • 文字欄位包含不需要 UTF-8 合規的位元組 Blob。文字欄位可用來裝飾具有應用程式平均值的查詢結果。例如 URL或 文件的內容等。

  • 向量欄位包含一個數字向量,也稱為內嵌。向量欄位支援使用指定演算法和距離指標進行固定大小向量的 K 最近鄰居搜尋 (KNN)。對於HASH索引, 欄位應包含以二進位格式編碼的整個向量 (little-endian IEEE 754)。對於JSON索引鍵,路徑應參考填入數字的正確大小陣列。請注意,當JSON陣列用作向量欄位時,JSON金鑰內陣列的內部表示式會轉換為所選演算法所需的格式,從而減少記憶體消耗和精確度。使用 JSON 命令的後續讀取操作將產生降低的精確度值。

向量索引演算法

提供兩種向量索引演算法:

  • 平面 – 平面演算法是索引中每個向量的暴力力線性處理,在距離運算精確度的界限內產生確切的答案。由於索引的線性處理,此演算法的執行時間對於大型索引來說可能非常高。

  • HNSW (階層式可導覽小世界) – HNSW演算法是一種替代方案,可提供近似的正確答案,以換取大幅較低的執行時間。演算法由三個參數 MEF_CONSTRUCTION和 控制EF_RUNTIME。前兩個參數是在索引建立時間指定,無法變更。EF_RUNTIME 參數具有建立索引時指定的預設值,但之後可在任何個別查詢操作上覆寫。這三個參數會互動,以在擷取和查詢操作期間平衡記憶體和CPU消耗,並控制精確KNN搜尋的近似品質 (稱為召回率)。

兩個向量搜尋演算法 (平面和 HNSW) 都支援選用INITIAL_CAP參數。指定時,此參數會預先配置索引的記憶體,進而降低記憶體管理額外負荷並提高向量擷取速率。

像 這樣的向量搜尋演算法HNSW可能無法有效地處理先前插入的向量的刪除或覆寫。使用這些操作可能會導致索引記憶體耗用過多and/or degraded recall quality. Reindexing is one method for restoring optimal memory usage and/or。

向量搜尋查詢表達式

FT.SEARCHFT.AGGREGATE 命令需要查詢表達式。此表達式是由一或多個運算子組成的單一字串參數。每個運算子都會使用索引中的一個欄位來識別索引中索引鍵的子集。可以使用布林合併器和括號來合併多個運算子,以進一步增強或限制收集的金鑰集 (或結果集)。

萬用字元

萬用字元運算子,星號 (‘*’),符合索引中的所有索引鍵。

數值範圍

數值範圍運算子具有下列語法:

<range-search> ::= '@' <numeric-field-name> ':' '[' <bound> <bound> ']' <bound> ::= <number> | '(' <number> <number> ::= <integer> | <fixed-point> | <floating-point> | 'Inf' | '-Inf' | '+Inf'

<numeric-field-name> 必須是類型 的宣告欄位NUMERIC。依預設,邊界包含 ,但主要的開放括號 【‘(’】 可用來使邊界成為排斥。 範圍搜尋可以使用 +Inf-Inf 作為其中一個邊界,轉換為單一關聯比較 (<、<=、>Inf、>=)。 無論指定的數值格式為何 (整數、固定點、浮點、無限),數字都會轉換為 64 位元浮點,以執行比較,進而降低精確度。

範例
@numeric-field:[0 10] // 0 <= <value> <= 10 @numeric-field:[(0 10] // 0 < <value> <= 10 @numeric-field:[0 (10] // 0 <= <value> < 10 @numeric-field:[(0 (10] // 0 < <value> < 10 @numeric-field:[1.5 (Inf] // 1.5 <= value

標籤比較

標籤比較運算子具有下列語法:

<tag-search> ::= '@' <tag-field-name> ':' '{' <tag> [ '|' <tag> ]* '}'

如果運算子中的任何標籤符合記錄標籤欄位中的任何標籤,則記錄會包含在結果集中。設計的欄位<tag-field-name>必須是類型 宣告的索引欄位TAG。標籤比較的範例包括:

@tag-field:{ atag } @tag-field: { tag1 | tag2 }

布林值組合

數值或標籤運算子的結果集可以使用布林邏輯組合:and/or. Parentheses can be used to group operators and/or變更評估順序。布林邏輯運算子的語法為:

<expression> ::= <phrase> | <phrase> '|' <expression> | '(' <expression> ')' <phrase> ::= <term> | <term> <phrase> <term> ::= <range-search> | <tag-search> | '*'

合併為片語的多個術語是「和」。與管道 (‘|’) 結合的多個片語是 “或”-ed。

向量索引支援兩種不同的搜尋方法:最近的鄰居和範圍。最近的鄰居搜尋會找出索引中最接近所提供 (參考) 向量的向量數字 K,這統稱為KNN「K」最近的鄰居。KNN 搜尋的語法為:

<vector-knn-search> ::= <expression> '=>[KNN' <k> '@' <vector-field-name> '$' <parameter-name> <modifiers> ']' <modifiers> ::= [ 'EF_RUNTIME' <integer> ] [ 'AS' <distance-field-name>]

向量KNN搜尋只會套用至滿足 的向量,<expression>其可以是上述定義運算子的任何組合:萬用字元、範圍搜尋、標籤搜尋和/或布林值組合。

  • <k> 是整數,指定要傳回的最近鄰居向量數目。

  • <vector-field-name> 必須指定類型 的宣告欄位VECTOR

  • <parameter-name> 欄位指定 FT.SEARCHFT.AGGREGATE命令PARAM資料表的其中一個項目。此參數是距離計算的參考向量值。向量的值會以小端點 IEEE754 二進位格式編碼為PARAM值 (與HASH向量欄位相同)

  • 對於類型 的向量索引HNSW,選用EF_RUNTIME子句可用來覆寫建立索引時所建立EF_RUNTIME參數的預設值。

  • 選用 為結果集<distance-field-name>提供欄位名稱,以包含參考向量和定位索引鍵之間的計算距離。

範圍搜尋會從參考向量找出指定距離 (半徑) 內的所有向量。範圍搜尋的語法為:

<vector-range-search> ::= ‘@’ <vector-field-name> ‘:’ ‘[’ ‘VECTOR_RANGE’ ( <radius> | ‘$’ <radius-parameter> ) $<reference-vector-parameter> ‘]’ [ ‘=’ ‘>’ ‘{’ <modifiers> ‘}’ ] <modifiers> ::= <modifier> | <modifiers>, <modifier> <modifer> ::= [ ‘$yield_distance_as’ ‘:’ <distance-field-name> ] [ ‘$epsilon’ ‘:’ <epsilon-value> ]

其中:

  • <vector-field-name>是要搜尋的向量欄位的名稱。

  • <radius> or $<radius-parameter> 是搜尋的數值距離限制。

  • $<reference-vector-parameter> 是包含參考向量的 參數名稱。向量的值會以小端點 754 二進位格式編碼為PARAM值 IEEE (與HASH向量欄位的編碼相同)

  • 選用項目為結果集<distance-field-name>提供欄位名稱,以包含參考向量和每個索引鍵之間的計算距離。

  • 選用 可<epsilon-value> 控制搜尋操作的界限,遠距離內的向量<radius> * (1.0 + <epsilon-value>) 會周遊尋找候選結果。預設值為 .01。

INFO 命令

向量搜尋透過幾個額外的統計資料和計數器區段來增強 Valkey 和 Redis OSSINFO命令。擷取區段的請求SEARCH將擷取下列所有區段:

search_memory 區段

名稱 描述
search_used_memory_bytes 所有搜尋資料結構中耗用的記憶體位元組數
search_used_memory_human 上述的人類可讀版本

search_index_stats 區段

名稱 描述
search_number_of_indexes 建立的索引數目
search_num_fulltext_indexes 所有索引中的非向量欄位數目
search_num_vector_indexes 所有索引中的向量欄位數目
search_num_hash_indexes HASH 類型索引鍵上的索引數目
search_num_json_indexes JSON 類型索引鍵上的索引數目
search_total_indexed_keys 所有索引中的索引鍵總數
search_total_indexed_vectors 所有索引中的向量總數
search_total_indexed_hash_keys 所有索引HASH中 類型的索引鍵總數
search_total_indexed_json_keys 所有索引JSON中 tytpe 的索引鍵總數
search_total_index_size 所有索引使用的位元組
search_total_fulltext_index_size 非向量索引結構使用的位元組
search_total_vector_index_size 向量索引結構使用的位元組
search_max_index_lag_ms 上次擷取批次更新期間的擷取延遲

search_ingestion 區段

名稱 描述
search_background_indexing_status 擷取狀態。 NO_ACTIVITY表示閒置。其他值表示擷取過程中有索引鍵。
search_ingestion_paused 除非重新啟動,否則這應一律為「否」。

search_backfill 區段

注意

本節中記錄的某些欄位只有在目前正在進行回填時才會顯示。

名稱 描述
search_num_active_backfills 目前回填活動的數量
search_backfills_paused 除非記憶體不足,否則這應一律為「否」。
search_current_backfill_progress_percentage 目前回填完成百分比 (0-100)

search_query 區段

名稱 描述
search_num_active_queries 目前進行中 FT.SEARCHFT.AGGREGATE命令的數量

向量搜尋安全性

ACL (存取控制清單) 命令和資料存取的安全機制都會擴展,以控制搜尋設施。ACL 完全支援個別搜尋命令的控制。提供了新的ACL類別 @search,並更新了許多現有類別 @read@fast@write、 等),以包含新的命令。搜尋命令不會修改金鑰資料,這表示會保留用於寫入存取的現有ACL機器。索引的存在不會修改 HASH和 JSON操作的存取規則;一般金鑰層級存取控制仍會套用至這些命令。

具有 索引的搜尋命令也會透過 控制其存取ACL。存取檢查是在整個索引層級執行,而不是在每個金鑰層級。這表示只有當使用者具有存取該索引之鍵空間字首清單中所有可能金鑰的許可時,才會授予使用者對索引的存取權。換句話說,索引的實際內容不會控制存取。相反地,它是用於安全檢查的字首清單所定義的索引理論內容。建立使用者對金鑰具有讀取和/或寫入存取權,但無法存取包含該金鑰的索引的情況很容易。請注意,建立或使用索引只需要對鍵空間的讀取存取權 – 不會考慮寫入存取是否存在。

如需ACLs搭配使用 MemoryDB 的詳細資訊,請參閱使用存取控制清單驗證使用者 (ACLs)