背景介绍
InfluxDB是一个由InfluxData开发的开源时序型数据库,专注于海量时序数据的高性能读、高性能写、高效存储与实时分析等,在DB-Engines Ranking时序型数据库排行榜上排名第一,广泛应用于DevOps监控、IoT监控、实时分析等场景。
InfluxDB部署简单、使用方便,在技术实现上充分利用了Go语言的特性,无需任何外部依赖即可独立部署。提供类似于SQL的查询语言,接口友好,使用方便。丰富的聚合运算和采样能力,提供灵活的数据保存策略(Retention Policy)来设置数据的保留时间和副本数,在保障数据可靠性的同时,及时删除过期数据,释放存储空间,提供灵活的连续查询(Continues Query)来实现对海量数据的采样。支持协议种类多,除了HTTP、UDP等原生协议,还兼容CollectD、Graphite、OpenTSDB、Prometheus等组件的通讯协议。
下载
windos 1.8.1版本安装包下载地址
https://dl.influxdata.com/influxdb/releases/influxdb-1.8.1_windows_amd64.zip
开启服务
InfluxDB的HTTP接口默认起在8086上,所以influx默认也是连的本地的8086端口,你可以通过influx --help来看怎么修改默认值。
数据库管理
数据管理
第一次安装好InfluxDB之后是没有数据库的(除了系统自带的_internal),因此创建一个数据库是我们首先要做的事,通过CREATE DATABASE 这样的InfluxQL语句来创建,其中就是数据库的名字。数据库的名字可以是被双引号引起来的任意Unicode字符。 如果名称只包含ASCII字母,数字或下划线,并且不以数字开头,那么也可以不用引起来
CREATE DATABASE <database_name> [WITH [DURATION <duration>] [REPLICATION <n>] [SHARD DURATION <duration>] [NAME <retention-policy-name>]]
-- 创建数据库
CREATE DATABASE <DATABASE_NAME>;
create database mydb;
-- 该语句创建了一个叫做NOAA_water_database的数据库,并且创建了liquid作为数据库的默认保留策略,其持续时间为3天,副本数是1,shard group的持续时间为一个小时
CREATE DATABASE "NOAA_water_database" WITH DURATION 3d REPLICATION 1 SHARD DURATION 1h NAME "liquid"
-- 删除数据库
DROP DATABASE <DATABASE_NAME>
drop database mydb;
-- 用DROP从索引中删除series
DROP SERIES FROM <measurement_name[,measurement_name]> WHERE <tag_key>='<tag_value>'
-- 从单个measurement删除所有series
DROP SERIES FROM "h2o_feet"
-- 从单个measurement删除指定tag的series
DROP SERIES FROM "h2o_feet" WHERE "location" = 'santa_monica'
-- 数据库删除有指定tag的所有measurement中的所有数据
DROP SERIES WHERE "location" = 'santa_monica'
-- 用DELETE删除series
-- DELETE删除数据库中的measurement中的所有点。与DROP SERIES不同,它不会从索引中删除series,并且它支持WHERE子句中的时间间隔。
DELETE FROM <measurement_name> WHERE [<tag_key>='<tag_value>'] | [<time interval>]
DELETE FROM "h2o_feet"
DELETE FROM "h2o_quality" WHERE "randtag" = '3'
DELETE WHERE time < '2016-01-01'
-- 删除measurement
DROP MEASUREMENT <measurement_name>
-- 删除shard
DROP SHARD <shard_id_number>
说明:在输入上面的语句之后,并没有看到任何信息,这在CLI里,表示语句被执行并且没有错误,如果有错误信息展示,那一定是哪里出问题了,这就是所谓的没有消息就是好消息。
-- 查看数据库
SHOW DATABASES;
-- 使用数据库
-- USE <DATABASE_NAME>;
use mydb
说明:_internal数据库是用来存储InfluxDB内部的实时监控数据的。
保留策略管理
创建数据库时,InfluxDB会自动创建一个名为autogen的保留策略,该保留策略保留时间为无限。您可以重命名该保留策略或在配置文件中禁用其自动创建。
-- 创建保留策略
CREATE RETENTION POLICY <retention_policy_name> ON <database_name> DURATION <duration> REPLICATION <n> [SHARD DURATION <duration>] [DEFAULT]
语法描述
DURATION
DURATION子句确定InfluxDB保留数据的时间。 是持续时间字符串或INF(无限)。 保留策略的最短持续时间为1小时,最大持续时间为INF。
REPLICATION
REPLICATION子句确定每个点的多少独立副本存储在集群中,其中n是数据节点的数量。该子句不能用于单节点实例。
SHARD DURATION
SHARD DURATION子句确定shard group覆盖的时间范围。 是一个持续时间字符串,不支持INF(无限)持续时间。此设置是可选的。 默认情况下,shard group持续时间由保留策略的DURATION决定:
保留策略的持续时间 | shard group的持续时间 |
< 2天 | 1小时 |
>= 2天并<=6个月 | 1天 |
> 6个月 | 7天 |
最小允许SHARD GROUP DURATION为1小时。 如果CREATE RETENTION POLICY查询尝试将SHARD GROUP DURATION设置为小于1小时且大于0,则InfluxDB会自动将SHARD GROUP DURATION设置为1h。 如果CREATE RETENTION POLICY查询尝试将SHARD GROUP DURATION设置为0,InfluxDB会根据上面列出的默认设置自动设置SHARD GROUP DURATION。
DEFAULT
将新的保留策略设置为数据库的默认保留策略。此设置是可选的。
创建一个保留策略
该语句给数据库NOAA_water_database创建一个保留策略one_day_only,持续时间为1天,副本数为1
CREATE RETENTION POLICY "one_day_only" ON "NOAA_water_database" DURATION 1d REPLICATION 1
修改保留策略
ALTER RETENTION POLICY形式如下,你必须至少指定一个属性:DURATION, REPLICATION, SHARD DURATION,或者DEFAULT:
ALTER RETENTION POLICY <retention_policy_name> ON <database_name> DURATION <duration> REPLICATION <n> SHARD DURATION <duration> DEFAULT
CREATE RETENTION POLICY "what_is_time" ON "NOAA_water_database" DURATION 2d REPLICATION 1
ALTER RETENTION POLICY "what_is_time" ON "NOAA_water_database" DURATION 3w SHARD DURATION 30m DEFAULT
删除保留策略
删除指定保留策略的所有measurement和数据:
DROP RETENTION POLICY <retention_policy_name> ON <database_name>
行协议
InfluxDB的行协议是一种写入数据点到InfluxDB的文本格式。必须要是这样的格式的数据点才能被Influxdb解析和写入成功,当然除非你使用一些其他服务插件。
语法
-- 至少有一个 field,零个或多个 tag
database -> measurement -> point(time、tags、fields)
-- 插入语法
-- 一行 Line Protocol 表示 InfluxDB 中的一个数据点,它向 InfluxDB 通知点的 measurement、tag set、field set和 timestamp,例如
weather,location=us-midwest temperature=82 1465839830100400200
| -------------------- -------------- |
| | | |
| | | |
+-----------+--------+-+---------+-+---------+
|measurement|,tag_set| |field_set| |timestamp|
+-----------+--------+-+---------+-+---------+
Tag set
-- 你想要数据点中包含的tag,tag在行协议里是可选的,measurement和tag set是用不带空格的逗号分开的,
-- 用不带空格的=来分割一组tag的键值
<tag_key>=<tag_value>
-- 多组tag直接用不带空格的逗号分开
<tag_key>=<tag_value>,<tag_key>=<tag_value>
Field set
-- 每个数据点在行协议中至少需要一个field。使用无空格的=分隔field的键值对
<field_key>=<field_value>
-- 多组field直接用不带空格的逗号分开:
<field_key>=<field_value>,<field_key>=<field_value>
-- 分离measurement和field set,或者如果您使用数据点包含tag set,则使用空格分隔tag set和field set,没有tag set的有效行协议
weather temperature=82 1465839830100400200
-- 使用空格分隔field set和可选的时间戳。如果你包含时间戳,则行协议中需要空格。
Timestamp
数据点的时间戳记以纳秒精度Unix时间。行协议中的时间戳是可选的。 如果没有为数据点指定时间戳,InfluxDB会使用服务器的本地纳秒时间戳。
数据类型
-- measurement、tag keys、tag values、field keys始终是字符串
-- Field value可以是整数、浮点数、字符串和布尔值
-- 浮点数 —— 默认是浮点数,InfluxDB假定收到的所有field value都是浮点数
-- 整数 —— 添加一个i在field之后,告诉InfluxDB以整数类型存储
-- 字符串 —— 双引号把字段值引起来表示字符串
-- 布尔型 —— 表示TRUE可以用t,T,true,True,TRUE;表示FALSE可以用f,F,false,False或者FALSE
-- 时间戳不要双或单引号
-- field value不要单引号,即使是字符串类型
-- 当Field value是字符串时,使用双引号
-- measurement名称,tag keys,tag value和field key不用单双引号。InfluxDB会假定引号是名称的一部分
-- 当field value是整数,浮点数或是布尔型时,不要使用双引号,不然InfluxDB会假定值是字符串类型
综上所述:
measurement 与 tag 之间用 , 分割,tag 和 field 之间用 空格 分离, tag 和 tag,field 和 field 之间用 , 分割,filed 和 timestamp 之间用 空格分隔。
-- 插入 tag、field、timestamp
insert measurement,tag_key1=tag_v1,tag_key2=tag_v2 field_key1=field_v1,field_key2=field_v2 timestamp
-- 插入 field、timestamp
insert measurement field_key1=field_value1,field_key2=field_value2,field_key3=field_value3 timestamp
-- 插入 field、timestamp
insert measurement field_float_key1=field_value1,field_int_key2=field_value2i,field_string_key3="field_value3" timestamp
实例
use mydb;
-- 创建表 user表+数据
> insert user,id=1,name=zhangsan age=20i,hobby="CSGO"
> insert user,id=2,name=lisi age=22i,hobby="LOL、CF"
> insert user,id=3,name=wangwu age=18i
Scheme查询语法
-- 返回指定数据库的measurement列表
SHOW MEASUREMENTS [ON "<DATABASE_NAME>"];
-- 删除指定measurement的所有数据和series,并且从索引中删除measurement
DROP MEASUREMENT <measurement_name>
-- 查看数据库的tag key列表
SHOW TAG KEYS [ON "<DATABASE_NAME>"] [FROM "<MEASUREMENT_NAME>" WHERE ...]
SHOW TAG VALUES [ON "<DATABASE_NAME>"] WITH KEY = "name"
-- 返回field key以及其field value的数据类型
SHOW FIELD KEYS [ON "<DATABASE_NAME>"] [FROM "<MEASUREMENT_NAME>" WHERE ...];
ON 是可选的。如果查询不包括ON ,则必须在CLI中使用USE 指定数据库,或者在HTTP API请求中指定db查询字符串参数。
WITH,WHERE,LIMIT和OFFSET子句是可选的。 WHERE子句支持tag比较; field比较对SHOW MEASUREMENTS查询无效。
数据查询语法
> insert user,id=1,name=zhangsan age=20i,hobby="CSGO"
> insert user,id=2,name=lisi age=22i,hobby="LOL、CF"
> insert user,id=3,name=wangwu age=18i
> insert role,uid=001,name=admin remark="管理员",grade=1i
> insert role,uid=002,name=manager remark="管理者",grade=2i
> insert role,uid=003,name=normal grade=3i
SELECT <field_key>[,<field_key>,<tag_key>] FROM <measurement_name>[,<measurement_name>]
-- select 在包含 tag 时必须 至少指定一个 field
-- 1.从单个measurement中查询特定tag和field
select "id","hobby" from "user"
-- 2.从单个measurement中选择特定的tag和field,并提供其标识符类型
-- 若 field 字段为空,则该条记录不显示
select "id"::tag, "hobby"::field from "user"
-- 3.从单个measurement查询所有field
select *::field from "user"
-- 4.从measurement中选择一个特定的field并执行基本计算
select ("age"::field * 2) + 4 from "user"
-- 5. 选择多表
select * from "user","role"
-- 6.从特定的数据库中查询多表数据
select * from "mydb".."user"
select * from "mydb"."autogen"."user"
-- 6.where
WHERE子句中的用单引号来把tag、field value引起来。未用单引号的tag或双引号的tag查询将不会返回任何数据,并且在大多数情况下不会返回错误
select * from "user" where "age" > 20
select * from "user" where "name"='lisi'
select * from "user" where "name"='lisi' or age > 20
select * from "user" where "name"='lisi' and age > 20
select * from "user" where time > now() -7d
-- 7. group by [tag]
select * from "user" group by "name"
select * from "user" group by "name","age"
select COUNT(*) from "cpu" WHERE time >= '2023-01-05T00:00:00Z' AND time <= '2023-01-07T00:30:00Z' GROUP BY time(10m) # 对 where 条件过滤的数据,每10分钟划分为一组
-- 8.查询或插入数据时指定时区
-- https://www.cnblogs.com/itdragon/p/11608812.html
SELECT * FROM "user" tz('Asia/Shanghai')
-- 9.order by 和 limit
-- 该语法同mysql一致
select * from "user" order by time desc limit 1
函数
InfluxDB的函数可以分成Aggregate,select和predict类型
Aggregations
COUNT() :返回非空字段值得数目
-- 计数指定field key的field value的数目
> select count("age") from "user"
name: user
time count
---- -----
0 3
-- 计数measurement中每个field key关联的field value的数量
> select count(*) from "user"
name: user
time count_age count_hobby
---- --------- -----------
0 3 2
DISTINCT():返回field value的不同值列表
-- 列出一个field key的不同的field value
> select distinct("hobby") from "user"
name: user
time distinct
---- --------
0 CSGO
0 LOL、CF
MEAN():返回字段的平均值
-- 计算指定字段的平均值
> select mean("age") from "user"
name: user
time mean
---- ----
0 20
-- 计算measurement中每个字段的平均值
> select mean(*) from "user"
name: user
time mean_age
---- --------
0 20
>
MEDIAN():返回排好序的字段的中位数
-- 计算指定字段的中位数
> select median("age") from "user"
name: user
time median
---- ------
0 20
-- 计算measurement中每个字段的中位数
> select median(*) from "user"
name: user
time median_age
---- ----------
0 20
MODE():返回字段中出现频率最高的值
-- 返回field key关联的值的出现频率最高的值。
> select mode("age") from "user"
name: user
time mode
---- ----
0 18
-- 返回满足正则表达式的每个field key关联的值的出现频率最高的值。
> select mode(*) from "user"
name: user
time mode_age mode_hobby
---- -------- ----------
0 18 CSGO
SPREAD():返回字段中最大和最小值的差值
-- 返回field key最大和最小值的差值
> select spread("age") from "user"
name: user
time spread
---- ------
0 4
-- 返回满足正则表达式的每个field key最大和最小值的差值
> select spread(*) from "user"
name: user
time spread_age
---- ----------
0 4
>
STDDEV():返回字段的标准差
SUM():返回字段值的和
Selectors
BOTTOM():返回最小的N个field值
-- 返回field key的最小的N个field value
BOTTOM(field_key,N)
-- 返回某个tag key的N个tag value的最小的field value
BOTTOM(field_key,tag_key(s),N)
-- 返回括号里的字段的最小N个field value,以及相关的tag或field,或者两者都有
BOTTOM(field_key,N),tag_key(s),field_key(s)
如果一个field有两个或多个相等的field value,BOTTOM()返回时间戳最早的那个
-- 选择一个field的最小的两个值
> select bottom("age",2) from "user"
name: user
time bottom
---- ------
1675229514606775400 20
1675229587332351800 18
-- 返回 tag::name 和 age 最小的两条记录
> select bottom("age","name",2) from "user"
name: user
time bottom name
---- ------ ----
1675229514606775400 20 zhangsan
1675229587332351800 18 wangwu
-- 返回 tag::name、tag::id 和 age 最小的两条记录
> select bottom("age",2), "name", "id" from "user"
name: user
time bottom name id
---- ------ ---- --
1675229514606775400 20 zhangsan 1
1675229587332351800 18 wangwu 3
FIRST():返回时间戳最早的值
-- 返回field key时间戳最早的值
FIRST(field_key)
-- 返回满足正则表达式的每个field key的时间戳最早的值
FIRST(/regular_expression/)
-- 返回measurement中每个field key的时间戳最早的值
FIRST(*)
-- 返回括号里的字段的时间戳最早的值,以及相关联的tag或field,或者两者都有
FIRST(field_key),tag_key(s),field_key(s)
FIRST()支持所有类型的field
-- 返回field key时间戳最早的值
> select first("age") from "user"
name: user
time first
---- -----
1675229514606775400 20
-- 列出一个measurement中每个field key的时间戳最早的值
> select first(*) from "user"
name: user
time first_age first_hobby
---- --------- -----------
0 20 CSGO
-- 返回field的最早的值,以及其相关的tag和field
> select first("age"), "name" from "user"
name: user
time first name
---- ----- ----
1675229514606775400 20 zhangsan
LAST():返回时间戳最近的值
> select last("age") from "user"
name: user
time last
---- ----
1675229587332351800 18
> select last(*) from "user"
name: user
time last_age last_hobby
---- -------- ----------
0 18 LOL、CF
> select last("age"), "name", "hobby" from "user"
name: user
time last name hobby
---- ---- ---- -----
1675229587332351800 18 wangwu
MAX():返回最大的字段值
> select max("age") from "user"
name: user
time max
---- ---
1675229563464391700 22
> select max(*) from "user"
name: user
time max_age
---- -------
1675229563464391700 22
> select max("age"), "name" from "user"
name: user
time max name
---- --- ----
1675229563464391700 22 lisi
MIN():返回最小的字段值
PERCENTILE():返回较大百分之N的字段值
选取某个字段中大于N%的这个字段值
如果一共有4条记录,N为10,则10%*4=0.4,四舍五入为0,则查询结果为空。N为20,则 20% * 4 = 0.8,四舍五入为1,选取的是4个数中最小的数。如果N为40,40% * 4 = 1.6,四舍五入为2,则选取的是4个数中第二小的数。由此可以看出N=100时,就跟MAX(field_key) 是一样的,而当N=50时,与MEDIAN(field_key) 在字段值为奇数个时是一样的
> select percentile("age", 30) from "user"
name: user
time percentile
---- ----------
1675229587332351800 18
> select percentile("age", 70) from "user"
name: user
time percentile
---- ----------
1675229514606775400 20
> select percentile("age", 100) from "user"
name: user
time percentile
---- ----------
1675229563464391700 22
TOP():返回最大的N个field值
> select top("age",2) from "user"
name: user
time top
---- ---
1675229514606775400 20
1675229563464391700 22
> select top("age", "id",2) from "user"
name: user
time top id
---- --- --
1675229514606775400 20 1
1675229563464391700 22 2
> select top("age",2), id from "user"
name: user
time top id
---- --- --
1675229514606775400 20 1
1675229563464391700 22 2
Transformations
CEILING():CEILING()已经不再是一个函数了,具体请查看Issue #5930。
CUMULATIVE_SUM():返回字段实时前序字段值的和
> select * from "user"
name: user
time age hobby id name
---- --- ----- -- ----
1675229514606775400 20 CSGO 1 zhangsan
1675229563464391700 22 LOL、CF 2 lisi
1675229587332351800 18 3 wangwu
> select cumulative_sum("age") from "user"
name: user
time cumulative_sum
---- --------------
1675229514606775400 20
1675229563464391700 42
1675229587332351800 60
DERIVATIVE:返回字段的相邻两个点的变化率
InfluxDB计算字段值之间的差并将结果转换为每unit变化率。unit参数是一个表示时间单位的字符,它是可选的。如果查询没有指定,则该unit默认为1秒(1s)
> select * from "user"
name: user
time age hobby id name
---- --- ----- -- ----
1675229514606775400 20 CSGO 1 zhangsan
1675229563464391700 22 LOL、CF 2 lisi
1675229587332351800 18 3 wangwu
-- (22 - 10)/ (1675229563464391700 - 1675229514606775400) time 需要将纳秒转化为秒
> select derivative("age") from "user"
name: user
time derivative
---- ----------
1675229563464391700 0.04093527583743377
1675229587332351800 -0.16758868303956984
> select derivative("age",1s) from "user"
name: user
time derivative
---- ----------
1675229563464391700 0.04093527583743377
1675229587332351800 -0.16758868303956984
参考文档
https://jasper-zhang1.gitbooks.io/influxdb/content/Query_language/functions.html