InfluxDB入门

546 阅读8分钟

基本概念

line-protocol

line protocol elements

  • measurement(必要): 用于存储数据的指标名字
  • tag set: 以逗号分隔的键值对列表, 每个键值对都代表一个标签; 标签的键和值是无引号的字符串, 空格、逗号、等号必须被转义; 可以类比关系型数据库表中带索引的字段;
  • field set(必要): 以逗号分隔的键值对列表, 每个键值对都代表一个字段; 字段键是无引号的字符串, 空格和逗号必须被转义; 字段值可以是字符串(带引号)、浮点数、整数、无符号整数或布尔运算; 可以类比关系型数据库表中不带索引的字段;
  • timestamp: 与数据相关的unix时间戳, influxDB支持最高纳秒级的精度; 如果时间戳的精度不是纳秒, 必须在向influxDB写入数据时指定精度

line protocol element parsing

  • measurement: 第一个未转义的逗号之前的所有内容
  • tag set: 第一个未转义的逗号和第一个未转义的空白之间的键值对
  • field set: 在第一个和第二个没有转义的空白处之间的键值对
  • timestamp: 在第二个未转义的空白处之后的整数值
  • 行与行之间用换行符(\n)分割

image.png

organization

一组用户的workspace, 所有的dashboard、tasks、buckets、members等资源都属于一个组织

bucket

一个bucket是一个命名的位置用来存储时间序列数据; 所有的bucket都有一个retention period; 一个bucket属于一个organization

point

在influxdb中, 一个point代表一条数据记录, 类似于SQL数据库表中的行记录

每个point包含:

  • 一个measurement、一组tag、一个field key, 一个field value以及一个timestamp
  • point由series和timestamp唯一标识

在一个series中, 每个point都有一个唯一的timestamp, 如果把一个timestamp和结合现有的point数据写入series, 那么新旧field会取并集

series

influxdb数据结构中共享一个measurement和tag set的数据集合

series基数

influxdb bucket中唯一的measurement、tag set、field key组合的数量

栗子1: 假设一个bucket有一个measurement, 单个measurement又两个tag(email和status); 如果有三个不同的email并且每个email地址关联两个不同的status, 那么对于这个measurement的series基数为3*2=6

image.png

栗子2: 从属标签是由另外一个标签决定范围的, 不会增加series基数, 如下所示把标签firstname加到上面的例子中, series基数不会是18(323)而是6(3*2), 因为firstname标签已经呗email标签范围覆盖

image.png

命令行基本操作

启动influxdb服务

使用influxd启动默认配置的influxdb服务

默认情况下数据目录在$HOME/.influxdbv2中; 默认访问地址http://localhost:8086/; 通过influx客户端连接到服务端的连接信息默认是存在$HOME/.influxdbv2/configs文件中

通过influxdb-cli初始化admin用户

influx setup -u USERNAME -p PASSWORD -t TOKEN -o ORGANIZATION_NAME -b BUCKET_NAME -f
  • -f: 使用非交互模式初始化用户
  • -u: 用户名
  • -p: 密码
  • -t: token
  • -o: 指定organization
  • -b: 指定bucket

创建 All-Access tokens

influx auth create \
  --all-access \
  --host http://localhost:8086 \
  --org <YOUR_INFLUXDB_ORG_NAME> \
  --token <YOUR_INFLUXDB_OPERATOR_TOKEN>

注意: token需要使用admin用户的 

注意: --token需要使用通过influxdb-cli初始化admin用户中创建的token

./influx auth create --all-access --host http://localhost:8086 --org myorg --token mytoken

ID Description Token User Name User ID Permissions

0a9060a7c836d000 c8YXKxUQtI3fvwPPg== admin 0a905edff1f6d000 [read:orgs/ff538db5e1fa9049/authorizations ……]

注意: 生成之后需要注意保留token

配置认证凭证

influx config create \
  --config-name get-started \
  --host-url http://localhost:8086 \
  --org <YOUR_INFLUXDB_ORG_NAME> \
  --token <YOUR_INFLUXDB_API_TOKEN>

注意: --token可以使用创建 All-Access tokens中创建的token

创建bucket

influx bucket create --name get-started

