一,influxdb内存溢出,启动报错
现象:
检查influxdb.log文件,看到如下错误:
fatal error: runtime: out of memory
runtime stack:
runtime.throw(0x12dae55, 0x16)
/usr/local/go/src/runtime/panic.go:608 +0x72
runtime.sysMap(0xc480000000, 0x164000000, 0x21cb618)
/usr/local/go/src/runtime/mem_linux.go:156 +0xc7
runtime.(*mheap).sysAlloc(0x21b1860, 0x164000000, 0x300097199d, 0x7ffd97731560)
/usr/local/go/src/runtime/malloc.go:619 +0x1c7
runtime.(*mheap).grow(0x21b1860, 0xb1487, 0x0)
/usr/local/go/src/runtime/mheap.go:920 +0x42
runtime.(*mheap).allocSpanLocked(0x21b1860, 0xb1487, 0x21cb628, 0x0)
.....
原因:
很明显内存不够了,那么内存为什么不够了呢?
经查,原因在于influxdb在启动时,需要将索引加入到内存中。由于我的环境中存在80GB左右的数据,并且使用了大量的tag,索引数据超过了机器内存,所以就报oom了。
解决办法:
改内存索引为磁盘索引
操作步骤:
1.首先将配置(influxdb.conf)中的索引类型进行修改
使以后的数据使用磁盘索引。如下:
[data]
# The type of shard index to use for new shards. The default is an in-memory index that is
# recreated at startup. A value of "tsi1" will use a disk based index that supports higher
# cardinality datasets.
//将#去掉,将值改为tsi1
index-version = "tsi1"
2.将已存在的tsm索引改为tsi磁盘索引
1.停止InfluxDB服务
2.删除所有_series文件夹
默认情况下,_series保存在/data//_series,检查并删除/data目录下所有_series
find . -name "_series" | xargs rm -rf
3.删除所有index文件夹
默认情况下,index文件夹在/data/<dbName///index使用
find . -name "index" | xargs rm -rf
4.influx_inspect重构TSI index,此步可能会很耗时
# 格式
influx_inspect buildtsi -datadir <data_dir> -waldir <wal_dir>
# 示例
influx_inspect buildtsi -datadir /data -waldir /wal
5.启动influxDB服务
二,常驻内存集占用过高
通过top命令查看,发现influxdb RES占用15个G,几乎占满了机器内存。
需要排查原因,使用下述命令,查看influxdb状态
./influx -host 10.x.xx.xx -port xx -username 'x' -password 'x' -execute "show stats" |less
name: runtime
Alloc Frees HeapAlloc HeapIdle HeapInUse HeapObjects HeapReleased HeapSys Lookups Mallocs NumGC NumGoroutine PauseTotalNs Sys TotalAlloc
----- ----- --------- -------- --------- ----------- ------------ ------- ------- ------- ----- ------------ ------------ --- ----------
99709592 12749096 99709592 165896192 101621760 2492153 1104644608 267517952 0 15241249 206 27 36862171 284375288 2197223664
如果发现runtime下HeapIdle+HeapInUse 与RES相差较大,且HeapReleased值特别大,很可能就是influxdb已标记释放的内存,未及时给系统回收导致的。
使用env GODEBUG=madvdontneed=1
参数,强制每次释放内存时,将内存交给系统。如下
env GODEBUG=madvdontneed=1 /usr/bin/influxd -config /usr/bin/influxdb.conf
重启influx服务,再看RES占用,发现大幅下降,只有一百多M了,约等于HeapIdle+HeapInUse。
三,GODEBUG=madvdontneed=1 配置仍不能解决内存占用过高的问题
如果不是内存释放不及时导致的问题,那么上述配置几乎没有作用。
那么就要注意monitor配置,也就是默认的_internal库,用户influxdb服务的监控,如果我们的数据量很大,需要监控指标很多,也会造成很大的压力。
所以如果不是必要的情况,可以禁用此功能。
在Influxdb.conf 修改配置
[monitor]
# Whether to record statistics internally.
#将这行的#号去掉,并将值改为true
store-enabled = false
四,tag数量超出限制,导致数据无法入库
修改influxdb.conf中相应限制,改大点即可。
max-values-per-tag = 100000
五,插入数据时报类型错误
报已存在某类型数据,类型错误本来是比较简单,改数据类型就可以了。
但是,有些表明明没有数据,依然会报类型错误。这时要删除series和measurement,并重启influxdb,即可解决。