Cassandra 文件

版本

您正在查看預發行版本的說明文件。

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 設定較為簡單,並使用現有的資料庫參數進行調整,例如 cassandra.yaml。使用 SAI 時,沒有提交記錄會在開機期間接受寫入;SAI 不需要等到開機才能讀取資料庫設定。使用 SAI 時,架構/索引選項位於索引的元資料中,由原生資料庫架構管理處理。

如何使用 SAI 功能?

儲存附加索引具有完全基於 CQL 的查詢。這些功能在設計上故意簡單且易於使用。

在高層級中,SAI 索引為

  • 透過 CQL CREATE INDEX ... USING 'sai' 指令和 DROP INDEX 指令,針對每一個欄位建立和刪除。從 SAI 快速入門 開始。

  • 透過 nodetool 重新建置和備份。請參閱 nodetool

  • 透過 nodetool、CQL 虛擬表格、系統指標和 JMX 的組合進行監控。請參閱 監控 SAI 索引

在資料庫表格中的哪一個欄位我可以建立 SAI 索引?

在任何表格欄位上定義每個 SAI 索引。例外:當分割鍵僅包含一個欄位時,不需要根據分割鍵定義 SAI 索引;在這種情況下,SAI 會發出 無效查詢 訊息。

您也可以使用表格複合分割鍵中的單一欄位定義 SAI 索引。複合分割鍵表示分割是根據兩個或多個欄位。在這種情況下,使用 SAI 索引時,您只需指定構成複合分割鍵的其中一個欄位。

對於集合映射,您可以在同一個欄位上定義一個或多個 SAI 索引,並指定 keysvaluesentries 作為映射類型。SAI 也支援 listset 集合。

在具有 SAI 索引的資料庫表格的 CQL 查詢中,CONTAINS 子句獲得支援,且特定於

  • 具有 keysvaluesentries 的 SAI 集合映射

  • 具有 listset 類型的 SAI 集合

當我在同一個欄位上 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 索引使用的寫入和讀取路徑是什麼?

SAI 在寫入時會建立 Memtables 和 SSTables 的索引,並在讀取時解決這些索引之間的差異。請參閱 SAI 寫入路徑和讀取路徑

SAI 支援哪些磁碟索引格式?

SAI 支援兩種磁碟索引格式,針對下列項目進行最佳化

  • 字串上的等式和非精確比對。

    • 字串會使用 trie 資料結構和張貼清單(術語/列對)清單在磁碟上建立索引。trie 對堆疊友善,提供術語的字串字首壓縮,且可以比對任何可以表示為確定有限自動機的查詢。此功能會將磁碟空間使用量降到最低,並支援簡單的權杖略過。

  • 數字和非文字類型上的等式和範圍查詢。

    • 數字值和其他非文字 CQL 類型(timestampdateUUID)會使用 k 維度樹 在磁碟上建立索引,這是一個平衡的結構,可提供跨一個或多個維度的快速查詢,並壓縮值和張貼清單。

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

  • 從 Cassandra ??? 開始,INET 支援 IPv4 和 IPv6。

  • 從 Cassandra ??? 開始,支援 DECIMALVARINT

  • SAI 也支援集合 — 請參閱 下一個常見問題

SAI 是否支援集合欄位的索引?

是 — SAI 支援 maplistset 類型的集合。請參閱下列主題

在具有 SAI 索引的資料庫表格的 CQL 查詢中,CONTAINS 子句獲得支援,且特定於

  • 具有 keysvaluesentries 的 SAI 集合映射

  • 具有 listset 類型的 SAI 集合

支援的查詢運算子有哪些?

針對具有 SAI 索引的表格進行查詢

  • 數字:=<>>=ANDORIN

  • 字串:=CONTAINSCONTAINS KEYANDORIN

不支援的查詢運算子為

  • 字串或數字: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 集合對應、清單和集合的 CONTAINS 子句查詢範例,請務必參閱 具有金鑰、值和項目的 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 有 ascii 選項。預設為 false。設定為 true 時,SAI 會將不在基本拉丁語 Unicode 區塊(前 127 個 ASCII 字元)中的字母、數字和符號字元轉換為 ASCII 等效字元(如果存在)。例如,此選項會將 à 變更為 a

請參閱 建立自訂索引,以及 SAI 快速入門 主題中的範例。

SAI 是否支援複合索引,也就是針對多個欄位建立單一索引?

否。SAI 索引與欄位之間是 1 對 1 的對應。不過,您可以在特定表格中的每個欄位建立個別索引。此外,SAI 可以於單一讀取查詢中使用多個已定義索引。

我如何檢視 SAI 記憶體使用量指標?

SAI 記憶體使用量分為 JVM 堆積和區塊快取。堆積儲存記憶體表索引,而區塊快取儲存最近存取的磁碟索引元件以及其他 SSTable 元件。SAI 提供堆積和區塊快取的指標。對於每個索引,SAI 也提供指標來判斷磁碟資料結構使用的記憶體位元組大小,以及磁碟使用量。請參閱 索引群組指標。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,以及靜態欄位來包含每個客戶的 addressphone_numberdate_of_birth。針對類似下列的查詢

SELECT * from transaction_by_customer where customer_id = 'xyz123';

如果存在 100,000 筆 transaction_by_customer 列,由於您已定義這三個靜態欄位,因此此查詢會針對使用磁碟空間顯著較少的表格執行,相較於在每列中插入每個客戶值(addressphone_numberdate_of_birth)的寫入環境。

SAI 提供基於靜態欄建立索引的選項和優點,同時也能達到節省表格空間的效益。

對於已編制索引的字串,SAI 如何處理欄資料中的 Unicode 字元?

當您根據字串欄建立 SAI 索引時,如果要讓 SAI 對欄資料執行 Unicode 正規化,請將 normalize 選項設為 true。SAI 支援 Unicode 正規化形式 C (NFC)。當設為 true 時,SAI 會將給定 Unicode 字元的不同版本正規化為單一版本,並保留索引中的所有標記和符號。例如,SAI 會將字元 Å (U+212B) 變更為 Å (U+00C5)。請參閱 建立自訂索引

索引的欄位名稱可以使用特殊字元嗎?

SAI 會驗證定義索引的欄位名稱。SAI 僅允許字母數字字元和底線。如果您嘗試在包含其他字元的欄位名稱上定義索引,SAI 會傳回 InvalidRequestException,且不會建立索引。

SAI 支援哪種分區器?

SAI 僅支援 Murmur3Partitioner