StatusOk+InfluxDb+Grafana(二)InfluxDB - 时序数据库的简要介绍

InfluxDB是一个由InfluxData开发的开源时序型数据库,具有跨OSS,云和企业产品的通用API的可编程性和高性能,可为您提供高粒度,高规模和高可用性。

InfluxDB由Go写成,着力于高性能地查询与存储时序型数据,被广泛应用于存储系统的监控数据,IoT行业的实时数据等场景。

1. 安装

1.1. 通过go自行make安装

如果自己构建,需要Go 1.11和Go模块支持,influxd是InfluxDB服务。 influx是CLI管理工具。

$ make
...
env GO111MODULE=on go build -tags 'assets ' -o bin/darwin/influx ./cmd/influx
env GO111MODULE=on go build -tags 'assets ' -o bin/darwin/influxd ./cmd/influxd

启动服务。默认情况下记录到stdout:

$ bin/darwin/influxd

1.2. 通过docker安装

类似mysql、mongo,本地开发环境,将influxdb数据存储在/var/lib/influxdb中

$ docker run -p 8086:8086 \
      -v /var/lib/influxdb:/var/lib/influxdb \
      influxdb

由InfluxDB使用的相关端口:

  • 8086 HTTP API端口
  • 8083 管理员界面端口,如果可用 (管理员界面自1.1.0起不推荐使用,将在1.3.0中删除,同时要使用管理员界面,必须将HTTP API管理员界面API转发到同一端口。)
  • 2003 Graphite支持,如果可用

与InfluxDB环境相关变量配置,通过环境变量指定配置(INFLUXDB_$SECTION_$NAME):

  • INFLUXDB_REPORTING_DISABLED=true
  • INFLUXDB_META_DIR=/path/to/metadir
  • INFLUXDB_DATA_QUERY_LOG_ENABLED=false
  • INFLUXDB_ADMIN_ENABLED=true
  • INFLUXDB_GRAPHITE_ENABLED=true
// docker 生成配置
$ docker run --rm influxdb influxd config > influxdb.conf

// 指定配置文件启动镜像
$ docker run -p 8086:8086 \
      -v $PWD/influxdb.conf:/etc/influxdb/influxdb.conf:ro \
      influxdb -config /etc/influxdb/influxdb.conf

// Graphite,InfluxDB支持Graphite线路协议,但默认情况下不会公开服务和端口,需要映射开启:
docker run -p 8086:8086 -p 2003:2003 \
    -e INFLUXDB_GRAPHITE_ENABLED=true \
    influxdb

2. influxdb初始化和简单操作

2.1. InfluxDB权限初始化

InfluxDB映像包含一些用于初始化数据库的额外功能。这些选项不建议用于生产,但在运行独立实例进行测试时非常有用。

  • INFLUXDB_DB : 自动初始化指定名称的数据库
  • INFLUXDB_HTTP_AUTH_ENABLED : 身份验证相关,必须设置
  • INFLUXDB_ADMIN_USER : 要创建的admin用户的名称。如果未设置,则不会创建管理员用户。
  • INFLUXDB_ADMIN_PASSWORD : 如果未设置,则生成随机密码并打印到标准输出。
  • INFLUXDB_USER : 要创建的没有权限的用户的名称,如果INFLUXDB_DB设置,则将授予此用户对该数据库的读写权限。
  • INFLUXDB_USER_PASSWORD: 没有设置,则随机生成
  • INFLUXDB_READ_USER : 只读用户
  • INFLUXDB_READ_USER_PASSWORD : 没有设置,则随机生成
  • INFLUXDB_WRITE_USER : 写用户
  • INFLUXDB_WRITE_USER_PASSWORD : 没有设置,则随机生成

创建InfluxDB - db0,同时开启管理员面板:INFLUXDB_ADMIN_ENABLED,设置管理员账号和密码,以及数据库访问的用户,指定数据库文件共享目录,以及通过一个.sh脚本手动初始化数据库:

