Golang 写入数据到 InfluxDB 2.0

更新日期: 2021-06-11 阅读次数: 8256 字数: 614 分类: InfluxDB

Golang SDK

https://github.com/influxdata/influxdb-client-go

生成 Token

在 InfluxDB UI 后台,可以手动生成 Token。而且里面有 Golang 的示例代码。

http://localhost:8086/

安装依赖

go get github.com/influxdata/influxdb-client-go/v2

阻塞与非阻塞

  • WriteAPIBlocking: 阻塞
  • WriteAPI: 非阻塞。即异步写

异步写的机制,数据首先被异步写入到一个 buffer,满足一定条件时才会写入数据库。 条件为:

  • 要么缓存数据达到 5000 条 (batch size)
  • 要么等待定时 flush,默认一秒一次

对于不重要的传感器上报数据,我觉得异步写足够了。

这个 batch size 也可以调整,例如修改为 20:

client := influxdb2.NewClientWithOptions("http://localhost:8086", "my-token",
        influxdb2.DefaultOptions().SetBatchSize(20))

为何要加 context.Background()

虽然示例中写的是

writeAPI.WritePoint(context.Background(), p)

但实际编译时,会报错

too many arguments in call to writeAPI.WritePoint
	have (context.Context, *"github.com/influxdata/influxdb-client-go/v2/api/write".Point)
	want (*"github.com/influxdata/influxdb-client-go/v2/api/write".Point)

还是需要写成:

writeAPI.WritePoint(p)

client.WriteAPI 是否可以在 coroutine 中复用

可以。

// Launch write routines
for t := 0; t < threads; t++ {
	wg.Add(1)
	go func() {
		for p := range pointsCh {
			writeApi.WritePoint(p)
		}
		wg.Done()
	}()
}

设置全局的 writeAPI

import (
	influxdb2 "github.com/influxdata/influxdb-client-go/v2"
	"github.com/influxdata/influxdb-client-go/v2/api"
)

var writeAPI api.WriteAPI

注意:

如果靠自动补全,可能会漏掉 api 的 v2 前缀,导致编译报错:

no required module provides package github.com/influxdata/influxdb-client-go/api

golang 写入数据的三种方式

参考:

https://github.com/influxdata/influxdb-client-go

方法一:

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

方法二:

// Create point using fluent style
p = influxdb2.NewPointWithMeasurement("stat").
	AddTag("unit", "temperature").
	AddField("avg", 23.2).
	AddField("max", 45.0).
	SetTime(time.Now())
writeAPI.WritePoint(p)

方法三:

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

对我而言,方法二的可读性最高。

field key 的长度是否会影响存储空间

https://community.influxdata.com/t/do-shorter-field-names-save-database-space/5740/8

例如,我有几百台设备,每个设备上有一堆不同的传感器,可能有:

  • 压力传感器
  • 温度传感器
  • 湿度传感器
  • 各种气体浓度传感器

在设置 field key 的时候,是否要写英文全称,还是写英文简写。非常纠结:

  • 写全称:方便阅读理解,但是会不会需要更多的存储空间
  • 写简写:省了空间,但是不容易理解,UI 后台的内置曲线图更不容易理解

从官方论坛的讨论看,如果是同一个系列,field key 不会重复存储。所以在设备数可控的情况下, 使用 field key 全称并不会影响到存储成本。

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式