==事件背景==
项目中需要接收设备上报的时序数据,写入到Influxdb中,在压力测试过程中发现服务器CPU占用的非常高,
使用pprof解析了CPU占用的详细信息之后,发现Influxdb的AddField方法占用的CPU较多,记录一下这个问题。
==程序版本==
Influxdb:2.0
golang:1.18
influxdb-client-go:1.4.0
==参考博客==
==原因分析==
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--
标签:方式,AddField,influxdb2,占用,写入,golang,CPU From: https://www.cnblogs.com/quchunhui/p/17010910.html