$ docker run --rm \
      -p 8086:8086 -p 8083:8083 -p 2003:2003 \
      -v /var/lib/influxdb:/var/lib/influxdb \
      -e INFLUXDB_HTTP_AUTH_ENABLED=true \
      -e INFLUXDB_ADMIN_ENABLED=true \
      -e INFLUXDB_ADMIN_USER=admin -e INFLUXDB_ADMIN_PASSWORD=secretpassword \
      -e INFLUXDB_USER=clark -e INFLUXDB_USER_PASSWORD=secretpassword \
      influxdb /init-influxdb.sh

2.2. 操作InfluxDB数据库

2.2.1. 基于HTTP API REST操作

创建名为mydb的数据库:

$ curl -G http://localhost:8086/query --data-urlencode "q=CREATE DATABASE mydb"

插入数据库:

$ curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'

2.2.2. 基于influx CLI管理工具

// 启动容器,执行命令
$ docker run --name=influxdb -d -p 8086:8086 influxdb
$ docker exec -it influxdb influx

// 在其他容器中,需要保证网络互通,
$ docker run --rm --link=influxdb -it influxdb influx -host influxdb

influx 客户端命令说明:

Usage of influx:
  -version  指定版本
  -host     连接主机
  -port     连接端口
  -socket   连接套接字
  -database 连接库名称
  -password 连接密码
  -username 连接用户名
  -ssl      基于https
  -unsafeSsl 使用https但不做检测
  -execute  执行命令
  -type     指定查询语言,'influxql|flux' 
  -format   指定输出输出格式,json|csv|column
  -precision 'rfc3339|h|m|s|ms|u|ns'
  -consistency 设置写入一致性级别,'any|one|quorum|all'
  -pretty   美化json格式输出
  -import   导入数据库
  -pps      导入每秒允许多少个点。默认情况下,它是零,不会限制导入。
  -path     导入的路径
  -compressed 是否是压缩导入的文件

3. InfluxDB的关键概念

在深入了解InfluxDB之前,熟悉数据库的一些关键概念是很好的,文档简要介绍了这些概念和通用的InfluxDB术语

3.1. measurement - 样本度量

  • database: 样本数据库
  • point: 指代样本集中的点
  • measurement: 指代样本度量
  • series: 样本系列
  • tag-set、tag-key、tag-val:样本集,样本标签key,样本标签val
  • field-set、field-key、field-val:选项领域集、领域key,定于val
  • timestamp: 时间
  • retention: 保留政策

思考一个样本统计的问题:在2015年某个时间段,科学家A、B,针对区域1、2两个位置,进行蝴蝶和蜜蜂的数量统计汇总

time(timestamp) butterflies(field-key) honeybees(field-key) location(tag-key) scientist(tag-key)
2015-08-18T00:00:00Z 12 23 1 langstroth
2015-08-18T00:00:00Z 1 30 1 perpetua
2015-08-18T00:06:00Z 11 28 1 langstroth
2015-08-18T00:06:00Z 3 28 1 perpetua
2015-08-18T05:54:00Z 2 11 2 langstroth
2015-08-18T06:00:00Z 1 10 2 langstroth
2015-08-18T06:06:00Z 8 23 2 perpetua
2015-08-18T06:12:00Z 7 22 2 perpetua

以上数据中:

  • point: 基于单条时间记录,作为样本集的一个点
  • time: 样本记录时间,所有的InfluxDB都有该字段
  • fields: butterflies、honeybees
    • field值可以为:strings, floats, integers, or Booleans,
    • field总是与字段值相关关联,field字段键和字段值对的集合构成字段集(field set)
    • Field是InfluxDB数据结构的必需部分,如果没有字段,则不能在InfluxDB中拥有数据。
    • Field字段是未编入索引的,使用字段值作为过滤器的查询必须扫描与查询中的其他条件匹配的所有值,因此,这些查询相对于标记上的查询不具有高性能,通常,字段不应包含常用查询元数据。
  • tags: location、scientist
    • 样本数据中的最后两列(称为位置和科学家)是标记。
    • 标签由标签键和标签值组成,标记键和标记值都存储为字符串和记录元数据。
  • field set:
    • butterflies = 12 honeybees = 23
    • butterflies = 1 honeybees = 30
    • butterflies = 11 honeybees = 28
    • butterflies = 3 honeybees = 28
    • butterflies = 2 honeybees = 11
    • butterflies = 1 honeybees = 10
    • butterflies = 8 honeybees = 23
    • butterflies = 7 honeybees = 22
  • tag set:
    • location = 1, scientist = langstroth
    • location = 2, scientist = langstroth
    • location = 1, scientist = perpetua
    • location = 2, scientist = perpetua
  • measurement:比如我们定为census(统计调查),测量名称是字符串,对于任何SQL用户,测量在概念上类似于表
    • 用作标记tags,字段fields和时间time的容器,度量名称是存储在关联字段中的数据的描述。

