Checkpointer重放Statistics相关Journal导致CPU突刺(达到5000%以上)

【详述】
问题现象: Routine Load导致CPU利用率突增(达到5000%以上)

起初以为是Routine Load导致的CPU突刺,后来经过各种排查和分析源码,最终定位到了是Checkpoint线程导致的CPU突刺:

查看FE日志,发现高峰时间段和Checkpoint时间非常吻合,每次Checkpoint的时候,必定出现CPU突刺,结合代码和其他日志,逐渐定位到原因:Checkpoint线程回放最近一段时间新增的journal的时候,也把journal中statistics相关的entry(OperationType.OP_ADD_BASIC_STATS_META)回放了,由此触发了statistics更新的过程,且是之前记录的journal堆积到了这一个时间点,此过程在集群上上会造成瞬时600个左右的statistics更新任务(因为Routine Load任务较多,且频繁更新表数据,所以触发的statistics统计任务也较多,这些统计任务都会被写到journal里面作为一条entry,在replay这些journal的时候,又被重复执行了),这些任务会被分发给BE执行,因此占用较高的CPU,造成突刺

不只是Routine Load,只要StarRocks中实时表过多(我们另外一个集群使用Flink写入很多表,也有突刺现象),就会造成这种现象

除了Checkpoint日志和突刺时间吻合之外,还有另外1个验证方式:关闭statistics自动收集:突刺现象消失

代码BUG:Checkpoint不应该触发statistics的更新,因为这些更新完成的统计信息只是临时的,Checkpoint完成之后就会被抛弃,属于无效更新;只有Follower节点才需要在replay这些journal的时候触发statistics的更新:
com.starrocks.persist.EditLog

修改代码,上线完成后,突刺消失:

下图中红框内为上线之前的突刺,代码于20:00上线,上线完成后,不再出现突刺现象

主要问题是,触发statistics自动全量收集的时候(其实准确点,不是收集而是刷新statistics缓存),是异步的 cache 实现的(com.starrocks.sql.optimizer.statistics.CachedStatisticStorage#getColumnStatistics),底层好像默认使用ForkJoinPool,而这个是没有做并发控制的,极端情况会用上很多线程(而手动创建的采集任务默认是3个并发控制: statistic_collect_concurrency,和这里自动的不同),有什么好办法可以避免这种情况吗?虽然修改代码后,我们的Checkpoint线程已经不再触发突刺了,但是未来不排除别的情况导致自动全量收集出现类似的堆积现象

【背景】做过哪些操作?
Create了1000个Routine Load Job,其中40个的并发task数目是3,其他均为1
【业务影响】

【StarRocks版本】
2.5.3
【集群规模】
3fe+3be(fe与be混部)
500GB内存,128 CPU核心
【表模型】
均为主键模型,Kafka的topic中UPSERT和DELETE操作都有

【导入或者导出方式】
Routine Load
【联系方式】
StarRocks社区群4-Matata
【附件】

3赞

@jingdan @Doni 两位大佬有时间再看看嘛,有啥建议不

或者我们在这个类:com.starrocks.sql.optimizer.statistics.CachedStatisticStorage 里面,给cache传入自定义的executor,是不是也能达到限制线程数目的目的,比如(简单示例):

分析的太专业了!

帮提个PR修复下?

6666,这波分析很到位了,可以的话最好是两个地方都fix:
一个是checkpoint的线程不需要refresh cache
一个是限制统计信息cache的执行器的线程池(另外10并发可能偏低,可以改成可配置项)

整理下这个问题的触发流程,应该大概是这样的:

  1. 导入/更新 会触发自动统计信息收集,自动收集策略在2.5.5版本前触发比较频繁,自动收集会记录&更新OperationType.OP_ADD_BASIC_STATS_META
  2. checkpoint 时回放 journal log,并刷新节点上的统计信息

由于频繁导入,会记录大量的统计信息journal log,导致checkpoint 回放时一次性更新节点上的统计信息cache,进一步导致CPU打高

对对对,就是这个情况,大佬总结的很到位