向量搜尋概觀 - Amazon MemoryDB

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

向量搜尋概觀

向量搜尋是建立在索引的建立、維護和使用之上。每個向量搜索操作指定一個索引和它的操作被局限於該索引,也就是說,對一個索引的操作不受任何其他索引的操作的影響。除了創建和銷毀索引的操作之外,任何數量的操作都可以在任何時間對任何索引發出,這意味著在集群級別,針對多個索引的多個操作可能正在同時進行。

單個索引是存在於唯一命名空間中的命名對象,它與其他 Redis 的OSS命名空間分開:鍵,函數等。每個索引在概念上都與傳統的資料庫表格相似,因為它的結構有兩個維度:欄和資料列。在表中的每一行對應於一個 Redis OSS 鍵。索引中的每一欄對應於該索引鍵的一個成員或部分。在本文檔中,術語鍵,行和記錄是相同的,並可以互換使用。同樣的術語列,字段,路徑和成員基本上是相同的,也可以互換使用。

沒有特殊命令可以添加,刪除或修改索引數據。而是修改索引中索引鍵的現有HASHJSON命令也會自動更新索引。

索引和 Redis 的密鑰空間 OSS

索引被構造和維護在 Redis 的OSS密鑰空間的子集。多個索引可以不受限制地選擇 Redis OSS 密鑰空間的脫節或重疊的子集。每個索引的索引鍵空間由建立索引時提供的索引鍵前置詞清單定義。前綴列表是可選的,如果省略,整個 Redis 的OSS密鑰空間將是該索引的一部分。索引也被鍵入,它們只涵蓋具有匹配類型的鍵。目前,僅支援JSON和HASH索引。索HASH引只會對其前置詞清單所涵蓋的索引HASH鍵進行索引,同樣的索JSON引只會對其前置詞清單所涵蓋的索引JSON鍵建立索引。索引鍵空間前置詞清單中沒有指定類型的索引鍵會被忽略,並且不會影響搜尋作業。

當HASH或JSON命令修改位於索引鍵空間內的索引鍵時,索引會更新。這個過程涉及為每個索引提取聲明的字段,並使用新值更新索引。更新過程是在後台線程中完成的,這意味著索引僅最終與其密鑰空間內容一致。因此,密鑰的插入或更新將不會在短時間內在搜索結果中可見。在繁重的系統負載和/或數據的重度突變期間,可見性延遲可能會變得更長。

索引的創建是多步驟的過程。第一步是執行 FT。 CREATE定義索引的命令。成功執行創建會自動啟動第二個步驟-回填。回填處理序會在背景執行緒中執行,並掃描 Redis 金OSS鑰空間,尋找新索引的前置詞清單中的金鑰。找到的每個索引鍵都會新增至索引。最終掃描整個密鑰空間,完成索引創建過程。請注意,當回填處理序正在執行時,會允許對索引鍵進行突變,沒有任何限制,而且索引回填程序將不會完成,直到所有索引鍵都已正確編製索引。不允許在索引進行回填時嘗試的查詢操作,並且會因錯誤而終止。回填過程的完成可以從該索引的FT.INFO命令的輸出中確定(「backfill_status」)。

索引欄位類型

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

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

  • 標籤欄位包含編碼為單一 UTF -8 字串的零個或多個標籤值。使用分隔符號字元 (預設值為逗號,但可以覆寫),並移除前置和尾端空格,將字串剖析為標籤值。單一標籤欄位中可包含任何數目的標籤值。標籤欄位可用於透過區分大小寫或不區分大小寫的比較來篩選標籤值對等的查詢。

  • 文字欄位包含不需要 UTF -8 相容的位元組。文字欄位可用於使用應用程式有意義的值來裝飾查詢結果。例如 a URL 或文檔的內容等

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

向量索引演算法

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

  • 平面 (Flat) — Flat 演算法是對索引中每個向量進行的蠻力線性處理,在距離計算的精確度範圍內產生精確的答案。由於索引的線性處理,對於大型索引而言,此演算法的執行時間可能會非常高。

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

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

像這樣的向量搜索算法HNSW可能無法有效地處理先前插入的向量的刪除或覆蓋。使用這些作業可能會導致過多的索引記憶體耗用量和/或回復品質降低。重新索引是恢復最佳內存使用率和/或調用的一種方法。