标签是可选的,虽然不需要在数据结构中包含标记,但通常最好使用它们,因为与字段不同,标记是索引的,这意味着标签上的查询更快,并且该标签非常适合存储常用查询元数据。考虑查询:

  • SELECT * FROM “census” WHERE “butterflies” = 1
  • SELECT * FROM “census” WHERE “honeybees” = 23

由于butterflies、honeybees之前都是field,则查询需要扫表,若重新调整tag与field,将butterflies、honeybees设置为tag,location、scientist设置为field,则influx查询会更快(无需扫表)

3.2. retention policy- 数据保留策略

一份测量数据,measurement我们可以以不同的保留策略,保留策略描述了如何保存(数据持久化)以及多少备份存在在集群中(数据复制)

3.3. series - 样本测量、数据保存策略、tag set的集合

在InfluxDB中,系列是保留策略(retention policy),度量(measurement)和标记集(tag set)的数据集合。在设计模式和在InfluxDB中处理数据时,理解系列的概念至关重要。

Arbitrary series number Retention policy Measurement Tag set
series 1 autogen census location = 1,scientist = langstroth
series 2 autogen census location = 2,scientist = langstroth
series 3 autogen census location = 1,scientist = perpetua
series 4 autogen census location = 2,scientist = perpetua

3.4. 数据库存储格式说明

格式参考:

// 注意field-key前面的空格!
<measurement>[,<tag-key>=<tag-value>...] <field-key>=<field-value>[,<field2-key>=<field2-value>...] [unix-nano-timestamp]

InfluxDB是一个无模式数据库,您可以随时添加新的测量,标签和字段。请注意,如果尝试使用与以前使用的类型不同的类型编写数据(例如,将字符串写入先前接受整数的字段),InfluxDB将拒绝这些数据。

相关内容查看,注意需要先进入到指定DB(use test_db):

show databases        show database names
show series           show series information
show measurements     show measurement information
show tag keys         show tag key information
show field keys       show field key information

// 插入数据(census:代表measurement;scientist=langstroth,location=1:代表tags键值对;空格:分割tags和fields;
  butterflies=12,honeybees=23:代表fields)
> create database_db
> insert census,scientist=langstroth,location=1 butterflies=12,honeybees=23
> show tag keys
name: census
tagKey
------
location
scientist
> show field keys
name: census
fieldKey    fieldType
--------    ---------
butterflies float
honeybees   float

3.5. InfluxDB和SQL数据库的一些区别

相关区别点 InfluxDB SQL数据库
数据库特点 InfluxDB旨在处理时间序列数据,InfluxDB可以存储大量的时间序列数据,并快速对这些数据进行实时分析 SQL数据库通常不单为此而实现
数据库DDL InfluxDB不必预先定义模式(DDL) SQL数据库需要提前做DDL定义数据存储结构信息
基本SQL 支持类似SQL的操作简单语法,诸如SHOW、CREATE DATABASE、SELECT、DELETE、GRANT、GROUP BY、LIIMIT等 SQL语法支持
JOIN支持 不支持JOIN SQL语法支持
性能提升 continuous queriesretention policies 存储过程
用户权限管控 支持数据库、用户创建、授权 SQL语法支持
聚合、数学函数支持 支持:https://docs.influxdata.com/influxdb/v1.7/query_language/functions/ SQL语法支持
CRUD说明 更像CR-ud,弱化更新和删除 强CRUD

