Prometheus指标写入ES间断问题排查

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Prometheus指标写入ES间断问题排查相关的知识,希望对你有一定的参考价值。

参考技术A

由于Prometheus自身容量有限,不适合存储大量数据,所以需要将数据写入远端存储。由于我对ES比较熟悉,所以选择了ES作为远端存储,adapter为 prometheus-es-adapter
环境搭建好后,很快就看到ES中已经有数据流入,就以为大功告成了,但第二天发现数据只写了半个小时就中断了。

通过初步排查后,发现是 prometheus-es-adapter 挂掉了,原因是OOMKilled(内存溢出),所以就将cpu增加到1000m,内存增加到1Gi,之后运行正常了。
但观察半天后,发现数据写入经常出现长时间间断,如下图:

由于我目前对Prometheus接触还比较少,于是带着问题去请教运维同学,运维同学检查完Prometheus配置后,指出可能是 remote_write.queue_config.capacity 设置过小,导致大量数据来不及写入ES而被丢弃。下面默认capacity是10:

于是我将 remote_write.queue_config.capacity 增大为1000:

但发现并没有起作用。这是把这个过程看成是生产者-消费者模式的话,那 Prometheus 就是生产者, prometheus-es-adapter 是消费者,既然问题不在Prometheus,很可能就在 prometheus-es-adapter 这边。于是我按照说明文档,设置环境变量 DEBUG=true 开启调试模式。

可以看到有日志正常输出,说明prometheus-es-adapter确实接收到了数据,并尝试写入ES,但为什么ES没有收到数据呢?(后来仔细观察,发现ES是有数据写入的,只不过速度很慢)

于是我猜想: 是不是prometheus-es-adapter把数据写入了队列中,等待数据达到一定数量后再批量写入呢?或者是消费线程太少,导致消息处理不过来而造成大量堆积呢? 如果是这样,那必定会占用大量内存,内存空闲率必然要不断下降,这也可以解释之前遇到的OOMKilled。
于是我通过 watch 命令去监控 prometheus-es-adapter 容器的内存空闲率:

下面两张图是观察了5分钟的结果,可以看到内存空闲率在不断下降。

于是我尝试着将 ES_WORKERS 增加为20,果然一段时间后数据就追上来了。

这个问题的根本原因是:prometheus-es-adapter处理线程太少,导致数据不能及时写入ES而致使Prometheus队列爆满,数据被大量丢弃或堆积在prometheus-es-adapter的处理队列中。这也是为什么只有一段时间有数据的原因及prometheus-es-adapter发生OOMKilled的原因。
要解决这个问题,需要修改两个地方:

以上是关于Prometheus指标写入ES间断问题排查的主要内容,如果未能解决你的问题,请参考以下文章

基于 prometheus 的微服务指标监控

统一观测丨使用 Prometheus 监控云原生网关,我们该关注哪些指标?

生产环境10分钟黄金时间快速排障:CPU不定时飙高怎么排查?

Prometheus指标优化

验证 prometheus 指标是不是已更新

Prometheus 指标没有给出路径变量值