Cassandra 文件

版本

您正在檢視預發行版本的說明文件。

拒絕列出分區

由於存取模式和資料建模,有時會有特定的分區「熱門」,並可能導致 Cassandra 群集不穩定。當資料模型在單一分區上包含許多更新或插入作業時,通常會發生這種情況,導致分區隨著時間推移而變得很龐大,進而使其讀取和維護成本很高。

Cassandra 支援「拒絕列出」這些有問題的分區,以便當客戶端發出點讀取(指定分區金鑰的 SELECT 陳述式)或範圍讀取(SELECT * 等,會提取資料範圍)與封鎖的分區金鑰相交時,查詢會立即以 InvalidQueryException 拒絕。

如何拒絕列出分區金鑰

system_distributed.denylisted_partitions 表格可用於拒絕列出分區。有幾種方式可以與這些資料互動並變更這些資料。首先:直接透過 CQL,透過插入具有下列詳細資料的記錄

  • Keyspace 名稱 (ks_name)

  • 表格名稱 (table_name)

  • 分區金鑰 (partition_key)

分區金鑰格式需要與 nodetool getendpoints 所需的格式相同。

以下是針對主鍵 Id 上不同資料類型,在 keyspace ks 和表格 table1 中取消拒絕列示分區金鑰的幾個範例

  • Id 是簡單類型 - INSERT INTO system_distributed.denylisted_partitions (ks_name, table_name, partition_key) VALUES ('ks','table1','1');

  • Id 是 blob - INSERT INTO system_distributed.denylisted_partitions (ks_name, table_name, partition_key) VALUES ('ks','table1','12345f');

  • Id 有冒號 - INSERT INTO system_distributed.denylisted_partitions (ks_name, table_name, partition_key) VALUES ('ks','table1','1\:2');

在複合欄位分區金鑰 (Key1, Key2) 的情況下

  • INSERT INTO system_distributed.denylisted_partitions (ks_name, table_name, partition_key) VALUES ('ks', 'table1', 'k11:k21')

特殊考量

拒絕清單具有以下特性,您希望盡可能讓快取 (請參閱下方) 和 CQL 資料在複本組上保持接近,因此您不希望叢集中的不同節點拒絕或允許不同的金鑰。為了最佳達成此目標,拒絕清單變更 (新增或刪除) 的工作流程應始終如下

JMX 路徑 (建議用於單一變更)

  1. 使用想要的 key 呼叫 denylistKey() 的 JMX 勾子

  2. 使用 isKeyDenylisted() 再次檢查快取已重新載入

  3. 檢查有關無法辨識的 keyspace/table 組合、限制或一致性層級的警告。如果您收到有關節點已停用且未命中拒絕清單 CL 的訊息,請復原已停用的節點,然後使用 loadPartitionDenylist() 在每個節點上觸發快取重新載入

CQL 路徑 (建議用於大量變更)

  1. 透過 CQL 變更拒絕列示的分區清單

  2. 透過 JMX loadPartitionDenylist() 在每個節點上觸發拒絕清單快取重新載入 (請參閱下方)

  3. 檢查有關拒絕清單更新可用性不足的警告。如果節點已停用,請復原它們,然後前往 2。

由於已知無法使用的範圍切片在啟動時會導致警報風暴,因此除非拒絕清單快取可以在 cassandra.yaml - denylist_consistency_level 中達成已設定的一致性層級,否則拒絕清單快取不會在節點啟動時載入。不過,無論可用節點數量為何,呼叫 loadPartitionDenylist 的 JMX 都會載入快取。這讓操作員可以控制在叢集狀態劣化期間是否拒絕列示。

已拒絕列示的分區快取

Cassandra 內部維護一個從 system_distributed.denylisted_partitions 載入的拒絕分區的堆內快取。資料表的值將會在 conf/cassandra.yaml 檔案中指定的 denylist_refresh 中自動重新填入,預設為 600s,或 10 分鐘。無效的記錄(未知的鍵空間、資料表或金鑰)將會被忽略,且不會在載入時快取。

快取可以用以下方式重新整理

  • 在 Cassandra 節點啟動期間

  • 透過自動堆內快取重新整理機制。注意:這將會在查詢後非同步發生,在 denylist_refresh 時間命中之後。

  • 透過 JMX 指令:loadPartitionDenylistthe org.apache.cassandra.service. StorageProxyMBean 呼叫點。

快取大小受以下兩個設定屬性限制

  • denylist_max_keys_per_table

  • denylist_max_keys_total

在快取載入時,如果資料表超過 denylist_max_keys_per_table 中允許的值(預設為 1000),將會在記錄中印出警告,且其餘的金鑰將不會快取。類似地,如果超過允許的總大小,後續的 ks_name + table_name 組合(以分群/字順排序)也會被略過,且會在伺服器記錄中記錄警告。

考量到 1) 變更、2) 重新載入快取的必要工作流程,自動重新載入屬性似乎是多餘的。它的存在是為了確保,如果操作員錯誤地拒絕或取消拒絕金鑰,但忘記重新載入快取,該意圖將會在下次快取重新載入時擷取。

JMX 介面

指令 效果

loadPartitionDenylist()

從 CQL 資料表重新載入快取的拒絕清單

getPartitionDenylistLoadAttempts()

取得快取重新載入嘗試次數

getPartitionDenylistLoadSuccesses()

取得快取重新載入成功的次數

setEnablePartitionDenylist(boolean enabled)

啟用或停用分區拒絕清單功能

setEnableDenylistWrites(boolean enabled)

啟用或停用寫入拒絕清單功能

setEnableDenylistReads(boolean enabled)

啟用或停用讀取拒絕清單功能

setEnableDenylistRangeReads(boolean enabled)

啟用或停用範圍讀取拒絕清單功能

denylistKey(String keyspace, String table, String partitionKeyAsString)

將特定的鍵空間、表格和分區金鑰組合新增至拒絕清單

removeDenylistKey(String keyspace, String cf, String partitionKeyAsString)

從拒絕清單中移除特定的鍵空間、表格和分區金鑰組合

setDenylistMaxKeysPerTable(int value)

限制拒絕清單中每個表格允許的金鑰數量

setDenylistMaxKeysTotal(int value)

限制系統中允許拒絕清單金鑰的總數量

isKeyDenylisted(String keyspace, String table, String partitionKeyAsString)

指出 keyspace.table 是否拒絕輸入的分區金鑰