3.6. InfluxDB设计见解和权衡

  1. 针对重复数据,简化的冲突解决方案可提高写入性能。
  2. 限制point删除,提高查询和写入性能。
  3. 限制point更新,提高查询和写入性能。
  4. 按时间升序添加数据的性能要高得多
  5. 能够处理大容量的读取和写入。
  6. 如果数据库负载很重,查询返回可能不包括最近的点
  7. 擅长管理不连续数据,没有表JOIN连接。
  8. point没有传统意义上的ID,们按时间戳和系列区分。

3.7. InfluxDB存储引擎

InfluxDB存储引擎这块涉及较多的数据结构和概念,诸如LSM Tree、B+Tree、TSM Tree(Time Structured Merge Tree)、Write Ahead Log (WAL)(日志预写)等概念,这块需要深入了解参见1

4. influx 客户端命令操作示例

4.1. 客户端连接

// 数据库连接
influx -database 'metrics' -host 'localhost' -port '8086'

// 数据库查询
influx -database 'metrics' -execute 'select * from cpu' -format 'json' -pretty

4.2. 帮助文档

// 版本
influx -version
InfluxDB shell version: 1.7.6
Enter an InfluxQL query

// 指定时间精度,以RFC3339格式(YYYY-MM-DDTHH:MM:SS.nnnnnnnnnZ)返回时间戳。
influx -precision rfc3339
Connected to http://localhost:8086 version 1.7.6
InfluxDB shell version: 1.7.6
Enter an InfluxQL query
> help
> SHOW DATABASES // 显示库
> show tag keys  // 显示标签键
> show series    // 显示系列信息
> ...
> exit/quit/ctrl+d 退出

4.3. 数据库创建和删除

//创建库
> CREATE DATABASE statusok 
//使用库
> USE statusok   
// 数据库删除
> DROP DATABASE statusok

4.4. 数据库插入

// measurement为cpu,host为tag-key,region为field-key被写入到数据库中!
> INSERT cpu,host=serverA,region=us_west value=0.64

4.5. 数据库查询、分组和排序,以及正则查询

InfluxQL是一种类似SQL的查询语言,用于与InfluxDB中的数据进行交互。

InfluxQL的SELECT查询语法:

// 查询语法
SELECT_clause [INTO_clause] FROM_clause [WHERE_clause] [GROUP_BY_clause] ORDER BY time DESC

【简单查询】
> SELECT "host", "region", "value" FROM "cpu"
// 没有LIMIT的查询,带来性能开销问题(插入关键字不区分大小写,允许自动缺失)
> select * from temperature where internal=1
// 查多个measurement,以及条件查询
> SELECT * FROM /.*/ LIMIT 1
// WEHERE 条件查询
> SELECT * FROM temperature WHERE internal = 33
> SELECT * FROM temperature WHERE internal > 33 AND internal < 38
// 排序
> SELECT "water_level" FROM "h2o_feet" WHERE "location" = 'santa_monica' ORDER BY time DESC

【使用正则表达式】
SELECT /<regular_expression_field_key>/ FROM /<regular_expression_measurement>/ WHERE [<tag_key> <operator> /<regular_expression_tag_value>/ | <field_key> <operator> /<regular_expression_field_value>/] GROUP BY /<regular_expression_tag_key>/

> SELECT MEAN(water_level) FROM "h2o_feet" WHERE "location" =~ /[m]/ AND "water_level" > 3

4.6. 数据库子查询

> SELECT "all_the_means" FROM (SELECT MEAN("water_level") AS "all_the_means" FROM "h2o_feet" WHERE time >= '2015-08-18T00:00:00Z' AND time <= '2015-08-18T00:30:00Z' GROUP BY time(12m) ) WHERE "all_the_means" > 5

4.7. 数据库函数操作

> SELECT MEAN("water_level") AS "all_the_means" FROM "h2o_feet" WHERE time >= '2015-08-18T00:00:00Z' AND time <= '2015-08-18T00:30:00Z' GROUP BY time(12m)

> SELECT SUM("water_level_derivative") AS "sum_derivative" FROM (SELECT DERIVATIVE(MEAN("water_level")) AS "water_level_derivative" FROM "h2o_feet" WHERE time >= '2015-08-18T00:00:00Z' AND time <= '2015-08-18T00:30:00Z' GROUP BY time(12m),"location") GROUP BY "location"

