本文介紹如何使用雲資料庫ClickHouse的資源隊列增強功能。
背景資訊
ClickHouse官方開源版目前沒有資源隊列的功能設計,20.8及以上版本的雲資料庫ClickHouse社區相容版叢集對於資源限制的用法,詳情請參見Restrictions on Query Complexity。
本文介紹的資源隊列是雲資料庫ClickHouse的增強功能,並且只適配於20.3版本的雲資料庫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;返回結果說明:
| 名稱 | 類型 | 說明 |
| name | String | 資源隊列名。 |
| concurrency | UInt32 | 資源隊列的並發限制。 |
| memory | UInt64 | 資源隊列的記憶體池大小。單位:Byte。 |
| isolate | UInt8 | 資源隊列的隔離等級。 |
| priority | Enum8(枚舉) | 資源隊列的優先順序別。 |
| roles | Array<String> | 資源隊資料行繫結的所有相關使用者。 |
List指定資源隊列的查詢使用狀態:
show resource queue stat [CURRENT | ALL];返回結果說明:
| 名稱 | 類型 | 說明 |
| name | String | 資源隊列名。 |
| running_query | UInt32 | 資源隊列中正在執行的查詢數量。 |
| waiting_query | UInt32 | 資源隊列中正在等待執行的查詢數量。 |
| grabbing_query | UInt32 | 正在臨時搶佔使用資源隊列記憶體池的查詢(不屬於該資源隊列)數量。 |
| allocated_memory | UInt64 | 資源隊列記憶體池被正常申請使用的記憶體大小。單位:Byte。 |
| grabbed_memory | UInt64 | 資源隊列記憶體池被臨時搶佔使用的記憶體大小。單位:Byte。 |
| free_memory | UInt64 | 資源隊列記憶體池當前剩餘記憶體大小。單位:Byte。 |
資源隊列相關查詢異常
並發限制導致查詢逾時
- 相關錯誤碼:13005
- 解決方案:降低用戶端的查詢並發數。
Bad Query使用記憶體超過資源隊列記憶體池
- 相關錯誤碼:241
- 解決方案:最佳化查詢Plan,或調大資源隊列記憶體池。
查詢強制路由的資源隊列不存在
- 相關錯誤碼:13006
- 解決方案:檢查資源隊列建立狀態。
查詢臨時搶佔申請低優先順序資源隊列被Kill
- 相關錯誤碼:394
- 解決方案:降低資源隊列並發數,調整隊列優先順序。