golang写入influxdb2,共3种方式,小心有坑!

==事件背景==

项目中需要接收设备上报的时序数据,写入到Influxdb中,在压力测试过程中发现服务器CPU占用的非常高,

使用pprof解析了CPU占用的详细信息之后,发现Influxdb的AddField方法占用的CPU较多,记录一下这个问题。

 

==程序版本==

Influxdb:2.0

golang:1.18

influxdb-client-go:1.4.0

 

==参考博客==

golang使用pprof笔记

 

==原因分析==

golang写入influxdb有3种方式,分别如下:

方式一:NewPoint(最终推荐方式)

这种方式是自己构造好tag及field的map,一次性创建出point,然后写入数据

p := influxdb2.NewPoint("stat",
    map[string]string{"unit": "temperature"},
    map[string]interface{}{"avg": 24.5, "max": 45.0},
    time.Now())
writeAPI.WritePoint(p)

 

方式二:NewPointWithMeasurement

这种方式是先构造出point之后,调用AddTag及AddField方法,动态增加tag及field。

p = influxdb2.NewPointWithMeasurement("stat").
    AddTag("unit", "temperature").
    AddField("avg", 23.2).
    AddField("max", 45.0).
    SetTime(time.Now())
writeAPI.WritePoint(p)

 

方式三:WriteRecord

以字符串的形式按照规则构造写入内容,一次性写入数据。

line := fmt.Sprintf("stat,unit=temperature avg=%f,max=%f", 23.5, 45.0)
writeAPI.WriteRecord(line)

 

问题发生时,我使用的是方式二,即动态添加field的方式,然后通过pprof工具抓取cpu占用情况之后,发现AddField占用了大量的CPU

下图finalshell的资源占用截图:

 

下图为pprof的cpu占用截图:

 

通过查看influxdb客户端源码发现,每次AddField方法中都会对已经添加过的Field循环一次,这样就造成了Field越多,循环就越多,从而占用了大量的CPU。

 

==优化方法==

放弃方式二,使用方式一写入数据。修改之后CPU降低了很多。

下图为修改后finalshell的资源占用截图:

 

下图为修改后pprof中cpu占用的截图:

 

--END--

posted @ 2022-12-28 17:51  大墨垂杨  阅读(894)  评论(0编辑  收藏  举报