5. 通过http操作InfluxDB数据库示例

5.1. 支持基于HTTP的数据传输协议

现代Web API已经确定了REST,因为它解决了常见的需求。随着端点数量的增加,对组织系统的需求变得迫切。REST是用于组织大量端点的行业认可的样式。这种一致性对于开发和使用API​​的人来说是好的:所涉及的每个人都知道会发生什么。

然而,REST是一种惯例。InfluxDB使用三个API端点。这个简单易懂的系统使用HTTP作为InfluxQL的传输方法。InfluxDB API不会尝试RESTful。

5.2. HTTP响应部分说明

  • 2xx:如果收到您的写请求HTTP 204 No Content,则表示成功!
  • 4xx:InfluxDB无法理解请求。(比如往一个bool中插入了浮点,则会响应400;往不存在的数据库中插入数据,则会引起404错误!)
  • 5xx:系统过载或严重受损。

涉及相关参数:

  • GET:SELECT、SHOW操作
  • POST:ALTER、CREATE、DELETE、DROP、GRANT、KILL、REVOKE等操作

5.3. 数据库创建

curl -i -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE mydb"

5.4. 数据库插入

// 单条插入
curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'

// 批量插入,通过新行分割插入内容
curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server02 value=0.67
cpu_load_short,host=server02,region=us-west value=0.55 1422568543702900257
cpu_load_short,direction=in,host=server01,region=us-west value=2.0 1422568543702900257'

5.5. 从文件导入数据到数据库

[文件cpu_data.txt]
cpu_load_short,host=server02 value=0.67
cpu_load_short,host=server02,region=us-west value=0.55 1422568543702900257
cpu_load_short,direction=in,host=server01,region=us-west value=2.0 1422568543702900257

// 基于文件导入
curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary @cpu_data.txt

5.6. 数据库查询

// 单条查询
curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=mydb" --data-urlencode "q=SELECT \"value\" FROM \"cpu_load_short\" WHERE \"region\"='us-west'"

// 多条查询
curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=mydb" --data-urlencode "q=SELECT \"value\" FROM \"cpu_load_short\" WHERE \"region\"='us-west';SELECT count(\"value\") FROM \"cpu_load_short\" WHERE \"region\"='us-west'"

6. 认证和授权

不应依赖身份验证和授权来阻止访问并保护数据免受恶意攻击者的攻击。如果需要其他安全性或合规性功能,InfluxDB应该在第三方服务后面运行。

6.1. 认证

InfluxDB的HTTP API和命令行界面(CLI)使用API​​连接到数据库,包括基于用户凭据的简单内置身份验证。

6.1.1. 设置身份验证

  1. 创建至少一个管理员用户
  2. 开启配置认证,默认情况下,配置文件中禁用身份验证:auth-enabled = true
  3. 重启服务
  4. 验证请求

6.1.2. http验证(两种选择)

// 首选方式,-u指定 user:pass
curl -G http://localhost:8086/query -u todd:influxdb4ever --data-urlencode "q=SHOW DATABASES"

// 通过get或post参数传递
curl -G "http://localhost:8086/query?u=todd&p=influxdb4ever" --data-urlencode "q=SHOW DATABASES"
curl -G http://localhost:8086/query --data-urlencode "u=todd" --data-urlencode "p=influxdb4ever" --data-urlencode "q=SHOW DATABASES"

HTTP认证错误:

  • 401:无账号或密码错误,没有身份验证凭据或凭据不正确的请求会产生HTTP 401 Unauthorized响应。
  • 403:未经授权,未经授权用户的请求会产生HTTP 403 Forbidden响应。

6.1.3. cli验证(三种选择)

// 使用`INFLUX_USERNAME`和`INFLUX_PASSWORD`环境变量进行身份验证
export INFLUX_USERNAME todd
export INFLUX_PASSWORD influxdb4ever
influx

// 在启动CLI时设置username和password标记进行身份验证
influx -username todd -password influxdb4ever

// 启动CLI后进行身份验证
auth <username> <password>

6.2. 授权2

只有在启用身份验证(auth-enabled = true)后才会强制执行授权,默认情况下,禁用身份验证,静默忽略所有凭据,并且所有用户都具有所有权限。

