在高QPS集群中,异常SQL可能消耗大量CPU和内存资源,导致集群性能下降甚至OOM。本文介绍如何快速发现并终止异常SQL,以及如何配置自动防护策略,避免资源耗尽。
步骤一:发现Bad SQL
使用以下命令查看正在运行的查询,找出CPU或内存消耗异常的SQL。
建议优先使用SHOW PROC '/global_current_queries'(需v3.4+),该命令可查看所有FE节点的运行中查询。v3.4以下版本使用SHOW PROC '/current_queries',仅能查看当前FE节点。
-- 查看所有FE节点正在运行的查询(v3.4+,推荐)
SHOW PROC '/global_current_queries';
-- v3.4以下版本,只能查看当前FE节点
SHOW PROC '/current_queries';查询结果中重点关注以下字段:
指标 | 高风险阈值 | 说明 |
CPUTime | > 60s | CPU消耗异常,可能是笛卡尔积或缺少谓词。 |
MemoryUsage | > 2 GB | 内存占用过高,有OOM风险。 |
步骤二:查杀Bad SQL
找到异常SQL后,通过ConnectionId或QueryId终止查询。
-- 通过ConnectionId终止(从步骤一结果获取)
KILL QUERY <ConnectionId>;
-- 通过QueryId终止(v3.1+)
KILL QUERY '<QueryId>';通过QueryId终止查询需要StarRocks v3.1及以上版本。ConnectionId为数字,不需要引号;QueryId为字符串,需要用单引号。
步骤三:分析原因(可选)
终止异常SQL后,可以开启慢查询Profile采集,分析SQL异常的根本原因,避免问题再次发生。
开启慢查询Profile采集
设置慢查询阈值,只对超过阈值的查询采集Profile,对正常查询无性能影响。
-- 开启慢查询Profile采集(只对超阈值查询生效,正常查询零开销)
SET GLOBAL big_query_profile_threshold = '30s';查看和分析Profile
-- 查看已采集的Profile
SHOW PROFILELIST LIMIT 50;
-- 分析指定查询的执行瓶颈
ANALYZE PROFILE FROM '<query_id>';自动防护配置
除了手动查杀,还可以通过资源组和查询队列实现自动防护,从根源上避免异常SQL耗尽集群资源。
资源组:自动拒绝超限查询
通过资源组(Resource Group)对CPU和内存设置上限,超过限制的查询将被自动拒绝。
SET GLOBAL enable_pipeline_engine = true;
CREATE RESOURCE GROUP bigQueryGuard
TO (db='your_db')
WITH (
'cpu_weight' = '10',
'mem_limit' = '20%',
'big_query_cpu_second_limit' = '300', -- CPU超过300s自动拒绝
'big_query_mem_limit' = '5368709120' -- 内存超过5GB自动拒绝
);以上参数值仅供参考,请根据实际集群配置和业务需求调整big_query_cpu_second_limit和big_query_mem_limit的值。
查询队列:防止并发过载
当集群资源使用达到阈值时,新查询将进入队列等待,避免过载。
SET GLOBAL enable_query_queue_select = true;
SET GLOBAL query_queue_concurrency_limit = 100;
SET GLOBAL query_queue_mem_used_pct_limit = 0.9;
SET GLOBAL query_queue_cpu_used_permille_limit = 800;
SET GLOBAL query_queue_max_queued_queries = 100;
SET GLOBAL query_queue_pending_timeout_second = 480;各参数说明如下。
参数 | 说明 |
enable_query_queue_select | 是否启用查询队列,设置为 |
query_queue_concurrency_limit | 最大并发查询数,超过此值的查询将排队等待。 |
query_queue_mem_used_pct_limit | 内存使用百分比阈值,超过后新查询排队。 |
query_queue_cpu_used_permille_limit | CPU使用千分比阈值(800表示80%),超过后新查询排队。 |
query_queue_max_queued_queries | 队列最大等待查询数,超过后新查询将被拒绝。 |
query_queue_pending_timeout_second | 排队超时时间(秒),超时后查询将被取消。 |
以上参数值仅供参考,请根据实际集群规模和业务负载情况调整。
速查
操作 | 命令或方式 |
发现Bad SQL |
|
查杀 |
|
Profile采集 |
|
自动防护 | 资源组 |