问题描述
在使用telegraf + influxdb做进程信息监控时,某天开始数据无法记录,telegraf日志显示如下错误:
partial write: max-values-per-tag limit exceeded (100009/100000)
原因分析
根据influxdb的官方说明,其默认tag的最大value数量是10万个,通过show series查看influxdb中的内容,发现大量的如下记录:
procstat,host=xxx,pid=xxx,process_name=sleep,user=root
经查询sleep进程是linux的ksm机制默认60s会调用一次,每次pid就会新生成一个。也就是相当于每1分钟会tag-value会增加一条,时间长了就超过了influxdb的限制。
导致这个问题的原因主要是因为telegraf配置导致的,主要因为2点:
启用了pid_tag=true,此开关将pid作为tag。(该参数上方有说明,官方建议谨慎开启)
使用inputs.prostat插件时,没有加过滤,记录了系统所有进程信息。
上面2个条件叠加在一起导致了tag-value的数量增长。
解决方案
第一种方案:关闭pid_tag=true
第二种方案:继续启用pid_tag=true,只监控常驻进程。(这种方案也不能从根本上解决问题,经常重启进程,数量也会增长,只不过pid作为tag时用于同名进程时比较方便)
网上有些解决方案将max-values-per-tag设置为0,用于关闭此限制,这种方案时间长了会导致ram增长,操作系统会将influxdb进程kill掉,所以不建议设置为0
为什么有这个限制
influxdb增加了对tag的值的大小的校验,若写入的数据的tag的值超限,则调用方会收到报错。用来防止写入到measurement的数据的series-cardinality( series-cardinality)过大。如果我们写入了大量的series-cardinality很高的数据,那么当我们删除数据的时候,InfluxDB会OOM。
InfluxDB在内存中维护了系统中每个series数据的索引。随着具有唯一性的series数据数量的增长,RAM的使用也会增长,过高的series cardinality会导致操作系统kill掉InfluxDB进程,抛出OOM异常。
扩展
在使用influxdb时,tag的设计要慎重,不要将随着时间变化的值作为tag。
不要轻易放开max-values-per-tag的限制,更不要设置为0,除非你明确的知道你的数量上限是多少。
转 https://blog.csdn.net/qiuxin315/article/details/122325016