前几天线上出了个StarRocks的Bug,我排查了一夜才解决。
事情是这样的:我们的实时数仓用了StarRocks,一直跑得挺稳定。那天晚上,突然收到告警,说StarRocks的查询延迟飙升,部分查询超时。我赶紧爬起来排查,折腾了一夜,终于找到原因并解决了。
本文记录这次排查的全过程,包括问题现象、排查思路、定位过程、根本原因、解决方法,以及从中总结的经验教训。希望能帮到遇到类似问题的同学。
一、问题现象
那天晚上11点多,我正准备睡觉,手机突然响了。
是监控系统的告警:StarRocks集群的P99查询延迟,从平时的200ms飙升到了5秒,而且有越来越多的查询超时。
我赶紧打开监控面板,看到:
- 查询延迟:P99从200ms涨到5s,P95从100ms涨到2s
- 查询成功率:从99.9%降到95%
- CPU使用率:BE节点的CPU从40%涨到90%+
- 内存使用率:BE节点的内存从60%涨到85%
- 磁盘IO:正常,没有明显升高
- 网络:正常
而且,延迟是慢慢涨上去的,不是突然飙升。从晚上9点开始慢慢涨,到11点已经涨到5秒了。
我第一反应是:是不是有慢查询把资源占满了?
二、初步排查
第一步:看正在运行的查询
我登录StarRocks的管理界面,看正在运行的查询。
SHOW PROCESSLIST;发现有几个查询已经跑了好几分钟了,还没结束。这些查询都是同一个业务方的,查询的是一张大表(大约50亿行),条件比较复杂。
我以为是这些慢查询把资源占满了,导致其他查询排队。于是我先把这几个慢查询杀掉了。
KILL QUERY <query_id>;杀掉之后,查询延迟确实降了一点,但没过多久,又涨上去了。而且,新的慢查询又出现了。
这说明,慢查询只是表象,不是根本原因。
第二步:看BE节点的状态
我看了一下BE节点的状态,发现有一个BE节点的CPU和内存明显比其他节点高。
SHOW BACKENDS;这个节点的CPU是95%,内存是90%,而其他节点都是50%左右。
我怀疑是数据倾斜,导致某个节点负载过高。
第三步:看数据分布
我查了一下那张大表的数据分布,发现数据确实倾斜了。
SELECT
tablet_id,
COUNT(*) as cnt
FROM table_name
GROUP BY tablet_id
ORDER BY cnt DESC
LIMIT 10;有几个tablet的数据量特别大,是其他tablet的10倍。而且这些大tablet都在同一个BE节点上。
我以为是数据倾斜导致的问题,于是做了一次数据重分布(ALTER TABLE ... DISTRIBUTED BY ...)。
重分布之后,数据确实均匀了,那个BE节点的负载也降下来了。我以为问题解决了,准备回去睡觉。
结果,没过半小时,延迟又涨上去了。而且这次,所有BE节点的CPU都很高,不是单个节点的问题了。
这说明,数据倾斜也不是根本原因。
三、深入排查
这时候已经凌晨1点多了。我有点慌了,因为问题还没找到,而延迟还在涨。
我决定换个思路,从系统层面排查。
第四步:看BE的日志
我登录到那个负载最高的BE节点,看BE的日志。
tail -f be/log/be.INFO日志里有很多查询,但没有明显的报错。不过,我注意到一个细节:日志里频繁出现"memory limit exceeded"的警告。
W0516 01:23:45.123456 12345 memory_limiter.cpp:123] Memory limit exceeded: query_id=xxx, used=85%, limit=80%这说明,查询因为内存超限被限流了。但为什么内存会超限呢?
第五步:看内存使用详情
我用StarRocks的内存分析工具,看了一下内存的使用情况。
SHOW PROC '/memory';发现大部分内存被"query memory"占用了,也就是查询用的内存。而且,有几个查询的内存使用量特别大,每个都用了好几GB。
我看了一下这些查询的SQL,发现它们都用了一个共同的特性:Bitmap去重。
SELECT COUNT(DISTINCT user_id) FROM table_name WHERE ...StarRocks的COUNT(DISTINCT)默认是用Bitmap实现的。Bitmap在数据量大的时候,会占用很多内存。
我怀疑是Bitmap去重导致的内存问题。但这个表一直都在用Bitmap去重,以前没问题,为什么今天突然有问题?
第六步:看数据量变化
我查了一下这张表的数据量,发现今天的数据量比平时多了很多。
SELECT COUNT(*) FROM table_name WHERE dt = '2022-05-16';平时每天新增大约1亿行,今天新增了5亿行。是平时的5倍!
我问了一下业务方,才知道今天他们做了一个活动,用户量暴增,所以数据量也暴增了。
数据量暴增,导致Bitmap去重的内存使用量暴增,进而导致查询内存超限,查询被限流,延迟飙升。
但这还不是根本原因。因为数据量虽然大了5倍,但集群的资源应该能扛住。为什么会导致所有查询都慢呢?
第七步:看内存限流的影响
我仔细看了一下内存限流的逻辑。
StarRocks有一个内存限制机制:当整个BE节点的内存使用超过阈值(默认80%)时,会对新的查询进行限流,甚至拒绝查询。
问题就在这里。那几个大查询(Bitmap去重)占用了大量内存,导致整个BE节点的内存超过了80%。然后,所有新的查询都被限流了,不管查询大小,都要排队等内存。
这就解释了为什么所有查询都变慢了——不是因为查询本身慢,而是因为内存限流,查询在排队。
而且,这是一个恶性循环:大查询占用内存 → 内存超限 → 小查询被限流排队 → 排队的查询越来越多 → 内存占用更高 → 更严重的限流。
四、根本原因
找到这里,根本原因就清楚了:
- 直接原因:业务活动导致数据量暴增5倍
- 触发因素:Bitmap去重查询在大数据量下占用大量内存
- 根本原因:StarRocks的内存限流机制是节点级别的,单个大查询会导致整个节点的所有查询被限流
简单说就是:几个大查询把内存占满了,导致所有查询都被限流,进而导致整个集群的查询延迟飙升。
五、解决方法
找到原因后,我采取了以下措施:
1. 立即缓解:杀掉大查询,限制并发
先把那几个占用内存大的Bitmap查询杀掉,然后限制这类查询的并发数。
-- 杀掉慢查询
KILL QUERY <query_id>;
-- 限制用户并发
SET PROPERTY FOR 'user_name' 'max_user_connections' = '5';杀掉大查询后,内存很快降下来了,查询延迟也恢复了正常。
2. 短期优化:调整内存配置
调整了BE的内存配置,增大了查询内存的限制,同时调整了内存限流的阈值。
# be.conf
query_mem_limit = 80% # 每个查询的内存限制
mem_limit = 85% # 节点内存限制另外,给Bitmap查询单独设置了资源组,限制它们的资源使用,避免影响其他查询。
3. 长期优化:优化查询和表结构
从根本上解决问题,需要优化查询和表结构:
- 对Bitmap列做预聚合,减少查询时的计算量
- 用物化视图预计算常用的去重指标
- 对大查询做异步化,避免影响在线查询
- 增加集群资源,应对数据量增长
六、经验教训
这次排查折腾了一夜,总结了几条经验教训。
1. 监控要细,不能只看整体
我们的监控只看了整体的查询延迟和成功率,没有细分到查询类型和资源使用。如果一开始就能看到内存使用和查询类型,就能更快定位问题。
以后要加更细的监控:
- 按查询类型监控延迟和资源使用
- 监控内存使用,特别是查询内存
- 监控Bitmap等特殊功能的使用情况
2. 大查询要隔离,不能和小查询混跑
大查询(比如Bitmap去重、大表Join)占用资源多,应该和小查询隔离开。用资源组或者单独的集群,避免大查询影响小查询。
3. 数据量增长要有预案
业务活动导致数据量暴增,这种情况应该有预案。提前评估数据量增长对系统的影响,做好扩容和优化。
4. 了解底层机制很重要
这次问题的根本原因,是StarRocks的内存限流机制。如果不了解这个机制,就很难定位问题。
用任何技术,都要了解它的底层机制和限制。不能只停留在会用的层面。
5. 排查问题要系统,不能想当然
我一开始以为是慢查询,后来以为是数据倾斜,都没找到根本原因。后来从系统层面(日志、内存、配置)排查,才找到真正的原因。
排查问题要系统,从现象到本质,一步步来,不能想当然。
七、StarRocks使用的其他建议
借着这次经历,也说说我用StarRocks的一些建议。
1. 合理设计分桶
分桶数要合适,太多太少都不好。一般建议每个tablet的数据量在1-10GB之间。分桶键要选择分布均匀的列,避免数据倾斜。
2. 用好物化视图
物化视图是StarRocks的一大利器。对于常用的聚合查询,可以用物化视图预计算,大大提升查询速度。
3. 注意内存使用
StarRocks是内存密集型的,要特别注意内存使用。监控内存,合理配置内存限制,避免OOM。
4. 定期Compaction
数据导入后会产生很多小的版本,需要Compaction合并。定期检查Compaction状态,必要时手动触发。
5. 做好备份
虽然StarRocks有多副本,但还是要定期备份。用BACKUP命令备份数据,以防万一。
八、写在最后
这次StarRocks的Bug排查,折腾了我一夜,但也让我对StarRocks的理解更深了。
技术就是这样,每踩一个坑,就多一分理解。没有白踩的坑,也没有白熬的夜。
希望这篇文章能帮到遇到类似问题的同学。如果你也在用StarRocks,遇到了查询延迟飙升的问题,可以从内存、大查询、数据倾斜这几个方面排查。
2022年了,StarRocks已经越来越成熟,成为了很多公司实时数仓的首选。但不管用什么技术,了解底层机制、做好监控、有应急预案,都是不变的真理。
最后,用一句话总结:"线上问题不可怕,可怕的是不知道为什么。只要系统排查,总能找到原因。"
愿大家的线上系统都能稳定运行,不用熬夜排查问题。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录