注意: --name使用配置认证凭证中创建的配置名字

写入数据

influx write \
  --bucket get-started \
  --precision s "
home,room=Living\ Room temp=21.1,hum=35.9,co=0i 1641024000
home,room=Kitchen temp=21.0,hum=35.9,co=0i 1641024000
home,room=Living\ Room temp=21.4,hum=35.9,co=0i 1641027600
home,room=Kitchen temp=23.0,hum=36.2,co=0i 1641027600
home,room=Living\ Room temp=21.8,hum=36.0,co=0i 1641031200
home,room=Kitchen temp=22.7,hum=36.1,co=0i 1641031200
home,room=Living\ Room temp=22.2,hum=36.0,co=0i 1641034800
home,room=Kitchen temp=22.4,hum=36.0,co=0i 1641034800
home,room=Living\ Room temp=22.2,hum=35.9,co=0i 1641038400
home,room=Kitchen temp=22.5,hum=36.0,co=0i 1641038400
home,room=Living\ Room temp=22.4,hum=36.0,co=0i 1641042000
home,room=Kitchen temp=22.8,hum=36.5,co=1i 1641042000
home,room=Living\ Room temp=22.3,hum=36.1,co=0i 1641045600
home,room=Kitchen temp=22.8,hum=36.3,co=1i 1641045600
home,room=Living\ Room temp=22.3,hum=36.1,co=1i 1641049200
home,room=Kitchen temp=22.7,hum=36.2,co=3i 1641049200
home,room=Living\ Room temp=22.4,hum=36.0,co=4i 1641052800
home,room=Kitchen temp=22.4,hum=36.0,co=7i 1641052800
home,room=Living\ Room temp=22.6,hum=35.9,co=5i 1641056400
home,room=Kitchen temp=22.7,hum=36.0,co=9i 1641056400
home,room=Living\ Room temp=22.8,hum=36.2,co=9i 1641060000
home,room=Kitchen temp=23.3,hum=36.9,co=18i 1641060000
home,room=Living\ Room temp=22.5,hum=36.3,co=14i 1641063600
home,room=Kitchen temp=23.1,hum=36.6,co=22i 1641063600
home,room=Living\ Room temp=22.2,hum=36.4,co=17i 1641067200
home,room=Kitchen temp=22.7,hum=36.5,co=26i 1641067200
"

基于FLUX查询数据

Flux是一个能够在influxdb查询和处理数据的函数式的脚本语言

Flux查询基础

  • from() 从influxdb的bucket中查询数据
  • range() 基于时间范围的数据过滤
  • filter() 基于列值的数据过滤, 每一行用r表示, 每一列用r的一个属性表示, 可以应用多个后续过滤器。
r = {
    _time: 2020-01-01T00:00:00Z,
    _measurement: "home",
    room: "Kitchen",
    _field: "temp",
    _value: 21.0,
}
(r) => r._measurement == "home" // Returns true
(r) => r.room == "Kitchen" // Returns true
(r) => r._field == "co" // Returns false
(r) => r._field == "co" or r._field == "temp" // Returns true
(r) => r._value <= 20.0 // Returns false

filter函数将每一行记录命名为r, 所以可以通过r._measurement, r.room这种方式来获取数据, 如果行判断为true则会在filter的输出中被包含, 否则会丢弃

Flux通过管道转发操作符|>将上一个函数的输出作为下一个函数的输入.

from(bucket: "get-started")
    |> range(start: 2022-01-01T08:00:00Z, stop: 2022-01-01T20:00:01Z)
    |> filter(fn: (r) => r._measurement == "home")
    |> filter(fn: (r) => r._field== "co" or r._field == "hum" or r._field == "temp")

执行Flux查询

  • 命令行方式
influx query '
from(bucket: "get-started")
    |> range(start: 2022-01-01T08:00:00Z, stop: 2022-01-01T20:00:01Z)
    |> filter(fn: (r) => r._measurement == "home")
    |> filter(fn: (r) => r._field== "co" or r._field == "hum" or r._field == "temp")
'

使用map函数对数据重新赋值

map获取单个参数即fn, fn是一个匿名函数, 将每一行作为一条记录来读取, 在每一行记录中, 每个键值对代表一个列和他的值

