dbaplus社群 02月03日
ClickHouse 被干冒烟了,咋整?
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

项目验收关键期,大屏数据指标显示‘黑’,后台出事。经排查发现clickhouse服务器负载过高,作者分享了找出问题、解决问题的过程及经验。

😱服务器负载过高,纯CPU消耗,超出满载400多倍

📋通过简单SQL找出资源消耗大户的SQL

🎯提出解决问题的三步策略及彻底解决的方法

Anryg(安瑞哥) 2025-02-03 08:01 广东

任凭鼠标再怎么刷新,都没有用……


这是一个发生在我生产环境的真实案例。


上周我们的一个项目准备接受第一阶段的验收时,结果就在这个关键的节骨眼上,大屏大部分数据指标显示突然都「黑」了,任凭鼠标再怎么刷新,都没有用。


很明显,后台出事了。


像这种「数据不能及时供应」的问题,排查链路一般都是这样的:提供数据的微服务 -> 存储数据的数据库 -> 计算该数据的进程 -> 进程上游的数据源。


一级级跟爬楼梯一样挨个排查,先是确保微服务没挂,日志没有异常;接着就是看存储该数据的数据库表里,有没有最新的数据,结果就是这么一查,查出问题了。


一、问题表现


来,先看个截图。



吓人不?


这就是我在查对应后台数据表时,发现查询结果一直在那里转圈圈出不来后,逐个向每台 clickhouse 服务器查看系统负载时发现的。


负载居然给干到了 2K+,而且这里是纯纯的 CPU 消耗。


这里插播个冷知识:


当看到系统负载过高时,有时不一定就是 CPU 被使的太狠导致的,如果系统出现了过多的 IO 等待操作,这个负载也会很高,但这一点,会通过「 IO 等待」这个指标反映出来,也就是截图第 3 行的那个 wa 指标。

如果这个 wa 的值不为 0,说明当前的 IO (网络 IO,或者磁盘 IO,或者两者兼而有之)出现了瓶颈,需要着手这个方面的优化。


而当前这个 wa 值为 0 ,或是接近 0,那就代表只是纯纯的 CPU 消耗。


再来瞅一眼,是哪个进程这么凶残,把这台服务器给榨成这样:



真凶果然就是我 clickhouse(下称 CK) 大宝贝。


要知道,当前这只是一台 64 核,单核单线程 CPU 的服务器。



理论上它的满荷负载,就是 64,而现在却是飙到了 2700+,足足超出满载的 400 多倍。


这就好比一辆只能拉 1吨货的汽车,你硬是给它压了 400多吨的重量,那不得干冒烟了呀。


二、揪出内鬼


根据我的经验,一般集群如果出现「慢」的问题,大概率都可能是其中的「某一台」机器出现了问题,但根据木桶原理,往往就是这么一个害群之马,会拖慢整个集群的效率。


只要是数据库,这种解决套路都大差不差,负载高,无非就是当前节点产生了很多不合理的读写操作。


那对于 CK 来说,该怎么把这些不合理的操作给揪出来呢?


CK 提供了两张很好用的,记录数据库操作的系统表。


一张叫:system.processes;


另一张叫:system.query_log。



网上看到了很多关于这两张表的用法,也试过一些,但是因为查询逻辑比较复杂(各种 join 跟函数嵌套使用),导致跑了好久,结果都出不来。


要知道,如果你当前 CK 机器本身负载就很高了,你再去执行一个逻辑复杂的 SQL,导致负载进一步增加,执行效率只会更低(甚至压根跑不出结果),那不就陷入死循环了嘛。


所以正确的玩法,一定是只需要执行一个非常简单的 SQL,就能把那些「资源消耗大户」给揪出来。


怎么玩?


根据我这次的经验,执行这个 SQL 就够了(连排序都不用)。



虽然负载很高,但因为这个 SQL 足够的简单,所以很快结果就能跑出来。



CK 很聪明,默认情况下,这个结果会根据 SQL 执行消耗的时间,从大到小排序。


所以,你一眼就能看出,是哪些 SQL 导致的当前负载过高。


三、怎么解决


问题找到了,怎么解决就好办了。


第 1 步:找到对应的,执行这个 SQL 的人,一起看看这个 SQL 写的是不是很傻逼,查询方式对不对,有没有有效利用索引等;


第 2 步: 这些导致高负载的 SQL,肯定不能让它继续执行了,根据上面找出来的 query_id,把它们挨个 kill 掉;



第 3 步:有时候就算把这些 SQL 暂时 kill 掉了,但过不了一会,因为后台调度的原因,又会跑起来,导致系统负载再次飙升,这个时候,一个聪明的做法,就是把这些查询涉及到的表给直接「下线」(这个设计很高明)。



这一次,我就是根据这「3 步走」策略,暂时稳住了整个项目。


其实这台服务器的「慢」,我心里是有数的,为了方便,在每次使用 CK 时,我都用客户端直接连的这台机器,这就导致一些数据量不大的表(千万级以下),我都用的「本地表」,而这些本地表,我又刚好都建在了这一台机器上。


所以就导致,跑在这台服务器上的 CK 实例,默默承受了超出其他几个实例,N 倍的压力。


至于怎么彻底解决这个问题?


1、调整一些不合理 SQL 的写法,傻逼写法改成科学合理的写法,该加索引加索引,不需要的字段能不查就不查;


2、把分片表的准入门槛降低,稍微大一点,且使用频率高的表,都尽量优化为分片表,让原来只在一台机器上的压力,给分摊到多台机器上;


3、所有那些数据量比较小的本地表,给尽可能平均挪到多台机器上,不要只薅一台服务器的羊毛。


四、最后


经过这么一系列的组合拳下去,这台曾经被干冒烟的服务器,终于恢复了往日该有的平静(负载一直控制在 30 左右)。


其实面对这样的「慢」问题,所有的数据库解决套路都非常类似。


只不过对于 CK 来说,因为它特殊的集群组织形式,在某些时候,需要花费的运维成本,确实要高那么一丢丢。


作者丨 Anryg(安瑞哥)

来源丨公众号: 安瑞哥是码农(ID:gh_c12dc29ae2e7

dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn


阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

clickhouse 服务器负载 问题解决 数据库运维
相关文章