从现象到根因:跨多层级定位运维场景中的性能问题
一、现象描述
Kubernetes集群监控显示,集群中的三个Infra节点会定期产生超高流量,大概每20分钟产生约900Mbps-1.5Gbps流量,每次持续13分钟,导致网络负载很高,集群状态整体正常,无法通过日志/事件诊断异常。

二、问题定位
1. 网络层面排查
首先可以明确,当节点稳定产生1Gbps左右的流量时,必定是一个长链接,链接的状态必定是established,从这个角度,用ss命令可以看到链接双方的ip和端口
ss -antnp state established得到以下结果

同时也可以看到,传输是由本地的768端口到目标2049端口;
1000以下的端口一般都是操作系统保留端口,而后面没有显示进程,也说明了这个传输是由内核进程发起的,即使是使用lsof -i :768也是无法查看具体是什么进程的;
然而,端口暴露了重要信息:2049端口是nfs标准端口,如无意外,这个链接执行的是nfs数据写入操作。
2. IO层面排查
根据网络层面排查结果,我们可以分析,NFS存储是基于网络的文件系统存储,性能一般,对于大量数据的并发写入处理能力其实比较低,因此当此类场景出现时,几乎都会同时出现IO等待现象,我们可以进行验证:
# 实时查看CPU状态,每秒刷新,持续60秒sar -u 1 60
3. 操作系统层面排查
目前我们已经确定了网络流量高是由于NFS写入操作导致的,但是还无法确定到底是什么进程在写入,下一步,就需要定位进程。
当NFS写入出现严重积压时,一般会同步出现大量NFS RPC请求和TCP socket长时间处于未完成状态,会导致已经产生的文件描述符无法释放,新的文件描述符继续产生,因此会出现文件描述符数量急剧增长的情况,此时,可以通过系统接口查看哪些进程产生了大量的文件描述符
# *: 通配符:检查所有进程# fd: file descriptor - 文件描述符ls /proc/*/fd可见:


通过这两个进程,9298和9299,几乎可以直接定位他们就是导致高流量的“元凶”,因为正常的进程根本不会创建这么多的文件描述符。
使用ps -up,可以检查是什么进程

4. 内存状态排查
此时还需要一步,就能完全确认是由NFS写入导致的问题了;检查内存的脏页和WriteBack状态:
cat /proc/meminfo | egrep "Dirty|Writeback"
如截图显示,系统有大量 dirty pages 积压和 writeback 洪峰,这说明本地一直在稳定地往NFS写数据,但 NFS server处理速度跟不上,导致数据边发边堆,最终表现为一段时间内持续的高网络流量。
三、根因定位
经过检索clickhouse官方文档,我门了解到clickhouse会定期将分散的小块数据合并为大块数据,然后写入到磁盘中,已提升顺序读时的性能,在网络负载升高期间,通过查询合并线程,观察到了15个并发合并线程:
SELECT * FROM system.merges;

四、验证
在出现网络流量升高现象时,进入到指定的clickhouse副本中,执行命令关闭当前的合并行为
SYSTEM STOP merge;之后继续观察,可以发现对应节点的网络负载比其他没做停止合并操作的副本的所在节点更快回落到了低水平(如图中黄线)

五、结论
本问题本质属于 ClickHouse 的自动合并行为 在 NFS 存储场景下引发的 Linux writeback 拥塞问题。当前 NFS 存储性能已无法有效承载现有 observability 场景下的 merge IO负载,属于存储性能瓶颈在网络层面上的反映,对应应用程序行为正常,节点操作系统正常,网络正常。
后续应按照clickhouse官方建议,使用本地SSD作为持久化存储。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!