监控和管理大查询
本文介绍如何在 StarRocks 集群中监控和管理大查询。
大查询包括扫描太多行或占用太多 CPU 和内存资源的查询。 如果不对其施加限制,它们很容易耗尽集群资源并导致系统过载。 为了解决这个问题,StarRocks 提供了一系列措施来监控和管理大查询,防止查询垄断集群资源。
StarRocks 中处理大查询的总体思路如下
- 使用资源组和查询队列设置针对大查询的自动预防措施。
- 实时监控大查询,并终止那些绕过预防措施的查询。
- 分析审计日志和大查询日志,研究大查询的模式,并微调您之前设置的预防机制。
此功能从 v3.0 开始支持。
设置针对大查询的预防措施
StarRocks 提供了两种用于处理大查询的预防工具 - 资源组和查询队列。 您可以使用资源组来阻止大查询的执行。 另一方面,查询队列可以帮助您在达到并发阈值或资源限制时对传入的查询进行排队,从而防止系统过载。
通过资源组过滤掉大查询
资源组可以自动识别和终止大查询。 创建资源组时,您可以指定查询有权使用的 CPU 时间、内存使用量或扫描行数的上限。 在命中资源组的所有查询中,任何需要更多资源的查询都会被拒绝并返回错误。 有关资源组的更多信息和说明,请参阅资源隔离。
在创建资源组之前,您必须执行以下语句来启用 Pipeline Engine,资源组功能依赖于该引擎
SET GLOBAL enable_pipeline_engine = true;
以下示例创建一个资源组 bigQuery
,该资源组将 CPU 时间上限限制为 100
秒,扫描行数上限限制为 100000
,内存使用量上限限制为 1073741824
字节 (1 GB)
CREATE RESOURCE GROUP bigQuery
TO
(db='sr_hub')
WITH (
'cpu_weight' = '10',
'mem_limit' = '20%',
'big_query_cpu_second_limit' = '100',
'big_query_scan_rows_limit' = '100000',
'big_query_mem_limit' = '1073741824'
);
如果查询所需的资源超过任何限制,则该查询将不会执行并返回错误。 以下示例显示了查询要求过多扫描行时返回的错误消息
ERROR 1064 (HY000): exceed big query scan_rows limit: current is 4 but limit is 1
如果是您第一次设置资源组,我们建议您设置相对较高的限制,以便它们不会妨碍常规查询。 在您更好地了解大查询模式后,您可以微调这些限制。
通过查询队列缓解系统过载
查询队列旨在缓解集群资源占用率超过预先指定的阈值时的系统过载恶化。 您可以为最大并发数、内存使用量和 CPU 使用率设置阈值。 当达到任何这些阈值时,StarRocks 会自动对传入的查询进行排队。 挂起的查询要么在队列中等待执行,要么在达到预先指定的资源阈值时被取消。 有关更多信息,请参阅查询队列。
执行以下语句为 SELECT 查询启用查询队列
SET GLOBAL enable_query_queue_select = true;
启用查询队列功能后,您可以定义触发查询队列的规则。
-
指定触发查询队列的并发阈值。
以下示例将并发阈值设置为
100
SET GLOBAL query_queue_concurrency_limit = 100;
-
指定触发查询队列的内存使用率比率阈值。
以下示例将内存使用率比率阈值设置为
0.9
SET GLOBAL query_queue_mem_used_pct_limit = 0.9;
-
指定触发查询队列的 CPU 使用率比率阈值。
以下示例将 CPU 使用率千分比 (CPU 使用率 * 1000) 阈值设置为
800
SET GLOBAL query_queue_cpu_used_permille_limit = 800;
您还可以通过配置最大队列长度和队列中每个挂起查询的超时来决定如何处理这些排队的查询。
-
指定最大查询队列长度。 达到此阈值时,传入的查询将被拒绝。
以下示例将查询队列长度设置为
100
SET GLOBAL query_queue_max_queued_queries = 100;
-
指定队列中挂起查询的最大超时。 达到此阈值时,将拒绝相应的查询。
以下示例将最大超时设置为
480
秒SET GLOBAL query_queue_pending_timeout_second = 480;
您可以使用SHOW PROCESSLIST检查查询是否正在挂起。
mysql> SHOW PROCESSLIST;
+------+------+---------------------+-------+---------+---------------------+------+-------+-------------------+-----------+
| Id | User | Host | Db | Command | ConnectionStartTime | Time | State | Info | IsPending |
+------+------+---------------------+-------+---------+---------------------+------+-------+-------------------+-----------+
| 2 | root | xxx.xx.xxx.xx:xxxxx | | Query | 2022-11-24 18:08:29 | 0 | OK | SHOW PROCESSLIST | false |
+------+------+---------------------+-------+---------+---------------------+------+-------+-------------------+-----------+
如果 IsPending
为 true
,则对应的查询正在查询队列中挂起。
实时监控大查询
从 v3.0 开始,StarRocks 支持查看当前在集群中处理的查询以及它们占用的资源。 这使您可以监控集群,以防任何大查询绕过预防措施并导致意外的系统过载。
通过 MySQL 客户端进行监控
-
您可以使用SHOW PROC查看当前正在处理的查询 (
current_queries
)。SHOW PROC '/current_queries';
StarRocks 返回查询 ID (
QueryId
)、连接 ID (ConnectionId
) 以及每个查询的资源消耗,包括扫描的数据大小 (ScanBytes
)、处理的行数 (ProcessRows
)、CPU 时间 (CPUCostSeconds
)、内存使用量 (MemoryUsageBytes
) 和执行时间 (ExecTime
)。mysql> SHOW PROC '/current_queries';
+--------------------------------------+--------------+------------+------+-----------+----------------+----------------+------------------+----------+
| QueryId | ConnectionId | Database | User | ScanBytes | ProcessRows | CPUCostSeconds | MemoryUsageBytes | ExecTime |
+--------------------------------------+--------------+------------+------+-----------+----------------+----------------+------------------+----------+
| 7c56495f-ae8b-11ed-8ebf-00163e00accc | 4 | tpcds_100g | root | 37.88 MB | 1075769 Rows | 11.13 Seconds | 146.70 MB | 3804 |
| 7d543160-ae8b-11ed-8ebf-00163e00accc | 6 | tpcds_100g | root | 13.02 GB | 487873176 Rows | 81.23 Seconds | 6.37 GB | 2090 |
+--------------------------------------+--------------+------------+------+-----------+----------------+----------------+------------------+----------+
2 rows in set (0.01 sec) -
您可以通过指定查询 ID 来进一步检查查询在每个 BE 节点上的资源消耗。
SHOW PROC '/current_queries/<QueryId>/hosts';
StarRocks 返回每个 BE 节点上的查询扫描的数据大小 (
ScanBytes
)、扫描的行数 (ScanRows
)、CPU 时间 (CPUCostSeconds
) 和内存使用量 (MemUsageBytes
)。mysql> show proc '/current_queries/7c56495f-ae8b-11ed-8ebf-00163e00accc/hosts';
+--------------------+-----------+-------------+----------------+---------------+
| Host | ScanBytes | ScanRows | CpuCostSeconds | MemUsageBytes |
+--------------------+-----------+-------------+----------------+---------------+
| 172.26.34.185:8060 | 11.61 MB | 356252 Rows | 52.93 Seconds | 51.14 MB |
| 172.26.34.186:8060 | 14.66 MB | 362646 Rows | 52.89 Seconds | 50.44 MB |
| 172.26.34.187:8060 | 11.60 MB | 356871 Rows | 52.91 Seconds | 48.95 MB |
+--------------------+-----------+-------------+----------------+---------------+
3 rows in set (0.00 sec)
通过 FE 控制台进行监控
除了 MySQL 客户端之外,您还可以使用 FE 控制台进行可视化交互式监控。
-
使用以下 URL 在浏览器中导航到 FE 控制台
http://<fe_IP>:<fe_http_port>/system?path=//current_queries
您可以在**系统信息**页面上查看当前正在处理的查询及其资源消耗。
-
单击查询的**QueryID**。
您可以在出现的页面上查看详细的、特定于节点的资源消耗信息。
手动终止大查询
如果任何大查询绕过您设置的预防措施并威胁到系统可用性,您可以使用KILL语句手动使用相应的连接 ID 终止它们
KILL QUERY <ConnectionId>;
分析大查询日志
从 v3.0 开始,StarRocks 支持大查询日志,这些日志存储在文件**fe/log/fe.big_query.log**中。 与 StarRocks 审计日志相比,大查询日志打印了另外三个字段
bigQueryLogCPUSecondThreshold
bigQueryLogScanBytesThreshold
bigQueryLogScanRowsThreshold
这三个字段对应于您定义的用于确定查询是否为大查询的资源消耗阈值。
要启用大查询日志,请执行以下语句
SET GLOBAL enable_big_query_log = true;
启用大查询日志后,您可以定义触发大查询日志的规则。
-
指定触发大查询日志的 CPU 时间阈值。
以下示例将 CPU 时间阈值设置为
600
秒SET GLOBAL big_query_log_cpu_second_threshold = 600;
-
指定触发大查询日志的扫描数据大小阈值。
以下示例将扫描数据大小阈值设置为
10737418240
字节 (10 GB)SET GLOBAL big_query_log_scan_bytes_threshold = 10737418240;
-
指定触发大查询日志的扫描行数阈值。
以下示例将扫描行数阈值设置为
1500000000
SET GLOBAL big_query_log_scan_rows_threshold = 1500000000;
微调预防措施
从实时监控和大查询日志中获得的统计信息中,您可以研究集群中省略的大查询(或被错误诊断为大查询的常规查询)的模式,然后优化资源组和查询队列的设置。
如果很大比例的大查询符合某种 SQL 模式,并且您想永久禁止这种 SQL 模式,您可以将此模式添加到 SQL 黑名单。 StarRocks 拒绝所有匹配 SQL 黑名单中指定的任何模式的查询,并返回错误。 有关更多信息,请参阅管理 SQL 黑名单。
要启用 SQL 黑名单,请执行以下语句
ADMIN SET FRONTEND CONFIG ("enable_sql_blacklist" = "true");
然后,您可以使用ADD SQLBLACKLIST将表示 SQL 模式的正则表达式添加到 SQL 黑名单。
以下示例将 COUNT(DISTINCT)
添加到 SQL 黑名单
ADD SQLBLACKLIST "SELECT COUNT(DISTINCT .+) FROM .+";