最近我们收到用户反馈,Sentry Web 无法正常刷数据,过一会儿又好了。经过初步排查,发现问题根源在于 ClickHouse 的 CPU 使用率居高不下,甚至达到了 100%,导致系统性能瓶颈。以下是我们对问题的详细分析、解决过程以及后续优化的总结,希望对遇到类似问题的团队有所帮助。
从用户的反馈来看,Sentry Web 数据无法及时刷新,表现为页面加载缓慢甚至无响应。通过监控仪表盘,我们注意到 ClickHouse 的 CPU 使用率异常高,长时间维持在 90%-100% 之间,且 24 小时内变化不明显(如下图所示)。

上图显示,CPU 使用率波动在 90%-100% 之间。更值得注意的是,即使在凌晨流量较低的预期的流量波动规律不符。通常情况下,凌晨流量减少时,CPU 使用率应该随之下降,但实际情况并非如此。这让我们初步判断,CPU 高负载可能与流量没有直接关系,而是由其他因素导致。
为了找到 CPU 打满的根本原因,我们从多个维度展开了排查。
通过观察 24 小时的 CPU 使用率趋势,我们发现其波动幅度很小,始终维持在 90%-100% 的高水位。即使在凌晨(例如 03:00-05:00)流量较低时,CPU 使用率也没有明显下降。这与我们对流量波动的预期不符,因此我们初步判断,CPU 高负载可能与业务流量没有直接关系,而是由某些后台任务或数据处理逻辑导致。
为了进一步验证这一猜测,我们决定深入分析凌晨时间段的 CPU 使用情况,找出具体消耗 CPU 的查询或操作。
我们通过 ClickHouse 的system.query_log表,查询了 2025 年 3 月 13 日凌晨 02:42:35 至 04:42:35 的 CPU 使用详情,SQL 如下:
SELECT
type,
`initial_user`,
query,
read_rows,
written_rows,
toDateTime(`event_time`) + INTERVAL 8 HOUR as time,
formatReadableSize(memory_usage) AS memory,
ProfileEvents.Values[indexOf(ProfileEvents.Names, 'UserTimeMicroseconds')] AS userCPU,
ProfileEvents.Values[indexOf(ProfileEvents.Names, 'SystemTimeMicroseconds')] AS systemCPU,
query_duration_ms,
normalizedQueryHash(query) AS normalized_query_hash
FROM
system.query_log
WHERE
time >= '2025-03-13 02:42:35'
AND time <= '2025-03-13 04:42:35'
ORDER BY `userCPU` DESC
LIMIT 100通过查询结果,我们发现 CPU 使用率主要被一类插入操作占据,具体查询如下:
INSERT INTO default.sessions_raw_local FORMAT JSONEachRow这一插入操作频繁执行,且每次操作的userCPU和systemCPU消耗都较高。结合上下文,我们推测这一操作可能与 Kafka 的数据消费有关,因为sessions_raw_local表通常用于存储从 Kafka 消费的原始会话数据。
在发现 CPU 从 2025 年 1 月 23 日开始被打满时,我们进一步分析了同一时期的其他指标。通过监控数据,我们发现:


上图显示,TPS 在 1 月 23 日后急剧上升,而 QPS(每秒查询数)变化较小,这进一步印证了问题可能与插入操作的频率增加有关,而非数据量的增长。
结合 TPS 变化,我们进一步分析了 Kafka 的消息堆积情况(如下图),发现其趋势与 CPU 使用率呈现反向关联。

从图中可以看到:
通过进一步排查,我们发现问题的起因与 2025 年 1 月 23 日的一次变更密切相关。当天,Sentry-session-consumer 的消费副本数从 1 增加到 12,目的是提升消费速度,减少 Kafka 消息堆积。然而,这一调整带来了意想不到的后果:
2 月 2日后,看消息不在堆积,Sentry-session-consumer 的消费副本从 12 个副本缩到 2 个副本
通过以上分析,我们得出结论:
为了解决 CPU 打满的问题,我们采取了以下措施:
调整后的效果非常显著。如下图所示,ClickHouse 的 CPU 使用率下降了大约 40%,稳定在 50%-60% 的区间,系统性能恢复正常,Sentry Web 的数据刷新问题也随之解决。

尽管问题得到了解决,但整个排查过程耗费了大量时间,主要原因在于:
为了避免类似问题再次发生,我们采取了以下改进措施:
ClickHouse 作为高性能的分析型数据库,对 TPS 和 Merge 负载非常敏感。在调整上游消费者(如 Sentry-session-consumer)时,必须综合考虑对下游数据库的潜在影响。
希望这篇总结能为其他团队提供参考。如果你在使用 ClickHouse 或类似系统中遇到过类似问题,欢迎留言交流!