向量搜尋查詢運算式

英尺. SEARCH英尺. 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>必須是以 type 宣告之索引的欄位TAG。標籤比較的範例如下:

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

布林組合

數值或標籤運算子的結果集可以使用布林邏輯:和/或結合。括號可用於將運算子分組和/或變更評估順序。布爾邏輯運算符的語法是:

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

多個術語合併成一個短語是「和」-ed。與管道('|')相結合的多個短語是「或」-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>field 指定FT.SEARCHFT.AGGREGATE命令PARAM表的其中一個項目。此參數是距離計算的參考向量值。向量的值以小端 IEEE 754 二進位格式編碼為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> 是包含參照向量的參數名稱。向量的值以小端 IEEE 754 二進位格式編碼為PARAM值 (與向量欄位的編碼相同) HASH

  • 可選項為結果集<distance-field-name>提供了一個字段名稱,以包含引用向量和每個鍵之間計算出的距離。

  • 可選<epsilon-value> 控制搜索操作的邊界,遍歷距離內的向量尋找候選結<radius> * (1.0 + <epsilon-value>) 果。預設值為 .01。

INFO 命令

向量搜尋可增加 Redis OSS INFO命令,其中包含數個額外的統計資料和計數器區段。擷取區段的請求SEARCH將擷取下列所有區段:

search_memory 區段

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

search_index_stats 區段

名稱 描述
索引的搜尋編號 已建立索引的數目
搜索全文索引 所有索引中非向量欄位的數目
搜索向量索引 所有索引中向量欄位的數目
搜索哈希索引 類型索引HASH鍵上的索引數
搜索索引 類型索引JSON鍵上的索引數
搜尋總索引鍵 所有索引中的索引鍵總數
搜索總索引向量 所有索引中的向量總數
搜索總索引哈希鍵 所有索引HASH中類型的索引鍵總數
搜尋總索引鍵 所有索引中 tytpe JSON 鍵的總數
搜尋總索引大小 所有索引使用的字節
搜索總計全文索引大小 非向量索引結構使用的字節
搜索總向量索引大小 向量索引結構使用的位元組
搜索 _ 最大值 _ 指數 _ 毫秒 上次擷取批次更新期間的擷取延遲

search_ingestion 區段

名稱 描述
搜索背景索引 _ 狀態 擷取狀態。 NO_ACTIVITY意味著閒置。其他值表示在攝取過程中有關鍵字。
搜尋 (_I) 已暫停 除了重新啟動時,這應該始終是「否」。

search_backfill 區段

注意

只有當回填目前正在進行中時,才能看見本節中所述的某些欄位。

名稱 描述
搜尋作用中 _ 回填 目前回填活動的數目
搜索 _ 反向填充(已暫停) 除了內存不足時,這應該永遠是「否」。
搜索當前 _ 反填 _ 進度 _ 百分比 目前回填的完成百分比 (0-100)

search_query 區段

名稱 描述
搜尋作用中查詢 目前正在進行的FT.AGGREGATE指令數FT.SEARCH和指令

向量搜尋安全

Redis OSS ACL (存取控制清單) 命令和資料存取的安全性機制會延伸以控制搜尋功能。ACL完全支援個別搜尋指令的控制。提供了一個新ACL品類@search,並更新了許多現有品類 (@fast@read@write、、等等) 以包括新指令。搜尋指令不會修改關鍵資料,這表示會保留用於寫入存取權的現有ACL機制。存取HASH和JSON作業的存取規則不會因為存在索引而修改;一般金鑰層級存取控制仍會套用至這些指令。

帶有索引的搜索命令也可以通過 Redis OSS ACL 控制其訪問權限。存取檢查是在整個索引層級執行,而不是在每個索引鍵層級執行。這表示只有當使用者有權存取該索引的 keyspace 前置詞清單中所有可能的金鑰時,才會將索引存取權授予使用者。換句話說,索引的實際內容不會控制存取。相反,它是由用於安全性檢查的前綴列表定義的索引的理論內容。建立使用者對金鑰具有讀取和/或寫入權限,但無法存取包含該金鑰的索引的情況很容易。請注意,只需要對密鑰空間的讀取訪問權限來創建或使用索引-不考慮是否存在寫入訪問。

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