r = {
    _time: 2020-01-01T00:00:00Z,
    _measurement: "home",
    room: "Kitchen",
    _field: "temp",
    _value: 21.0,
}

fn函数以任何你需要的方式修改记录, 并返回一个新的记录, 如下所示:

(r) => ({ _time: r._time, _field: "temp_F", _value: (r._value * 1.8) + 32.0})

// Returns: {_time: 2020-01-01T00:00:00Z, _field: "temp_F", _value: 69.8}

注意: 在上例中有部分的列会被丢弃, 原因是因为fn只显式的映射_time、_field、_value列, 如果需要只更新或者添加指定的列需要使用with操作

(r) => ({r with _value: (r._value * 1.8) + 32.0, degrees: "F"})

// Returns:
// {
//     _time: 2020-01-01T00:00:00Z,
//     _measurement: "home",
//     room: "Kitchen",
//     _field: "temp",
//     _value: 69.8,
//     degrees: "F",
// }
from(bucket: "get-started")
    |> range(start: 2022-01-01T08:00:00Z, stop: 2022-01-01T20:00:01Z)
    |> filter(fn: (r) => r._measurement == "home")
    |> filter(fn: (r) => r._field == "hum")
    |> map(fn: (r) => ({r with _value: r._value / 100.0}))

使用group函数重新将数据分组

默认情况下,from()返回从InfluxDB查询的数据,按系列(测量、标签和字段键)分组。返回的表流中的每个表代表一个组。每个表都包含相同的数据分组列的值。这种分组在你汇总数据时是很重要的。

from(bucket: "get-started")
    |> range(start: 2022-01-01T08:00:00Z, stop: 2022-01-01T20:00:01Z)
    |> filter(fn: (r) => r._measurement == "home")
    |> group(columns: ["room", "_field"])

若 |> group() 则为不分组

聚合数据

取平均值

from(bucket: "get-started")
    |> range(start: 2022-01-01T08:00:00Z, stop: 2022-01-01T20:00:01Z)
    |> filter(fn: (r) => r._measurement == "home")
    |> filter(fn: (r) => r._field == "co" or r._field == "hum" or r._field == "temp")
    |> mean()

计数

from(bucket: "get-started")
    |> range(start: 2022-01-01T14:00:00Z, stop: 2022-01-01T20:00:01Z)
    |> filter(fn: (r) => r._measurement == "home")
    |> toFloat()
    |> group(columns: ["room"])
    |> count()

内置聚合方法: docs.influxdata.com/flux/v0.x/f…

内置selector方法:docs.influxdata.com/flux/v0.x/f…

转换数据结构为关系型数据库表结构

pivot函数: docs.influxdata.com/flux/v0.x/s…

from(bucket: "get-started")
    |> range(start: 2022-01-01T14:00:00Z, stop: 2022-01-01T20:00:01Z)
    |> filter(fn: (r) => r._measurement == "home")
    |> filter(fn: (r) => r._field == "co" or r._field == "hum" or r._field == "temp")
    |> filter(fn: (r) => r.room == "Kitchen")
    |> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")

使用aggregateWindow采样数据

aggregateWindow函数:docs.influxdata.com/influxdb/v2…

数据采样是一种策略, 可以提高查询时的性能, 也可以优化长期数据存储; 简单来说采样数据减少返回点的数量, 而不会丢失数据的总体趋势

from(bucket: "get-started")
    |> range(start: 2022-01-01T14:00:00Z, stop: 2022-01-01T20:00:01Z)
    |> filter(fn: (r) => r._measurement == "home")
    |> filter(fn: (r) => r._field == "temp")
    |> aggregateWindow(every: 2h, fn: mean)
  • every参数指定窗口周期
  • fn指定使用aggregate或selector中的函数
  • timeSrc指定使用哪一列值来为每个窗口创建新的聚合时间戳, 默认是_stop

InfluxDB任务

task是预定的查询, 可以执行上述任何数据处理操作; 一般来说任务会使用to函数将处理后的结构写回给InfluDB

InfluxDB任务: docs.influxdata.com/influxdb/v2…