StarRocks 大查询监控与管理:从资源隔离、查询队列到 Big Query Log 的完整实践
【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks
大查询(Big Query)指扫描行数过多、或占用过多 CPU 与内存资源的查询,它们极易耗尽集群资源并导致系统过载。本文基于 StarRocks 官方文档 Monitor and manage big queries(自 v3.0 起支持),系统讲解"预防—监控—治理"三层方案:先用资源组与查询队列设防,再用实时监控发现漏网之鱼并手动终止,最后借助审计日志与 Big Query Log 分析大查询规律、反向调优防护机制。读完本文,你将掌握一套完整的、可落地的大查询治理闭环。
适用版本:StarRocks v3.0 及以上;文中涉及的特性参数以当前仓库
main分支的 FE 源码(fe/fe-core/src/main/java/com/starrocks/qe/SessionVariable.java、GlobalVariable.java)与 官方文档 为准。
一、整体治理思路:预防、监控、复盘三层闭环
StarRocks 处理大查询的整体思路分为三步:
- 预防:用资源组(Resource Group)和查询队列(Query Queue)对大查询设置自动防线——资源组直接拒绝超限查询,查询队列在并发或资源达到阈值时把查询放入队列,缓解系统过载。
- 监控:实时监控集群中正在执行的查询及其资源占用,发现绕过预防机制的大查询后,手动终止它们。
- 复盘:分析审计日志(Audit Log)和 Big Query Log,研究大查询的规律,并反过来微调第 1 步中设置的预防机制,形成持续改进的闭环。
该特性自 StarRocks v3.0 起支持。
二、设置预防机制(Precautions)
StarRocks 提供了两件预防大查询的"武器":资源组与查询队列。资源组用来直接阻止大查询执行;查询队列则在并发或资源阈值被触达时排队新进入的查询,防止系统过载恶化。
2.1 用资源组过滤大查询
资源组能够自动识别并终止大查询。创建资源组时,你可以为命中该资源组的查询指定 CPU 时间、内存使用量或扫描行数的上限。任何需要更多资源的查询都会被拒绝并返回错误。完整的使用说明参见 Resource Isolation。
资源组特性依赖 Pipeline Engine,因此在创建资源组之前,必须先执行以下语句开启 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' );TO (db='sr_hub'):指定该资源组生效的数据库范围,这里命中sr_hub库的查询都会受到该资源组约束。cpu_weight:CPU 权重,用于资源组之间的 CPU 调度分配(示例为10)。mem_limit:资源组的内存上限(示例为20%)。big_query_cpu_second_limit:大查询 CPU 时间上限(秒)。big_query_scan_rows_limit:大查询扫描行数上限。big_query_mem_limit:大查询内存上限(字节)。
从源码看,这三个big_query_*_limit参数正是资源组判定大查询的硬性指标,相关常量定义于 ResourceGroup.java:
public static final String BIG_QUERY_MEM_LIMIT = "big_query_mem_limit"; public static final String BIG_QUERY_SCAN_ROWS_LIMIT = "big_query_scan_rows_limit"; public static final String BIG_QUERY_CPU_SECOND_LIMIT = "big_query_cpu_second_limit";如果某查询所需资源超过其中任一上限,该查询将不被执行,直接返回错误。例如,当查询要求的扫描行数超过上限时,会返回如下错误信息:
ERROR 1064 (HY000): exceed big query scan_rows limit: current is 4 but limit is 1首次配置建议:如果你是第一次设置资源组,建议先设置相对较高的上限,以免误伤常规查询;等对大查询的规律有了更充分的了解后,再逐步收紧紧上限。
2.2 用查询队列缓解系统过载
查询队列用于在集群资源占用超过预设阈值时,缓冲系统过载的恶化趋势。你可以设置最大并发数、内存使用率和 CPU 使用率的阈值;当任一阈值被触达时,StarRocks 会自动将新进入的查询放入队列。排队中的查询要么在队列中等待执行,要么在预设资源阈值触达时被取消。详细说明参见 Query Queues。
首先开启 SELECT 查询的查询队列:
SET GLOBAL enable_query_queue_select = true;该全局变量定义于 GlobalVariable.java,与之并列的还有enable_query_queue_statistic(统计查询)、enable_query_queue_load(导入任务)等开关,说明查询队列可按查询类型分别开启。
开启后,即可定义触发查询队列的规则。
① 并发数阈值
以下示例将并发阈值设为100:
SET GLOBAL query_queue_concurrency_limit = 100;② 内存使用率阈值
以下示例将内存使用率阈值设为0.9(即 90%):
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;上述 5 个阈值常量同样在 GlobalVariable.java 中集中定义,查询队列相关的机制还包括query_queue_fresh_resource_usage_interval_ms(资源用量刷新间隔)、query_queue_driver_high_water/query_queue_driver_low_water(driver 水位)等,可用于更精细的队列调优。
如何判断查询是否在排队?使用 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 支持查看集群中当前正在处理的查询及其资源占用,以便在预防机制被绕过、出现意外系统过载时及时发现问题。
3.1 通过 MySQL 客户端监控
第 1 步:查看当前正在执行的查询
使用 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)从示例输出可以直观看出:第二行查询扫描了13.02 GB数据、处理了近4.88 亿行、占用6.37 GB内存,属于典型的大查询,应重点关注。
第 2 步:按查询 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)该视图便于定位资源消耗是否在某台 BE 上出现倾斜,辅助判断数据分布或节点负载问题。
3.2 通过 FE 控制台可视化监控
除 MySQL 客户端外,还可以使用 FE 控制台(FE console)进行可视化、交互式的监控:
在浏览器中打开如下 URL 进入 FE 控制台:
http://<fe_IP>:<fe_http_port>/system?path=//current_queries在System Info页面查看当前正在处理的查询及其资源消耗。
点击查询的QueryID,在随后出现的页面中查看该查询在各节点上的详细资源消耗信息。
3.3 手动终止大查询
如果有大查询绕过你设置的预防机制并威胁到系统可用性,可以使用 KILL 语句配合对应的连接 ID 手动终止它:
KILL QUERY <ConnectionId>;注意:KILL QUERY使用的是SHOW PROC '/current_queries'输出中的ConnectionId(连接 ID),而不是QueryId。
四、分析 Big Query Log
自 v3.0 起,StarRocks 支持 Big Query Log,日志存储在文件fe/log/fe.big_query.log中。与 StarRocks 审计日志(Audit Log)相比,Big Query Log 额外打印三个字段:
bigQueryLogCPUSecondThresholdbigQueryLogScanBytesThresholdbigQueryLogScanRowsThreshold
这三个字段对应你为判定"某查询是否为大查询"而定义的资源消耗阈值。
先开启 Big Query Log:
SET GLOBAL enable_big_query_log = true;该变量的默认值在 SessionVariable.java 中为true(enableBigQueryLog = true),即默认开启。开启后,即可定义触发 Big Query Log 的规则:
① 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(15 亿行):
SET GLOBAL big_query_log_scan_rows_threshold = 1500000000;从源码实现看,这 4 个会话变量集中定义于 SessionVariable.java:
public static final String ENABLE_BIG_QUERY_LOG = "enable_big_query_log"; public static final String BIG_QUERY_LOG_CPU_SECOND_THRESHOLD = "big_query_log_cpu_second_threshold"; public static final String BIG_QUERY_LOG_SCAN_BYTES_THRESHOLD = "big_query_log_scan_bytes_threshold"; public static final String BIG_QUERY_LOG_SCAN_ROWS_THRESHOLD = "big_query_log_scan_rows_threshold"; public static final String BIG_QUERY_PROFILE_THRESHOLD = "big_query_profile_threshold";其默认值与设计意图在 SessionVariable.java 的注释中有所说明:若enable_big_query_log = true且查询的 CPU/IO 开销超过相关阈值,查询信息就会被写入 big query log。默认阈值分别为 CPU 时间480秒、扫描数据量10 GB、扫描行数10 亿行——这些默认值是为测试场景设定的(如"三台 16 核机器满载计算 10 秒"),生产环境需根据自身场景调整。
此外,Config.java 中还有一批与 big query log 文件管理相关的 FE 配置项,可用于控制日志的滚动与保留策略:
big_query_log_dir:big query log 目录,默认STARROCKS_HOME_DIR + "/log";big_query_log_roll_num:单个滚动周期内保留的最大 FE 日志文件数,默认10;big_query_log_roll_interval:日志滚动周期,默认DAY;big_query_log_delete_age:日志删除年龄,默认7d;big_query_log_roll_file_index:滚动文件索引策略,可选min、max、nomax,默认min;big_query_log_delete_count:保留的滚动 big query log 文件数量硬上限,默认-1(不限制)。
五、基于监控与日志复盘、微调预防机制
借助实时监控与 Big Query Log 得到的统计信息,你可以研究集群中"漏网的大查询"(或被误判为大查询的常规查询)的规律,进而优化资源组与查询队列的设置。
如果相当比例的大查询符合某种 SQL 模式,并且你希望永久禁止该 SQL 模式,可以将该模式加入SQL 黑名单(SQL Blacklist)。StarRocks 会拒绝所有匹配 SQL 黑名单中任意模式的查询,并返回错误。详细说明参见 Manage SQL Blacklist。
先开启 SQL 黑名单功能:
ADMIN SET FRONTEND CONFIG ("enable_sql_blacklist" = "true");该 FE 配置项默认值定义于 Config.java(enable_sql_blacklist = false),即默认关闭,需要显式开启。
然后使用 ADD SQLBLACKLIST 将代表该 SQL 模式的正则表达式加入黑名单。
以下示例将COUNT(DISTINCT)加入 SQL 黑名单:
ADD SQLBLACKLIST "SELECT COUNT(DISTINCT .+) FROM .+";加入后,所有匹配该正则的查询(此处为对任意表执行COUNT(DISTINCT ...)的 SELECT)都会被直接拒绝。
六、完整治理实践建议
结合前三层机制,一个完整的 StarRocks 大查询治理落地流程可以归纳为:
- 设防:开启
enable_pipeline_engine后,创建带big_query_*_limit上限的资源组,从源头拒绝超限查询;同时开启enable_query_queue_select,并配置并发/内存/CPU 阈值与队列长度、超时,让瞬时高峰查询排队而非压垮系统。 - 监控:日常使用
SHOW PROC '/current_queries'与 FE 控制台http://<fe_IP>:<fe_http_port>/system?path=//current_queries观察运行中查询;发现异常大查询时用KILL QUERY <ConnectionId>及时止损。 - 复盘:确认
enable_big_query_log已开启,通过fe/log/fe.big_query.log结合审计日志沉淀大查询画像;根据画像反向调整资源组阈值、队列参数,必要时用ADD SQLBLACKLIST永久拦截高频危险 SQL 模式。
值得注意的是,资源组阈值、Big Query Log 阈值、查询队列阈值三者是三套独立配置:资源组阈值决定"执行前拒绝",Big Query Log 阈值决定"执行后记录",查询队列阈值决定"高峰时排队"。合理设置它们的分工,可以让大查询治理既有前置防线、又有事后取证,形成可持续优化的闭环。
延伸阅读
- Resource Isolation(资源组):资源组创建与调优完整手册
- Query Queues(查询队列):查询队列全部参数说明
- Manage SQL Blacklist:SQL 黑名单管理
- SHOW PROCESSLIST / SHOW PROC / KILL:监控与终止相关 SQL 语句
- ADD SQLBLACKLIST:添加 SQL 黑名单
- audit_loader:审计日志导入与管理
- logs:FE/BE 日志体系说明
【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考