本文介紹如何使用云數據庫ClickHouse的資源隊列增強功能。

背景信息

ClickHouse官方開源版目前沒有資源隊列的功能設計,20.8及以上版本的云數據庫ClickHouse社區兼容版集群對于資源限制的用法,詳情請參見Restrictions on Query Complexity

本文介紹的資源隊列是云數據庫ClickHouse的增強功能,并且只適配于20.3版本的云數據庫ClickHouse社區兼容版集群。由于ClickHouse官方開源版存在用戶級別內存隔離機制,資源隊列功能在新購集群時默認不開啟。

使用限制

云數據庫ClickHouse云原生版不支持資源隊列增強功能。

資源隊列定義

創建資源隊列語法:

-- 創建資源隊列定義
CREATE RESOURCE QUEUE [IF NOT EXISTS | OR REPLACE] name [ON CLUSTER cluster]
  * {[SET] MEMORY = {number}
  * [, CONCURRENCY = {number}]
  * [, PRIORITY = { LOWEST | LOW | NORMAL | HIGH | HIGHEST }]
  * [, ISOLATE = {number}]
    * }
  * [TO {role [,...] | ALL | ALL EXCEPT role [,...]}]

-- 更改指定資源隊列定義
ALTER RESOURCE QUEUE [IF NOT EXISTS | OR REPLACE] name [ON CLUSTER cluster]
  * {[SET] MEMORY = {number}
  * [, CONCURRENCY = {number}]
  * [, PRIORITY = { LOWEST | LOW | NORMAL | HIGH | HIGHEST }]
  * [, ISOLATE = {number}]
    * }
  * [TO {role [,...] | ALL | ALL EXCEPT role [,...]}]  

-- 查看指定資源隊列定義
SHOW CREATE resource queue name

-- 查看當前用戶使用的資源隊列定義
SHOW CREATE resource queue current

-- 刪除指定資源隊列定義
DROP resource queue if exists name
定義參數說明:
  • memory:聲明創建的資源隊列內存池大小,如果節點的總內存被已有的資源隊列分配完,則創建會失敗。
  • concurrency:聲明創建的資源隊列中查詢的并發數限制,默認值為20,并發限制會對用戶發起的查詢進行阻塞排隊,對系統發起的子查詢不會阻塞但是會計入到當前并發統計中。即并發限制為20的資源隊列當前同時在跑的系統子查詢可以達到25個,但此時用戶發起的查詢全部會被阻塞,直到系統子查詢數降低到20以下。
  • priority:聲明創建的資源隊列優先級,包含cpu調度優先級和內存搶占優先級。
  • isolate:聲明創建的資源隊列內存隔離級別。
    • 默認值是0,表示沒有隔離,當目標資源隊列中的內存使用率處于低水位時,更高優先級的資源隊列在內存不夠用時可以臨時搶占目標資源隊列的內存。
    • 設定為1時,表示該資源隊列有軟隔離,不可被高優先級隊列搶占內存。
    • 設定為2時,表示該資源隊列絕對隔離,不可被搶占內存,同時也不會去搶占低優先級隊列的內存。
  • role:通過To role [,...]聲明,把目標資源隊列綁定到多個用戶上,對應用戶的查詢默認會進入到目標資源隊列中。當同時有多個資源隊列綁定同一用戶時,系統會隨機選擇一個最高優先級的資源隊列執行查詢。
配置參數說明:
  • target_resource_queue:聲明目標查詢強制路由到指定資源隊列中,也可以在用戶的profile文件中配置強制用戶對應的查詢強制路由。
  • resource_queue_max_wait_ms:聲明查詢在資源隊列中因為并發限制阻塞排隊的最長等待時間,默認10s。

示例:

CREATE RESOURCE QUEUE IF NOT EXISTS test_queue ON CLUSTER cluster SET 
  MEMORY = 1073741824, CONCURRENCY = 20, ISOLATE = 0, PRIORITY = NORMAL 
    TO default;

CREATE RESOURCE QUEUE IF NOT EXISTS anonymous_queue ON CLUSTER cluster SET 
  MEMORY = 1073741824, CONCURRENCY = 20, ISOLATE = 1, PRIORITY = LOW;

SHOW CREATE resource queue test_queue;

SHOW CREATE resource queue current;

SELECT count (distinct intDiv(number, 10)) FROM numbers(100000) settings target_resource_queue='anonymous_queue';

DROP resource queue if exists test_queue;

DROP resource queue if exists anonymous_queue;

資源隊列狀態查詢

List當前所有的資源隊列定義:
show resource queues;

返回結果說明:

名稱類型說明
nameString資源隊列名。
concurrencyUInt32資源隊列的并發限制。
memoryUInt64資源隊列的內存池大小。單位:Byte。
isolateUInt8資源隊列的隔離級別。
priorityEnum8(枚舉)資源隊列的優先級別。
rolesArray<String>資源隊列綁定的所有相關用戶。
List指定資源隊列的查詢使用狀態:
show resource queue stat [CURRENT | ALL];

返回結果說明:

名稱類型說明
nameString資源隊列名。
running_queryUInt32資源隊列中正在執行的查詢數量。
waiting_queryUInt32資源隊列中正在等待執行的查詢數量。
grabbing_queryUInt32正在臨時搶占使用資源隊列內存池的查詢(不屬于該資源隊列)數量。
allocated_memoryUInt64資源隊列內存池被正常申請使用的內存大小。單位:Byte。
grabbed_memoryUInt64資源隊列內存池被臨時搶占使用的內存大小。單位:Byte。
free_memoryUInt64資源隊列內存池當前剩余內存大小。單位:Byte。

資源隊列相關查詢異常

并發限制導致查詢超時
相關錯誤碼:13005
解決方案:降低客戶端的查詢并發數。
Bad Query使用內存超過資源隊列內存池
相關錯誤碼:241
解決方案:優化查詢Plan,或調大資源隊列內存池。
查詢強制路由的資源隊列不存在
相關錯誤碼:13006
解決方案:檢查資源隊列創建狀態。
查詢臨時搶占申請低優先級資源隊列被Kill
相關錯誤碼:394
解決方案:降低資源隊列并發數,調整隊列優先級。