6.2.1. 用户类型和权限

管理员用户,拥有所有库的读写权限:

  • CREATE DATABASE, DROP DATABASE
  • DROP SERIES,DROP MEASUREMENT
  • CREATE RETENTION POLICY, ALTER RETENTION POLICY, DROP RETENTION POLICY
  • CREATE CONTINUOUS QUERY, DROP CONTINUOUS QUERY
  • 用户管理权限
    • 管理员管理:CREATE USER, GRANT ALL PRIVILEGES, REVOKE ALL PRIVILEGES, and SHOW USERS
    • 非管理员管理:CREATE USER, GRANT [READ,WRITE,ALL], REVOKE [READ,WRITE,ALL], and SHOW GRANTS
    • 普通用户管理:SET PASSWORD and DROP USER

非管理员用户,针对每个库有3类权限,可以通过SHOW命令查看:

  • 读权限
  • 写权限
  • 读写权限

6.2.2. 用户管理命令

创建用户以及认证的一些限制:

  • 用户名,如果已数字或者包含特殊字符,需要以双引号包裹!
  • 密码,必须以单引号包裹!
  • 认证的时候,不需要单引号;
  • 重复的用户名创建,是幂等的,不然直接报错;
【创建用户】
// 开启HTTP认证,需要至少一个管理员用户,创建账号是幂等的!
CREATE USER todd WITH PASSWORD 'passwd' WITH ALL PRIVILEGES
// 创建普通用户
CREATE USER developer WITH PASSWORD 'passwd'
// 显示所有用户
SHOW USERS

【授权用户】
// 授权给指定用户
GRANT ALL PRIVILEGES TO "todd"
// 收回权限
REVOKE ALL PRIVILEGES FROM "todd"
// 授权指定权限给到用户
GRANT [READ,WRITE,ALL] ON <database_name> TO <username>
> grant write on mydb to developer
> grant read on mydb to developer
> grant all on mydb to developer
> show grants for developer

【密码更改】
> set password for developer = '123456'

【删除用户】
DROP USER TODD

7. 配置文件

7.1. 存储位置

  • Linux: /etc/influxdb/influxdb.conf
  • macOS: /usr/local/etc/influxdb.conf
influxd -config /etc/influxdb/influxdb.conf

7.2. 基本单位

  • ns       nanoseconds
  • us or µs microseconds
  • ms       milliseconds
  • s      seconds
  • m      minutes
  • h      hours
  • d      days
  • w      weeks

7.3. 配置环境变量

  • INFLUXDB_*开始的变量,比如INFLUXDB_CONFIG_PATH
  • GOMAXPROCS,go语言中的处理器设定,与处理器核心绑定一致

7.4. 配置应用服务变量

比如数据存储位置、分片策略、监控策略、HTTP端点、查询管理等,更多参见参考部分3

8. 小结

文章内容简单介绍了InfluxDB的特点以及其关键的概念,以科学家统计昆虫的样本测量,解释了什么是测量读、标签集、字段集,以及保存策略和series系列;

随后,类似于Mysql的操作,进行数据的基本用户的授权和认证管控,以及从HTTP和CLI两个方面,对InfluxDB进行简单的SQL查询和管理操作;

最后,针对InfluxDB的配置简要过了下,希望整体对InfluxDB有个初步的了解!

9. 参考

  • influxdb,身份认证和授权管理:https://docs.influxdata.com/influxdb/v1.7/administration/authentication_and_authorization/
  • influxdb,API文档:https://docs.influxdata.com/influxdb/v1.7/tools/api/
  • influxdb,查询语言:https://docs.influxdata.com/influxdb/latest/query_language/spec/
  • influxdb,
  • influxdb,术语:https://docs.influxdata.com/influxdb/v1.7/concepts/glossary/#series

  1. InfluxDB存储引擎:https://docs.influxdata.com/influxdb/v1.7/concepts/storage_engine/ ↩︎

  2. 数据库管理: https://docs.influxdata.com/influxdb/v1.7/query_language/database_management/ ↩︎

  3. 配置inflduxdb: https://docs.influxdata.com/influxdb/v1.7/administration/config/ ↩︎