SAI 常見問題
使用此常見問題解答尋找常見問題的答案並取得儲存附加索引 (SAI) 的協助。
什麼是 SAI?
儲存附加索引 (SAI) 是 Cassandra 資料庫的高擴充性、全球分佈式索引。SAI 結合了
-
開放原始碼 SSTable 附加次要索引 (SASI) 的儲存附加架構
-
多個高度最佳化的磁碟索引結構
支援哪些資料庫?
目前唯一支援的資料庫是 Cassandra 5.0。
在建立資料庫、一個鍵空間和一個或多個表格後,使用 CREATE INDEX ... USING 'sai'
定義表格上的其中一個或多個 SAI 索引。對於 Cassandra 資料庫,請使用 cqlsh
。兩個都提供相同的 CREATE INDEX ... USING 'sai'
命令。請參閱 SAI 快速入門。
我應該在 SAI 中使用哪些組態設定?
與大多數索引環境相比,SAI 組態和相關設定簡單許多。重點
-
增加
--XX:MaxDirectMemorySize
,為作業系統和其他記憶體中結構保留約 15-20% 的記憶體。 -
在 cassandra.yaml 中,將
file_cache_size_in_mb
明確設定為該值的 75%。 -
大量混合讀取/寫入工作負載可能想要
-
減少
range_request_timeout_in_ms
-
增加
write_request_timeout_in_ms
-
-
如果
memtable_flush_writers
值設定得太低,寫入可能會暫停。如果在您的環境中發生這種情況,請增加memtable_flush_writers
。
除了記憶體之外,SAI 使用與 Cassandra 相同的可調整參數,例如壓縮處理量和壓縮執行器。這對寫入效能很重要。對於讀取效能,再次強調,最大化使用區塊快取將使 SAI 讀取受益,因為所有磁碟索引元件都是透過此機制存取的。請參閱設定 SAI 索引。
SAI 解決了哪些運算挑戰?
開發人員經常問:「我如何查詢 Apache Cassandra 分割鍵以外的其他欄位?」
SAI 實作基於表格欄位的有效率索引,例如複合分割鍵的一部分。在 SAI 之前,您可以索引叢集鍵,但無法索引複合分割的一部分。SAI 的開發靈感來自 SASI,目標是透過建立次要索引來達成有效率且更簡單的篩選。
SAI 也讓資料建模更簡單,因為您不需要建立自訂表格來迎合特定的查詢模式。您可以建立最適合您的表格,只寫入該表格,並以任何您想要的方式查詢它。
使用 SAI 的優點是什麼?
SAI 可以定義同一個資料庫表格上的多個索引。每個 SAI 索引可以基於表格中的任何欄位。例外:當分割鍵只包含一個欄位時,不需要定義基於分割鍵的 SAI 索引;在這種情況下,SAI 會發出無效查詢
訊息。您也可以使用表格複合分割鍵中的單一欄位來定義 SAI 索引。複合分割鍵表示分割基於兩個或以上的欄位。在這種情況下,使用 SAI 索引,您只需指定組成複合分割鍵的其中一個欄位。
對於開發人員來說,SAI 消除了幾個先前的痛點,包括需要複製非正規化資料來查詢非 PrimaryKey 欄位。
對於操作員來說,SAI 有幾個優點,包括索引使用的磁碟空間顯著減少;故障點較少;由於 SAI 的架構簡化,因此停機時間較短;以及需要保護的資料副本較少。
SAI 是完整的搜尋解決方案嗎?
SAI 不是企業搜尋引擎。雖然它提供了一些相同的功能,但 SAI 並非文字搜尋的完整替代方案。SAI 的核心是一個過濾引擎,簡化了資料建模和客戶端應用程式,否則這些應用程式將嚴重依賴維護多個特定於查詢的表格。
SAI 和文字搜尋的架構管理有何不同?
SAI 是索引,不是搜尋引擎。與文字搜尋不同,SAI 不需要架構管理。SAI 設定較為簡單,並使用現有的資料庫參數進行調整,例如 cassandra.yaml。使用 SAI 時,沒有提交記錄會在開機期間接受寫入;SAI 不需要等到開機才能讀取資料庫設定。使用 SAI 時,架構/索引選項位於索引的元資料中,由原生資料庫架構管理處理。
在資料庫表格中的哪一個欄位我可以建立 SAI 索引?
在任何表格欄位上定義每個 SAI 索引。例外:當分割鍵僅包含一個欄位時,不需要根據分割鍵定義 SAI 索引;在這種情況下,SAI 會發出 無效查詢
訊息。
您也可以使用表格複合分割鍵中的單一欄位定義 SAI 索引。複合分割鍵表示分割是根據兩個或多個欄位。在這種情況下,使用 SAI 索引時,您只需指定構成複合分割鍵的其中一個欄位。
對於集合映射,您可以在同一個欄位上定義一個或多個 SAI 索引,並指定 keys
、values
和 entries
作為映射類型。SAI 也支援 list
和 set
集合。
在具有 SAI 索引的資料庫表格的 CQL 查詢中,
|
當我在同一個欄位上 DROP
並重新建立 SAI 索引時,這會阻擋任何讀取作業嗎?是否有方法可以檢查索引狀態?
當您 DROP
/ 重新建立 SAI 索引時,您不會被阻擋輸入不使用索引的查詢。但是,您無法使用該 SAI 索引(基於同一個欄位),直到它建置完成且可查詢為止。若要判斷特定索引的目前狀態,請查詢 system_views.indexes
虛擬表格。範例
SELECT is_queryable,is_building FROM system_views.indexes WHERE keyspace_name='keyspace'
AND table_name='table' AND index_name='index';
請參閱 虛擬表格 和 SAI 索引和 SSTable 的虛擬表格。
SAI 索引使用的寫入和讀取路徑是什麼?
SAI 在寫入時會建立 Memtables 和 SSTables 的索引,並在讀取時解決這些索引之間的差異。請參閱 SAI 寫入路徑和讀取路徑。
SAI 索引的磁碟空間使用量開銷是多少?
與其他原生或附加式 Cassandra 索引解決方案相比,SAI 需要大幅降低的磁碟使用量。與未建立索引的資料相比,SAI 產生的額外磁碟使用量為 20-35%。SAI 磁碟使用量在很大程度上取決於基礎資料模型和建立索引的欄位數目。
SAI 建立索引支援哪些欄位資料類型?
支援的類型為:ASCII, BIGINT, DATE, DECIMAL, DOUBLE, FLOAT, INET, INT, SMALLINT, TEXT, TIME, TIMESTAMP, TIMEUUID, TINYINT, UUID, VARCHAR, VARINT
。
|
SAI 是否支援集合欄位的索引?
是 — SAI 支援 map
、list
和 set
類型的集合。請參閱下列主題
在具有 SAI 索引的資料庫表格的 CQL 查詢中,
|
支援的查詢運算子有哪些?
針對具有 SAI 索引的表格進行查詢
-
數字:
=
、<
、>
、⇐
、>=
、AND
、OR
、IN
-
字串:
=
、CONTAINS
、CONTAINS KEY
、AND
、OR
、IN
不支援的查詢運算子為
-
字串或數字:
LIKE
範例
SELECT * FROM cycling.cyclist_semi_pro WHERE registration > '2010-01-01' AND registration < '2015-12-31' LIMIT 10;
SELECT * FROM audit WHERE text_map CONTAINS KEY 'Giovani';
如要取得利用 SAI 集合對應、清單和集合的 |
針對 SAI 的 CREATE INDEX
指令,有哪些選項可用?
使用 WITH OPTIONS
子句來指出 SAI 應如何處理索引中的大小寫敏感性和特殊字元。例如,針對字串欄位 lastname
CREATE INDEX lastname_sai_idx ON cycling.cyclist_semi_pro (lastname)
USING 'sai' WITH OPTIONS =
{'case_sensitive': 'false', 'normalize': 'true', 'ascii': 'true'};
SAI 是否支援複合索引,也就是針對多個欄位建立單一索引?
否。SAI 索引與欄位之間是 1 對 1 的對應。不過,您可以在特定表格中的每個欄位建立個別索引。此外,SAI 可以於單一讀取查詢中使用多個已定義索引。
將 SAI 欄位新增到讀取查詢的效能影響是什麼?我可以新增多少個 AND
子句?
單一查詢中可使用的索引欄位數量沒有限制。cassandra.yaml 中的 sai_indexes_per_table_failure_threshold
設定控制單一資料表中允許的最大 SAI 索引數量(預設為 10)。然而,針對多個索引欄位進行查詢會產生成本,這與處理的索引元件數量增加有關。在查詢中評估多個索引欄位時,SAI 會執行工作流程(1:Traverse。2:Merged。3:Intersect),最終會合併來自多個記憶體表和 SSTable 的資料。
在查詢中,AND 查詢將處理最多兩個 SAI 索引;如果查詢使用超過兩個 SAI 索引,此情況將導致 SAI 對剩餘子句執行後續篩選。 |
有關相關資訊,請參閱 比對串流和後續篩選 範例。
SAI 寫入作業是異步的,還是 SAI 會在向使用者確認寫入之前等待?
SAI 寫入路徑實際上非常簡單。索引與資料共存,同時存在於記憶體表和 SSTable 中。當寫入已確認給客戶端時,資料已編入索引。這是一個同步程序。當記憶體表被清除時,索引也會被清除。請參閱 SAI 寫入路徑和讀取路徑。
磁碟索引元件會細分為每個 SSTable 索引檔案和每個欄位索引檔案。欄位索引不會儲存主鍵或令牌;相反地,它們會儲存可壓縮的列 ID。每個 SSTable 索引檔案會將欄位索引中的列 ID 連結到其備份 SSTable。此 SAI 設計允許單一 SSTable 中的所有欄位索引共用每個 SSTable 索引檔案,這進一步有助於減少磁碟空間使用量。
關於 SAI 索引的欄位基數有哪些準則?
欄位 基數 會影響複製品之間範圍查詢的讀取效能。符合高基數欄位(例如信用卡號碼)值的列數目較有可能孤立在極少數節點(甚至孤立至一個節點),而符合低基數欄位值的列數目較有可能存在於許多節點。如果查詢未指定分割鍵,Cassandra 協調器會掃描令牌環並依端點(節點)分組令牌範圍。然後,協調器會同時執行所有參與端點的讀取命令。在索引欄位具有極高基數的最糟情況下,可能需要進行完整叢集掃描才能找到符合條件的項目。對於低基數欄位,請注意,如果您的 LIMIT
高於目標欄位的數值,Cassandra 必須再次搜尋所有複製品,才能判定無法滿足 LIMIT
。在此情況下,Cassandra 只會傳回符合條件的結果數目。
SAI 在什麼情況下套用後置篩選?
SAI 會在許多情況下套用後置篩選。例如,考慮一個簡單的表格,以及僅在兩個非 PK 欄位其中一個上建立的 SAI 索引
CREATE KEYSPACE test WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1};
CREATE TABLE test.mytable (id int PRIMARY KEY,
col1 text,
col2 timestamp);
CREATE CUSTOM INDEX mytable_col1_idx ON test.mytable (col1) USING 'StorageAttachedIndex';
針對以下類型的查詢
SELECT * FROM test.mytable WHERE col1 = 'hello world' and col2 < toTimestamp(now()) ALLOW FILTERING;
對於此查詢,Cassandra 會先依索引欄位 (col1
) 縮小搜尋範圍,然後對 col2
套用後置篩選。(請謹慎使用 ALLOW FILTERING
子句。)在此情況下,不需要其他複製品往返;會在複製品本身上執行 col2
的後置篩選。
後置篩選會派上用場的另一種情況是,當建構包含兩個以上 SAI 索引的查詢時。請參閱這個 相關常見問題,了解有關 AND
查詢的資訊。
是否可以根據 靜態欄位 建立 SAI 索引?
可以。例如,考慮一個 transaction_by_customer
表格,其中您有一個主鍵 customer_id
,以及靜態欄位來包含每個客戶的 address
、phone_number
和 date_of_birth
。針對類似下列的查詢
SELECT * from transaction_by_customer where customer_id = 'xyz123';
如果存在 100,000 筆 transaction_by_customer
列,由於您已定義這三個靜態欄位,因此此查詢會針對使用磁碟空間顯著較少的表格執行,相較於在每列中插入每個客戶值(address
、phone_number
、date_of_birth
)的寫入環境。
SAI 提供基於靜態欄建立索引的選項和優點,同時也能達到節省表格空間的效益。 |
對於已編制索引的字串,SAI 如何處理欄資料中的 Unicode 字元?
當您根據字串欄建立 SAI 索引時,如果要讓 SAI 對欄資料執行 Unicode 正規化,請將 normalize
選項設為 true
。SAI 支援 Unicode 正規化形式 C (NFC)。當設為 true
時,SAI 會將給定 Unicode 字元的不同版本正規化為單一版本,並保留索引中的所有標記和符號。例如,SAI 會將字元 Å (U+212B) 變更為 Å (U+00C5)。請參閱 建立自訂索引。