这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
一灰灰学InfluxDB
InfluxDB是什么?
InfluxDB是一个用于存储和分析时间序列数据的开源数据库。
主要特性有:
- 内置HTTP接口,使用方便
- 数据可以打标记,这样查询可以很灵活
- 类SQL的查询语句
- 安装管理很简单,并且读写数据很高效
- 能够实时查询,数据在写入时被索引后就能够被立即查出
- …
系列教程讲什么,可以收获什么
《一灰灰学InfluxDB》 记录了一灰灰当初学习并实际使用InfluxDB的全过程,其中包含两部分
基础系列教程
通过基础系列教程,相信对于influxdb的CURD对各位看官来说必定不在话下了,希望可以通过这一系列文章,减少各位小伙伴降低对于influxdb的上手难度,降低门槛
实战小技巧
这里将记录一些一灰灰个人在实际使用过程的可以用到的小技巧,主要是为了让我们更好的来使用它
1 - InfluxDb基础教程
时序数据库InfluxDB的基本使用姿势教程,手把手教你如何使用是时序数据库InfluxDB
1.1 - 01.安装及influx-cli使用姿势介绍
influxdb 时序数据库,因为实际业务中使用到了,然而并没有发现有特别好的文章,完整的介绍influx sql的使用姿势,因此记录下实际开发中学习的体会,主要参考来自于官方文档 Influx Query Language (InfluxQL)
influx已经推出2.0beta版本,并没有使用,后面的所有都是以1.7版本进行说明
I. 安装
安装教程,直接参考官网链接,installing-influxdb-oss,下面只介绍centos/macos两个操作系统的安装姿势
1. centos
通过yum包管理方式实现安装最新的稳定版, 在终端中输入
cat <<EOF | sudo tee /etc/yum.repos.d/influxdb.repo
[influxdb]
name = InfluxDB Repository - RHEL \$releasever
baseurl = https://repos.influxdata.com/rhel/\$releasever/\$basearch/stable
enabled = 1
gpgcheck = 1
gpgkey = https://repos.influxdata.com/influxdb.key
EOF
然后就可以按照常见的yum方式进行安装
sudo yum install influxdb
# 启动
sudo service influxdb start
# 7+ 版本可以使用 systemctl 方式启动
sudo systemctl start influxdb
2. macos
mac推荐通过homebrew方式进行安装,命令也比较简单
brew update
brew install influxdb
3. 相关配置
一般安装完毕之后,如果作为测试的话,直接使用并没有啥问题;但是实际的成产环境中,铁定是需要修改默认配置的
如果需要开启权限校验,访问时需要用户名密码时,可以参考: 190505-InfluxDB之权限管理
如果需要修改数据的存储位置,访问端口号等,可以参考: 190506-InfluxDB之配置修改
II. influx-cli
安装完毕之后,influx自带了一个控制台访问操作的工具: influx
,在正式进入后面的influxsql
之前,有必要了解一下这个工具如何使用,因为后面的sql,都是需要在它上面玩耍的
官方也给出了它的使用文档,有兴趣的可以参考: InfluxDB command line interface (CLI/shell)
1. 参数
默认情况下,我们直接在控制台输入 influx
之后就可以进入与influxdb交互的终端界面,如果我们修改了influx的默认配置,比如增加了用户名/密码时,这个时候可能需要使用参数来链接到influxdb了
下面给出几个常用的参数
参数 |
示例 |
说明 |
-username |
admin |
配置访问用户名 |
-password |
admin |
配置访问密码 |
-format |
json csv column |
格式化输出结果 |
-host |
localhost |
influxdb提供访问的域名或ip |
-port |
8086 |
influxdb提供访问的端口号 |
-precisoin |
rfc3339(h,m,s,ms,u,ns) |
指定time时间戳格式化 |
一个简单的使用case如下

2. 使用示例
上面的参数是在连接的时候直接指定了,这些参数在连接之后,也是可以再指定的,下面给出以下常用的使用姿势
a. help
直接输入help,会给出一些命令提示

b. auth
因为直接使用前面的方式输入用户名和密码的方式,并不安全,所以推荐的方式是直接influx进去之后,使用auth来权限校验,这种思路和redis-cli的差不多

c. pretty
是输出更加友好的方式,配合-format=json
的时候比较合适

注意pretty输入一次表示开启,再输入一次表示关闭
d. precision
时间戳格式化,对人更友好的显示方式
直接输入: precision rfc3339

e. history
influx-cli会保存历史命令(不包括auth),所以可以通过输入这个来查询之前的命令
f. 退出
三种方式
exit/quit/ctrl+d quits the influx shell
1.2 - 02.database 数据库
对于influxdb而言,database和我们更熟悉的mysql中的dababse没有什么特别的区别,可以将数据库简单理解为一堆表(measurement)的集合,接下来我们将看一下在influxdb中,database的常规操作
1. 查看当前数据库
如果需要查询当前有哪些数据库,可以通过show语句来实现

上面的_internal
是内置的数据库
2. 创建数据库
创建一个名为yhh的数据库

3. 使用数据库
如果需要查询某个measurement的数据时,首先需要进入到对应的数据库,直接使用use语句即可

4. 删除数据库
数据库的删除,需要慎重,因为会删除其中所有的数据,属于高危操作

1.3 - 03.retention policy 保存策略
retention policy这个东西相比较于传统的关系型数据库(比如mysql)而言,是一个比较新的东西,在将表之前,有必要来看一下保存策略有什么用,以及可以怎么用
I. 基本操作
1. 创建retention policy
retention policy
依托于database存在,也就是说保存策略创建时,需要指定具体的数据库,语法如下
CREATE RETENTION POLICY <retention_policy_name> ON <database_name> DURATION <duration> REPLICATION <n> [SHARD DURATION <duration>] [DEFAULT]
创建语句中,有几个地方需要额外注意一下
retention_policy_name
: 策略名(自定义的)
database_name
: 一个必须存在的数据库名
duration
: 定义的数据保存时间,最低为1h,如果设置为0,表示数据持久不失效(默认的策略就是这样的)
REPLICATION
: 定义每个point保存的副本数,默认为1
default
: 表示将这个创建的保存策略设置为默认的
下面是一个实际的case,创建一个数据保存一年的策略
create retention policy "1Y" on test duration 366d replication 1

2. 策略查看
上面演示的case中,已经有如何查看一个数据库的保存策略了
show retention policies on <database name>
3. 修改保存策略
修改一个已经存在的保存策略,语法如下
ALTER RETENTION POLICY <retention_policy_name> ON <database_name> DURATION <duration> REPLICATION <n> SHARD DURATION <duration> DEFAULT
上面的定义和前面创建基本一致,下面给出一个case

4. 删除保存策略
DROP RETENTION POLICY <retention_policy_name> ON <database_name>
当如下面的case,删除了默认的策略之后,会发现居然没有了默认的保存策略了,这个时候可能需要注意下,手动指定一个

II. 进阶说明
前面虽然介绍了保存策略的增删改查,但是这个东西究竟有什么用,又可以怎么用呢?
看一下前面查看保存策略的图

从前面的查看,可以看到保存策略主要有三个关键信息,数据保存时间
,数据分片时间
,副本数
1. 保存时间
duration 这一列,表示的就是这个策略定义的数据保存时间
因为我们知道每条记录都有一个time表明这条记录的时间戳,如果当前时间与这条记录的time之间差值,大于duration,那么这条数据就会被删除掉
注意
默认的保存策略autogen
中的duraiton=0
,这里表示这条数据不会被删除
2. 分片时间
简单理解为每个分片的时间跨度,比如上面的1_d
这个策略中,数据保存最近24小时的,每个小时一个分组
我们在创建数据策略的时候,大多时候都没有指定这个值,系统给出的方案如下
Retention Policy’s DURATION |
Shard Group Duration |
< 2 days |
1 hour |
>= 2 days and <= 6 months |
1 day |
> 6 months |
7 days |
3. 副本
副本这个指定了数据有多少个独立的备份存在
4. 场景说明
了解上面的几个参数之后,可以预见保存策略有个好的地方在于删除过期数据,比如使用influx来存日志,我只希望查看最近一个月的数据,这个时候指定一个duration
时间为30天的保存策略,然后添加数据时,指定这个保存策略,就不需要自己来关心日志删除的问题了
1.4 - 04.measurement 表
在influxdb中measurement相当于mysql中的表,可以理解为一条一条记录都是存与measurent中的,一个数据库中可以有多个measurement,一个measurement中可以存很多的数据。虽然可将measurement类比为mysql中的表,但是他们之间的差别也挺明显的
首先我们先了解一下measurement的几个常用命令,如何查看、新增删除
1. show measurements
查看一个数据库中有哪些measurement,属于常规操作了
- 先确定数据库
- 执行
show measurements
查看当前数据库的所有measurement
> use test
Using database test
> show measurements
name: measurements
name
----
yhh
我们也可以在不执行use databaseName
的时候,进行查看;而且还支持按名进行匹配,语法为
SHOW MEASUREMENTS [ON <database_name>] [WITH MEASUREMENT <regular_expression>] [WHERE <tag_key> <operator> ['<tag_value>' | <regular_expression>]] [LIMIT_clause] [OFFSET_clause]
下面给出查询指定数据库中,以yhh开头的所有measurement示例
> show measurements on test
name: measurements
name
----
doraemon
doraemon2
yhh
yhh2
> show measurements on test with measurement =~ /yhh*/
name: measurements
name
----
yhh
yhh2
2. 创建measurement
在influxdb中没有专门用来创建measurement的命令,在执行向某个measurement新增记录的时候,如果不存在measurement,则会新创建一个
下面是一条简单的演示case
# 像userInfo中新增一条记录,如果userInfo这个measurement不存在,则新建一个
> insert userInfo,name=一灰灰blog userId=10,blog="https://blog.hhui.top/"
> show measurements
name: measurements
name
----
doraemon
doraemon2
userInfo
yhh
yhh2
3. 删除measurement
两种方式,一个是把measurement里面的所有数据都删完,那么这个measurement就没了
> select * from userInfo
name: userInfo
time blog name userId
---- ---- ---- ------
1563712849953792293 https://blog.hhui.top/ 一灰灰blog 10
# 删除userInfo中的记录
> delete from userInfo where time=1563712849953792293
# 再次查看,发现userInfo已经被删除
> show measurements
name: measurements
name
----
doraemon
doraemon2
yhh
yhh2
>
另外一种方式就是直接使用drop measurement
命令实现删除
# 先创建userInfo
> insert userInfo,name=一灰灰blog userId=10,blog="https://blog.hhui.top/"
> show measurements
name: measurements
name
----
doraemon
doraemon2
userInfo
yhh
yhh2
# 直接使用drop语句删除
> drop measurement userInfo
> show measurements
name: measurements
name
----
doraemon
doraemon2
yhh
yhh2
>
4. 修改
不同于mysql中的表,measurement是没有修改操作的,从前面的创建操作也可以看出,对于measurement而言,也就只有一个名字,那如果我希望重命名现有的measurement,该怎么办?
原则上不建议这么干,如果确实有需要,可以用下面的方式来变相实现
> show measurements
name: measurements
name
----
doraemon
doraemon2
userInfo
yhh
yhh2
# 使用select into语句实现将查询结果保存到另外一个measurement中
> select * into userBaseInfo from userInfo
name: result
time written
---- -------
0 1
> show measurements
name: measurements
name
----
doraemon
doraemon2
userBaseInfo
userInfo
yhh
yhh2
> select * from userBaseInfo, userInfo
name: userBaseInfo
time blog name name_1 userId
---- ---- ---- ------ ------
1563713690876924095 https://blog.hhui.top/ 一灰灰blog 10
name: userInfo
time blog name name_1 userId
---- ---- ---- ------ ------
1563713690876924095 https://blog.hhui.top/ 一灰灰blog 10
>
1.5 - 05.series/point/tag/field
influxdb中的一条记录point,主要可以分为三类,必须存在的time(时间),string类型的tag,以及其他成员field;而series则是一个measurement中保存策略和tag集构成;本篇教程将介绍一些这几个概念
1. tag
influxdb数据结构中记录元数据(metadata)的kv对,不要求必须存在,tag key/value 都是字符串类型,而且会建立索引,因此基于tag进行查询效率比单纯的基于field进行查询是要高的;后续的一些sql也会发现,某些查询只能基于tag
重点提炼
常见的查询tag的语法如下
show tag keys on <database> from <measurement>
下面给出一个实际的例子, insert语句后面会说到,我们塞入的一条数据,指定name为tag,另外三个为field
> insert yhh,name=一灰灰 age=26,id=10,blog="http://blog.hhui.top"
> select * from yhh
name: yhh
time age blog id name
---- --- ---- -- ----
1563888301725811554 26 http://blog.hhui.top 10 一灰灰
> show tag keys from yhh
name: yhh
tagKey
------
name
上面是获取tag keys的查询方式,下面介绍下查询tag values的使用姿势
show tag values on <database> from <measurement> with KEY [ [<operator> "<tag_key>" | <regular_expression>] | [IN ("<tag_key1>","<tag_key2")]] [WHERE <tag_key> <operator> ['<tag_value>' | <regular_expression>]] [LIMIT_clause] [OFFSET_clause]
- with key 后面带上查询条件,必须存在,如查询汇率表中,base_symbol有哪些
- 连接符号可以为:等于
=
, 不等于:!=
, <>
, 正则:=~
, !~
> show tag values from currency_rate with key="base"
name: currency_rate
key value
--- -----
base AUD
base CAD
base CNY
base DKK
base EUR
base GBP
base HKD
base IDR
base INR
base JPY
base KRW
base NZD
base PHP
base PLN
base RUB
base SGD
base THB
base TRY
base UAH
base USD
2. field
成员,也可以理解为一条记录中,不需要建立索引的数据,一般来说,不太会有参与查询语句建设的可以设置为field
区别与tag,field有下面几个特性
查看field key的语句如下
show field keys on <database> from <measurement>
下面演示一下查看的姿势
> show field keys from yhh
name: yhh
fieldKey fieldType
-------- ---------
age float
blog string
id float
3. point
https://docs.influxdata.com/influxdb/v1.7/concepts/glossary/#point
在influxdb中,你可以将一条mysql中的记录简单的理解为一个point,它由四个组件
- measurement
- tag set
- field set
- timestamp
每个point是根据 timestamp + series
来保证唯一性。
关于point可以怎么理解呢?因为influxdb是时序数据库,简单来讲就是每个数据都是时间轴上的一个点,这些数据与时间强相关,其中的tag用来检索,field用来记录一些信息,measurement用来将相同类型的数据归集
4. series
https://docs.influxdata.com/influxdb/v1.7/concepts/glossary/#series
上面说到point的唯一性时,说到了series,这个概念又是啥呢?
官方的说明是:
The collection of data in the InfluxDB data structure that share a measurement, tag set, and retention policy.
influxdb中measurement + tags set + retention policy 组成的数据集合
直接看定义可能有点懵逼,官方提供查看series的命令如下
show series on <database> from <measurement>
下面是几个实例辅助说明
> insert yhh,name=一灰灰 age=26,id=10,blog="http://blog.hhui.top"
> insert yhh,name=一灰灰 age=30,id=11,blog="http://blog.hhui.top"
> select * from yhh;
name: yhh
time age blog id name
---- --- ---- -- ----
1563889538654374538 26 http://blog.hhui.top 10 一灰灰
1563889547738266214 30 http://blog.hhui.top 11 一灰灰
> show series on test from yhh
key
---
yhh,name=一灰灰
>
我们插入两个point
到yhh
这个measurement
中,但是他们的tag相同都是一灰灰
,此时我们查看series时,发现只有一条yhh,name=一灰灰
,包含measurement
和tag set
接下来我们试一下,新增一个tag,series是否会增加呢?
> insert yhh,name=一灰灰2 age=30,id=11,blog="http://blog.hhui.top"
> insert yhh,name=一灰灰3,phone=110 age=30,id=11,blog="http://blog.hhui.top"
> select * from yhh
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
1563889538654374538 26 http://blog.hhui.top 10 一灰灰
1563889547738266214 30 http://blog.hhui.top 11 一灰灰
1563889704754695002 30 http://blog.hhui.top 11 一灰灰2
1563889723440000821 30 http://blog.hhui.top 11 一灰灰3 110
> show series on test from yhh
key
---
yhh,name=一灰灰
yhh,name=一灰灰2
yhh,name=一灰灰3,phone=110
官方定义中series还与保存策略有关,前面两个case都是默认的保存测录,我们现在在新的保存策略中测试
> create retention policy "1D" on test duration 1d replication 1
> insert into "1D" yhh,name=一灰灰4 age=26,id=10,blog="http://blog.hhui.top"
> select * from yhh;
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
1563889538654374538 26 http://blog.hhui.top 10 一灰灰
1563889547738266214 30 http://blog.hhui.top 11 一灰灰
1563889704754695002 30 http://blog.hhui.top 11 一灰灰2
1563889723440000821 30 http://blog.hhui.top 11 一灰灰3 110
> select * from "1D".yhh
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
1563890614849474879 26 http://blog.hhui.top 10 一灰灰4
> show series
key
---
yhh,name=一灰灰
yhh,name=一灰灰2
yhh,name=一灰灰3,phone=110
yhh,name=一灰灰4
插入到"1D"保存策略中的point也构成了一个series: yhh,name=一灰灰4
注意
show series
预计中还支持基于tag
的where
查询,下面是一个简单的示例
show series from yhh where "name" = '一灰灰'
key
---
yhh,name=一灰灰
> show series from yhh where phone != ''
key
---
yhh,name=一灰灰3,phone=110
1.6 - 06.insert 添加数据
接下来开始进入influxdb的curd篇,首先我们看一下如何添加数据,也就是insert的使用姿势
在进入本篇之前,对于不了解什么是retention policy, tag, field的同学,有必要快速过一下这几个基本概念,可以参考文后的系列教程
I. Insert 使用说明
基本语法
insert into <retention policy> measurement,tagKey=tagValue fieldKey=fieldValue timestamp
1. 基本写数据姿势
当measurement不存在的时候,我们插入一条数据时,就会创建这个measurement
a. 基本case
下面给出一个简单的实例
insert add_test,name=YiHui,phone=110 user_id=20,email="bangzewu@126.com"
- 新增一条数据,measurement为
add_test
, tag为name
,phone
, field为user_id
,email
> show measurements
name: measurements
name
----
yhh
> insert add_test,name=YiHui,phone=110 user_id=20,email="bangzewu@126.com"
> show measurements;
name: measurements
name
----
add_test
yhh
> select * from add_test
name: add_test
time email name phone user_id
---- ----- ---- ----- -------
1564149327925320596 bangzewu@126.com YiHui 110 20
> show tag keys from add_test;
name: add_test
tagKey
------
name
phone
> show field keys from add_test;
name: add_test
fieldKey fieldType
-------- ---------
email string
user_id float
从上面的输出,简单小结一下插入的语句写法
insert
+ measurement
+ ","
+ tag=value,tag=value
+
+ field=value,field=value
- tag与tag之间用逗号分隔;field与field之间用逗号分隔
- tag与field之间用空格分隔
- tag都是string类型,不需要引号将value包裹
- field如果是string类型,需要加引号
b. field类型
我们知道field有四种类型,int
, float
, string
, boolean
,下面看一下插入数据时,四种类型如何处理
> insert add_test,name=YiHui,phone=110 user_id=21,email="bangzewu@126.com",age=18i,boy=true
> show field keys from add_test
name: add_test
fieldKey fieldType
-------- ---------
age integer
boy boolean
email string
user_id float
小结一下四种类型的指定方式
类型 |
方式 |
示例 |
float |
数字 |
user_id=21 |
int |
数字i |
age=18i |
boolean |
true/false |
boy=true |
String |
"" or '' |
email=“bangzewu@126.com” |
c. 时间戳指定
当写入数据不指定时间时,会自动用当前时间来补齐,如果需要自己指定时间时,再最后面添加上即可,注意时间为ns
> insert add_test,name=YiHui,phone=110 user_id=22,email="bangzewu@126.com",age=18i,boy=true 1564150279123000000
> select * from add_test;
name: add_test
time age boy email name phone user_id
---- --- --- ----- ---- ----- -------
1564149327925320596 bangzewu@126.com YiHui 110 20
1564149920283253824 18 true bangzewu@126.com YiHui 110 21
1564150279123000000 18 true bangzewu@126.com YiHui 110 22
2. 指定保存策略插入数据
前面写入数据没有指定保存策略,表示这条数据写入到默认的保存策略中;我们知道一个数据库可以有多个保存策略,一个measurement中也可以存不同的保存策略的数据,在写入数据时,如果需要指定保存策略,可以使用 insert into 保存策略 ...
> show retention policies on test
name duration shardGroupDuration replicaN default
---- -------- ------------------ -------- -------
autogen 0s 168h0m0s 1 true
1_d 24h0m0s 1h0m0s 1 false
1_h 1h0m0s 1h0m0s 1 false
> insert into "1_d" add_test,name=YiHui2,phone=911 user_id=23,email="bangzewu@126.com",age=18i,boy=true 1564150279123000000
> select * from add_test;
name: add_test
time age boy email name phone user_id
---- --- --- ----- ---- ----- -------
1564149327925320596 bangzewu@126.com YiHui 110 20
1564149920283253824 18 true bangzewu@126.com YiHui 110 21
1564150279123000000 18 true bangzewu@126.com YiHui 110 22
> select * from "1_d".add_test;
name: add_test
time age boy email name phone user_id
---- --- --- ----- ---- ----- -------
1564150279123000000 18 true bangzewu@126.com YiHui2 911 23
1.7 - 07.insert 修改数据
在influxdb中没有专门的修改数据的update
语句,对于influxdb而言,如果想修改数据,还是得使用我们前面的说到的insert
来实现,那么怎么判断一条insert语句是插入还是修改呢?
1. insert数据修改
关于insert的使用语法,可以参考上一篇博文:190726-Influx Sql系列教程五:insert 添加数据
这里只是贴一下基本语法
insert into <retention policy> measurement,tagKey=tagValue fieldKey=fieldValue timestamp
如果我们希望修改一条数据,比如修改既有的field,或者增加/删除field时,我们需要指定具体的时间戳和tag
下面是一个简单的修改演示
> select * from add_test where time=1564149327925320596
name: add_test
time age boy email name phone user_id
---- --- --- ----- ---- ----- -------
1564149327925320596 bangzewu@126.com YiHui 110 20
> show tag keys from add_test
name: add_test
tagKey
------
name
phone
> insert add_test,name=YiHui,phone=110 user_id=20,email="bangzewu@126.com",boy=true,age=18i 1564149327925320596
> select * from add_test where time=1564149327925320596
name: add_test
time age boy email name phone user_id
---- --- --- ----- ---- ----- -------
1564149327925320596 18 true bangzewu@126.com YiHui 110 20
在上面的case中,我们执行的的insert语句来修改某条已有的记录时,有几个参数必须存在
- time: 指定为要要改记录的时间戳
- tag: 所有的tag都必须和要修改的数据一致
name=YiHui,phone=110
然后field的内容,会增量修改之前的数据,如下
> insert add_test,name=YiHui,phone=110 boy=true,age=19i 1564149327925320596
> select * from add_test where time=1564149327925320596
name: add_test
time age boy email name phone user_id
---- --- --- ----- ---- ----- -------
1564149327925320596 19 true bangzewu@126.com YiHui 110 20
通过上面的insert,可以动态新增field,但是如果我希望删除field怎么办?
- 目前提供的
influxdb sql
中没有找到删除field的方式,一个可供选择的方式就是把原来的记录删掉;然后再重新插入一条
如果需要修改tag怎么办?
- 前面的case已经表明,修改记录是根据 time + tag values来唯一定位记录,然后执行删除的,如果你需要修改一个tag,对
insert
语句而言就是新增了一个point;这个时候可以考虑由自己来删除旧的数据
1.8 - 08.delete 删除数据
前面介绍了使用insert实现新增和修改记录的使用姿势,接下来我们看一下另外一个简单的使用方式,如何删除数据
1. delete 语句
delete的官方语法如下
DELETE FROM <measurement_name> WHERE [<tag_key>='<tag_value>'] | [<time interval>]
delete语句和我们常见sql语法有点像,但是注意一下上面的where中的条件,只允许根据tag和时间来进行删除操作
下面给出几个简单的例子
case1 根据时间删除
> select * from add_test
name: add_test
time age boy email name phone user_id
---- --- --- ----- ---- ----- -------
1564149327925320596 19 true bangzewu@126.com YiHui 110 0
1564149920283253824 18 true bangzewu@126.com YiHui 110 21
1564150279123000000 18 true bangzewu@126.com YiHui 110 22
> delete from add_test where time>=1564150279123000000
> select * from add_test
name: add_test
time age boy email name phone user_id
---- --- --- ----- ---- ----- -------
1564149327925320596 19 true bangzewu@126.com YiHui 110 0
1564149920283253824 18 true bangzewu@126.com YiHui 110 21
case2 根据tag删除
注意name为保留名,因此需要用双引号括起来
> show tag keys from add_test
name: add_test
tagKey
------
name
phone
> delete from add_test where "name"='YiHui'
> select * from add_test
>
2. 不同保存策略的数据删除
从前面的语法定义中,没有看到指定保留策略的情况,那么如果需要删除某个保存策略的数据,应该怎样?
> insert add_test,name=YiHui,phone=110 boy=true,age=19i,user_id=2
> insert into "1D" add_test,name=YiHui,phone=110 boy=true,age=19i,user_id=1
> select * from add_test
name: add_test
time age boy name phone user_id
---- --- --- ---- ----- -------
1564483471390538399 19 true YiHui 110 2
> select * from "1D".add_test
name: add_test
time age boy name phone user_id
---- --- --- ---- ----- -------
1564483483748916258 19 true YiHui 110 1
> delete from add_test where "name"='YiHui'
> select * from add_test
> select * from "1D".add_test
>
执行上面的case之后,发现根据tag进行删除时,默认策略,和"1D"保存策略中的数据都被删除掉了
下面是另外一个验证
> select * from add_test;
name: add_test
time age boy name phone user_id
---- --- --- ---- ----- -------
1564483778197609864 19 true YiHui 110 1
> insert into "2_h" add_test,name=YiHui,phone=110 boy=true,age=19i,user_id=1
> select * from "2_h".add_test;
name: add_test
time age boy name phone user_id
---- --- --- ---- ----- -------
1564483793280811751 19 true YiHui 110 1
> delete from add_test where time=1564483793280811751
> select * from "2_h".add_test;
> select * from add_test;
name: add_test
time age boy name phone user_id
---- --- --- ---- ----- -------
1564483778197609864 19 true YiHui 110 1
我们在"2_h"
这个策略中新增了一条数据,直接根据时间进行删除,当前的策略下的数据没有影响,"2_h"
策略中刚添加的数据被删除掉了
1.9 - 09.query数据查询基本篇
前面几篇介绍了InfluxDB的添加,删除修改数据,接下来进入查询篇,掌握一定的SQL知识对于理解本篇博文有更好的帮助,下面在介绍查询的基础操作的同时,也会给出InfluxSql与SQL之间的一些差别
在开始之前,先看一下供查询的数据
> show measurements
name: measurements
name
----
yhh
> select * from yhh
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
1563889538654374538 26 http://blog.hhui.top 10 一灰灰
1563889547738266214 30 http://blog.hhui.top 11 一灰灰
1563889704754695002 30 http://blog.hhui.top 11 一灰灰2
1563889723440000821 30 http://blog.hhui.top 11 一灰灰3 110
> show tag keys from yhh
name: yhh
tagKey
------
name
phone
1. 基本查询
基本查询语法如下
SELECT <field_key>[,<field_key>,<tag_key>] FROM <measurement_name>[,<measurement_name>]
上面的语法中,划分了select和from两块
select语句
select *
: 表示查询所有的field和tag对应的值
select field_key
: 表示查询特定的field对应的值
select tag_key
: 表示查询的特定的tag对应的值
SELECT "<field_key>"::field,"<tag_key>"::tag
: 注意::field
和::tag
用来限定这个数据的类型为tag或者是field
from语句
from后面需要接上measurement,表示从这个mesaurement中查询数据
FROM <measurement_name>
从指定的measurement中获取数据
FROM <measurement_name>,<measurement_name>
从多个measurement中获取数据
FROM <database_name>.<retention_policy_name>.<measurement_name>
从某个数据库中某个保留策略中查询measurement中的数据
实例演示
下面给出几个简答的演示实例,分别介绍查询指定的field/tag的方式
> select age from yhh;
name: yhh
time age
---- ---
1563889538654374538 26
1563889547738266214 30
1563889704754695002 30
1563889723440000821 30
> select "age"::field, "name"::tag from yhh;
name: yhh
time age name
---- --- ----
1563889538654374538 26 一灰灰
1563889547738266214 30 一灰灰
1563889704754695002 30 一灰灰2
1563889723440000821 30 一灰灰3
2. 保留策略数据查询
上面的定义中,说明了可以查询指定保留策略中的数据,下面演示一下应该如何实现
# 创建保留策略
> create retention policy "1D" duration 1d on test
# 插入一条数据
> insert into "1D" yhh,name=二灰,phone=119 email="bangzewu@126.com",blog="http://spring.hhui.top",id=27
# 查询
> select * from "1D".yhh
name: yhh
time blog email id name phone
---- ---- ----- -- ---- -----
1565693045801509796 http://spring.hhui.top bangzewu@126.com 27 二灰 119
>
查询语句和一般的select没有什么特别的区别,唯一需要注意的是measurement前面需要加上保留策略
3. Where语句
前面的查询主要是限定需要获取的数据,而我们实际的场景中,更多的是查询某类满足条件的数据,也就是常见的SQL中加上where查询条件限定
语法如下
SELECT_clause FROM_clause WHERE <conditional_expression> [(AND|OR) <conditional_expression> [...]]
主要看一下where后面的条件表达式,因为influxdb中的数据可以划分为两类,这两种不同的类型,在构建查询语句的时候,会有一些区别
field查询条件
我们已知field的类型有四种:string|int|boolean|float
,所以它支持的操作符有
操作符 |
说明 |
= |
相等 |
<> , != |
不相同 |
> , >= |
大于,大于等于 |
< , <= |
小于,小于等于 |
tag查询条件
在influxdb中tag都是string类型,会建立索引,所以基于tag的查询效率一般来讲是优于field查询的,它支持的操作符为
在influxdb中没有in查询,不同的查询条件可以使用and/or来连接,表示同时满足or一个满足即可,下满给出几个简单的实例
# 根据field进行查询
> select * from yhh where age=26
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
1563889538654374538 26 http://blog.hhui.top 10 一灰灰
# 根据tag进行查询
> select * from yhh where phone!=''
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
1563889723440000821 30 http://blog.hhui.top 11 一灰灰3 110
# 简单的运算查询
> select * from yhh where age + 2>30
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
1563889547738266214 30 http://blog.hhui.top 11 一灰灰
1563889704754695002 30 http://blog.hhui.top 11 一灰灰2
1563889723440000821 30 http://blog.hhui.top 11 一灰灰3 110
> select * from yhh where "name"='一灰灰'
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
1563889538654374538 26 http://blog.hhui.top 10 一灰灰
1563889547738266214 30 http://blog.hhui.top 11 一灰灰
4. 小结
这一小节内容,介绍的是最基础的inflxudb查询操作,和我们了解的SQL基本上没有太多的区别,可能唯一需要注意的就是制定保留策略查询时,需要使用"<retention policy>".<measurement>
的方式跟在from语句之后
其次一个需要注意的时,查询语句中,推荐的写法是
tag key
或field key
请使用双引号括起来
- 如果类型为string,请用单引号把过滤条件括起来
如下面这种写法,否则可能会出现问题
select * from yhh where "name"='一灰灰'
下一篇,我们将介绍查询语句中常见的分组,排序,分页等场景的使用姿势
1.10 - 10.query数据查询基本篇二
前面一篇介绍了influxdb中基本的查询操作,在结尾处提到了如果我们希望对查询的结果进行分组,排序,分页时,应该怎么操作,接下来我们看一下上面几个场景的支持
在开始本文之前,建议先阅读上篇博文: 190813-Influx Sql系列教程八:query数据查询基本篇
0. 数据准备
在开始查询之前,先看一下我们准备的数据,其中name,phone
为tag, age,blog,id
为field
> select * from yhh
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
1563889538654374538 26 http://blog.hhui.top 10 一灰灰
1563889547738266214 30 http://blog.hhui.top 11 一灰灰
1563889704754695002 30 http://blog.hhui.top 11 一灰灰2
1563889723440000821 30 http://blog.hhui.top 11 一灰灰3 110
> show tag keys from yhh
name: yhh
tagKey
------
name
phone
1. 分组查询
和sql语法一样,influxdb sql的分组也是使用group by
语句,其定义如下
SELECT_clause FROM_clause [WHERE_clause] GROUP BY [* | <tag_key>[,<tag_key]]
a. group by tag
从上面的定义中,有一点需要特别强调,用来分组的必须是tag,也就是说对于influxdb而言,不支持根据field进行分组
一个实际的演示如下:
> select * from yhh group by phone
name: yhh
tags: phone=
time age blog id name
---- --- ---- -- ----
1563889538654374538 26 http://blog.hhui.top 10 一灰灰
1563889547738266214 30 http://blog.hhui.top 11 一灰灰
1563889704754695002 30 http://blog.hhui.top 11 一灰灰2
name: yhh
tags: phone=110
time age blog id name
---- --- ---- -- ----
1563889723440000821 30 http://blog.hhui.top 11 一灰灰3
注意上面的输出结果,比较有意思,分成了两个结构段落,且可以输出完整的数据;而mysql的分组查询条件中一般需要带上分组key,然后实现一些数据上的聚合查询
如果我的分组中,使用field进行分组查询,会怎样?报错么?
> select * from yhh group by age
name: yhh
tags: age=
time age blog id name phone
---- --- ---- -- ---- -----
1563889538654374538 26 http://blog.hhui.top 10 一灰灰
1563889547738266214 30 http://blog.hhui.top 11 一灰灰
1563889704754695002 30 http://blog.hhui.top 11 一灰灰2
1563889723440000821 30 http://blog.hhui.top 11 一灰灰3 110
从上面的case中可以看出,虽然执行了,但是返回的结果并不是我们预期的。
b. group by *
另外一个与一般SQL语法不一样的是group by
后面可以跟上*
,表示根据所有的tag进行分组,一个测试如下
> select * from yhh group by *
name: yhh
tags: name=一灰灰, phone=
time age blog id
---- --- ---- --
1563889538654374538 26 http://blog.hhui.top 10
1563889547738266214 30 http://blog.hhui.top 11
name: yhh
tags: name=一灰灰2, phone=
time age blog id
---- --- ---- --
1563889704754695002 30 http://blog.hhui.top 11
name: yhh
tags: name=一灰灰3, phone=110
time age blog id
---- --- ---- --
1563889723440000821 30 http://blog.hhui.top 11
>
c. group by time
除了上面的根据tag进行分组之外,还有一个更高级的特性,根据时间来分组,这个时间还支持一些简单的函数操作
定义如下
SELECT <function>(<field_key>) FROM_clause WHERE <time_range> GROUP BY time(<time_interval>),[tag_key] [fill(<fill_option>)]
我们知道influxdb的一个重要应用场景就是监控的记录,在监控面板上经常会有的就是根据时间进行聚合,比如查询某个服务每分钟的异常数,qps, rt等
下面给出一个简单的使用case
# 为了显示方便,将数据的时间戳改成日期方式展示
> precision rfc3339
> select * from yhh
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
2019-07-23T13:45:38.654374538Z 26 http://blog.hhui.top 10 一灰灰
2019-07-23T13:45:47.738266214Z 30 http://blog.hhui.top 11 一灰灰
2019-07-23T13:48:24.754695002Z 30 http://blog.hhui.top 11 一灰灰2
2019-07-23T13:48:43.440000821Z 30 http://blog.hhui.top 11 一灰灰3 110
> select count(*) from yhh where time>'2019-07-23T13:44:38.654374538Z' and time<'2019-07-23T13:50:43.440000821Z' GROUP BY time(2m)
name: yhh
time count_age count_blog count_id
---- --------- ---------- --------
2019-07-23T13:44:00Z 2 2 2
2019-07-23T13:46:00Z 0 0 0
2019-07-23T13:48:00Z 2 2 2
2019-07-23T13:50:00Z 0 0 0
在上面的查询语句中,有几个地方需要说明一下
- select后面跟上的是单个or多个field的聚合操作,根据时间进行分组时,不允许查询具体的field值,否则会有下面的错误提示
> select * from yhh where time>'2019-07-23T13:44:38.654374538Z' and time<'2019-07-23T13:50:43.440000821Z' GROUP BY time(2m)
ERR: GROUP BY requires at least one aggregate function
- where条件限定查询的时间范围,否则会得到很多数据
group by time(2m)
表示每2分钟做一个分组, group by time(2s)
则表示每2s做一个分组
2. 排序
在influxdb中排序,只支持针对time进行排序,其他的field,tag(因为是string类型,也没法排)是不能进行排序的
语法比较简单,如下,根据时间倒序/升序
一个简单的实例如下
# 根据非time进行排序时,直接报错
> select * from yhh order by age
ERR: error parsing query: only ORDER BY time supported at this time
# 根据时间进行倒排
> select * from yhh order by time desc
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
2019-07-23T13:48:43.440000821Z 30 http://blog.hhui.top 11 一灰灰3 110
2019-07-23T13:48:24.754695002Z 30 http://blog.hhui.top 11 一灰灰2
2019-07-23T13:45:47.738266214Z 30 http://blog.hhui.top 11 一灰灰
2019-07-23T13:45:38.654374538Z 26 http://blog.hhui.top 10 一灰灰
>
3. 查询限制
我们常见的分页就是limit语句,我们常见的limit语句为 limit page, size
,可以实现分页;然而在influxdb中则不同,limit后面只能跟上一个数字,表示限定查询的最多条数
a. limit
N指定每次measurement返回的point个数
SELECT_clause [INTO_clause] FROM_clause [WHERE_clause] [GROUP_BY_clause] [ORDER_BY_clause] LIMIT <N>
下满给出几个实际的case
> select * from yhh limit 2
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
2019-07-23T13:45:38.654374538Z 26 http://blog.hhui.top 10 一灰灰
2019-07-23T13:45:47.738266214Z 30 http://blog.hhui.top 11 一灰灰
# 分组之后,再限定查询条数
> select * from yhh group by "name" limit 1
name: yhh
tags: name=一灰灰
time age blog id phone
---- --- ---- -- -----
2019-07-23T13:45:38.654374538Z 26 http://blog.hhui.top 10
name: yhh
tags: name=一灰灰2
time age blog id phone
---- --- ---- -- -----
2019-07-23T13:48:24.754695002Z 30 http://blog.hhui.top 11
name: yhh
tags: name=一灰灰3
time age blog id phone
---- --- ---- -- -----
2019-07-23T13:48:43.440000821Z 30 http://blog.hhui.top 11 110
b. slimit
N指定从指定measurement返回的series数
SELECT_clause [INTO_clause] FROM_clause [WHERE_clause] GROUP BY *[,time(<time_interval>)] [ORDER_BY_clause] SLIMIT <N>
接下来演示下这个的使用姿势,首先准备插入几条数据,确保tag相同
> insert yhh,name=一灰灰,phone=110 blog="http://spring.hhui.top",age=14,id=14
> insert yhh,name=一灰灰,phone=110 blog="http://spring.hhui.top",age=15,id=15
> insert yhh,name=一灰灰,phone=110 blog="http://spring.hhui.top",age=16,id=16
> select * from yhh
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
2019-07-23T13:45:38.654374538Z 26 http://blog.hhui.top 10 一灰灰
2019-07-23T13:45:47.738266214Z 30 http://blog.hhui.top 11 一灰灰
2019-07-23T13:48:24.754695002Z 30 http://blog.hhui.top 11 一灰灰2
2019-07-23T13:48:43.440000821Z 30 http://blog.hhui.top 11 一灰灰3 110
2019-08-14T11:18:06.804162557Z 14 http://spring.hhui.top 14 一灰灰 110
2019-08-14T11:18:10.146588721Z 15 http://spring.hhui.top 15 一灰灰 110
2019-08-14T11:18:12.753413004Z 16 http://spring.hhui.top 16 一灰灰 110
> show series on test from yhh
key
---
yhh,name=一灰灰
yhh,name=一灰灰,phone=110
yhh,name=一灰灰2
yhh,name=一灰灰3,phone=110
如下面的一个使用case
> select * from yhh group by * slimit 3
name: yhh
tags: name=一灰灰, phone=
time age blog id
---- --- ---- --
2019-07-23T13:45:38.654374538Z 26 http://blog.hhui.top 10
2019-07-23T13:45:47.738266214Z 30 http://blog.hhui.top 11
name: yhh
tags: name=一灰灰, phone=110
time age blog id
---- --- ---- --
2019-08-14T11:18:06.804162557Z 14 http://spring.hhui.top 14
2019-08-14T11:18:10.146588721Z 15 http://spring.hhui.top 15
2019-08-14T11:18:12.753413004Z 16 http://spring.hhui.top 16
name: yhh
tags: name=一灰灰2, phone=
time age blog id
---- --- ---- --
2019-07-23T13:48:24.754695002Z 30 http://blog.hhui.top 11
name: yhh
tags: name=一灰灰3, phone=110
time age blog id
---- --- ---- --
2019-07-23T13:48:43.440000821Z 30 http://blog.hhui.top 11
说实话,这一块没看懂,根据官方的文档进行翻译的,没有get这个slimit的特点
4. 分页
上面只有point个数限制,但是分页怎么办?难道不支持么?
在influxdb中,有专门的offset来实现分页
SELECT_clause [INTO_clause] FROM_clause [WHERE_clause] [GROUP_BY_clause] [ORDER_BY_clause] LIMIT_clause OFFSET <N> [SLIMIT_clause]
简单来讲,就是limit 条数 offset 偏移
使用实例
> select * from yhh
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
2019-07-23T13:45:38.654374538Z 26 http://blog.hhui.top 10 一灰灰
2019-07-23T13:45:47.738266214Z 30 http://blog.hhui.top 11 一灰灰
2019-07-23T13:48:24.754695002Z 30 http://blog.hhui.top 11 一灰灰2
2019-07-23T13:48:43.440000821Z 30 http://blog.hhui.top 11 一灰灰3 110
2019-08-14T11:18:06.804162557Z 14 http://spring.hhui.top 14 一灰灰 110
2019-08-14T11:18:10.146588721Z 15 http://spring.hhui.top 15 一灰灰 110
2019-08-14T11:18:12.753413004Z 16 http://spring.hhui.top 16 一灰灰 110
# 查询结果只有2条数据,从第三个开始(0开始计数)
> select * from yhh limit 2 offset 3
name: yhh
time age blog id name phone
---- --- ---- -- ---- -----
2019-07-23T13:48:43.440000821Z 30 http://blog.hhui.top 11 一灰灰3 110
2019-08-14T11:18:06.804162557Z 14 http://spring.hhui.top 14 一灰灰 110
> select * from yhh limit 2 offset 3
5. 小结
本篇influxdb的查询篇主要介绍了sql中的三种常用case,分组,排序,分页;虽然使用姿势和我们常见的SQL大同小异,但是一些特殊点需要额外注意一下
- 分组查询时,注意分组的key必须是time或者tag,分组查询可以返回完整的point
- 排序,只支持根据时间进行排序,其他的字段都不支持
- 分页,需要注意
limit size offset startIndex
和我们一般的使用case不同,它的两个参数分别表示查询的point个数,以及偏移量;而不是传统sql中的页和条数
1.11 - 11.query数据查询基本篇三
前面介绍了两篇influxdb的查询基本操作姿势,然后有些小伙伴在实际的使用过程中,发现了一些有意思的问题,这里单独开一篇进行说明
1. select tag 无返回
select的查询语句格式定义如下
select "<field_key>"::field,"<tag_key>"::tag from xxx
当我们查询字段中,只有tag时,就会发现啥都没有

当我们需要查询tag value值时,请使用下面的方式
show tag values from measurements on key="tagKey"
如下

2. distinct(tag) 无返回
distinct函数主要用于去重,但是请注意函数内的只能是field,不能是tag,官方文档有说明

3. 模糊查询
influxdb的查询条件支持正则表达式,无论是tag,还是field都是可以的
语法如下
where [tagName|fieldName]=~/xxx/
演示如下

2 - InfluxDb小技巧
一些InfluxDB的使用过程中,您可能会用到的实战小技巧,推荐按需获取
2.1 - v1.6.0安装和简单使用小结
InfluxDB安装和简单使用小结
InfluxDB是一个时序性数据库,因为工作需求,安装后使用测试下是否支持大数据下的业务场景
说明:
- 安装最新版本 v1.6.0
- 集群版本要收费,单机版本免费
- 内部集成的web控制台被ko掉了
I. 安装
直接到官网,查询对应的下载安装方式
安装方式
SHA256: fa118d657151b6de7c79592cf7516b3d9fada813262d5ebe16516f5c0bf62039
wget https://dl.influxdata.com/influxdb/releases/influxdb-1.6.0.x86_64.rpm
sudo yum localinstall influxdb-1.6.0.x86_64.rpm
服务启动命令
# 启动命令
service influxdb start
# 关闭命令
service influxdb stop
注意
默认占用8086/8088两个端口号,可以根据自己的实际场景进行替换,进入配置文件 /etc/influxdb/influxdb.conf
查询 bind-address,其中端口号对应的用处说明如下
# Bind address to use for the RPC service for backup and restore.
bind-address = "127.0.0.1:8088"
...
[http]
# Determines whether HTTP endpoint is enabled.
# enabled = true
# The bind address used by the HTTP service.
bind-address = ":8086"
II. 控制台简单使用
influx提供了一个控制台进行简单的操作,下面给出基本的使用姿势,对于influxdb的一些概念性问题,放在下一篇专门给与说明
首先进入控制台
influx
# 如果修改了端口号,则需要显示指定
# influx -port xxx
1. database相关
这个数据库和我们平常接触比较多的mysql中的数据库差不多,使用姿势也相差无几
a. 显示所有的数据库
说明: >后面跟的是命令,后面的是输出结果
> show databases
name: databases
name
----
_internal
hh_test
b. 创建数据库
和mysql语法一致, create database xxx
> create database mytest
> show databases
name: databases
name
----
_internal
hh_test
mytest
c. 删除数据库
使用drop进行删除,drop database xxx
> drop database mytest
> show databases
name: databases
name
----
_internal
hh_test
d. 选择数据库
> use hh_test
Using database hh_test
2. 表相关
在influxDB中,表不是我们传统理解的table,在这里,专业术语叫做 measurement
(度量?)
查看所有的measurement的命令
show measurements;
name: measurements
name
----
trade
不同于mysql,没有提供专门的创建表,新插入数据,就会自动创建一个不存在的表
1. 新增数据
insert <tbname>,<tags> <values> [timestamp]
说明:
- tbname : 数据表名称
- tags : 表的tag域
- values : 表的value域
- timestamp :当前数据的时间戳(可选,没有提供的话系统会自带添加)
> insert students,addr=wuhan phone=124
> select * from students
name: students
time addr phone
---- ---- -----
1532514647456815845 wuhan 124
2. 查询
查询和sql类似,基本结构如下,但是有很多的限制,后面详解
select * from table where condition group by xxx order by time asc limit 10
一个实例case
> insert students,addr=wuhan phone=124
> insert students,addr=wuhan phone=123
> insert students,addr=changsha phone=15
> select * from students where phone>0 group by addr order by time desc limit 10;
name: students
tags: addr=wuhan
time phone
---- -----
1532515056470523491 123
1532515052664001894 124
name: students
tags: addr=changsha
time phone
---- -----
1532515064351295620 15
3. 更新与删除
当需要更新一个记录时,直接覆盖一个时间戳+所有的tag相等的即可
> select * from students
name: students
time addr phone
---- ---- -----
1532515052664001894 wuhan 124
1532515056470523491 wuhan 123
1532515064351295620 changsha 15
> insert students,addr=wuhan phone=111123 1532515052664001894
> select * from students
name: students
time addr phone
---- ---- -----
1532515052664001894 wuhan 111123
1532515056470523491 wuhan 123
1532515064351295620 changsha 15
删除一条记录,用delete命令
> select * from students
name: students
time addr phone
---- ---- -----
1532515052664001894 wuhan 111123
1532515056470523491 changsha 123
1532515056470523491 wuhan 123
> delete from students where time=1532515056470523491
> select * from students
name: students
time addr phone
---- ---- -----
1532515052664001894 wuhan 111123
4. 删除表
drop measurement students
2.2 - InfluxDB基本概念小结
InfluxDB基本概念小结
InfluxDB作为时序数据库,与传统的关系型数据库相比而言,还是有一些区别的,下面尽量以简单明了的方式介绍下相关的术语概念
I. 基本概念
mysql |
influxdb |
说明 |
database |
database |
数据库 |
table |
measurement |
类似mysql中表的概念 |
record |
tag + field + timestamp |
传统表中的一行数据,映射到influxdb中,可以划分为三个 |
1. database
数据库,和mysql的数据库相比,没有太大的歧义
2. measurement
对比的是mysql中的table,从实际体验来看,两个之间最明显的区别在于没有单独的创建measurement的方法,直接新增一条数据时,若measurement不存在,则直接创建并插入一条数据
3. Point
这个对比的是mysql中的record,在influxDB中,表示每个表中,某个时刻,满足某个条件的filed数据(简单来说就是 timestamp + tag + filed)的组成一个point
- timestamp : 时间戳,ns单位,每个记录都必然有这个属性,没有显示添加时,默认给一个
- tag: 标签,kv结构,在database中, tag + measurement 一起构建索引
- 参与索引创建,因此适合作为查询的过滤条件
- tag的数据量不要太多,最好能有典型的辨别性(和mysql的建立索引的原则差不多)
- value为String类型
- tag是可选的,在measurement不设置tag也是ok的
- field:存储数据,kv结构
- 数据类型为: long, String, boolean, float
4. Series
Series: tag key 与tag value的唯一组合
II. 实例分析
上面几个为基本的概念,单独的看起来印象不够深刻,下面结合实例进行说明:
建立一个measurement,保存某个应用的性能状况,包含以下指标, 每秒写一次数据到influxDB中
- 服务机器: host=127.0.0.1
- 服务接口: service=app.service.index
- qps: qps=1340
- rt: 1313
- cpu: 45.23
- mem: 4154m
- load: 1.21
1. measurement创建
上面有7个指标参数,第一步就是区分tag和field,前面说到tag会建索引,推荐用于可以区分类型,取值可以预估的字段,所以对上面进行如下区分
tag
field
一条实际的插入数据如
> insert myapp,host=127.0.0.1,service=app.service.index qps=1340,rt=1313,cpu=45.23,mem="4145m",load=1.21
> select * from myapp
name: myapp
time cpu host load mem qps rt service
---- --- ---- ---- --- --- -- -------
1532597158613778583 45.23 127.0.0.1 1.21 4145m 1340 1313 app.service.index
a. 小结说明
- 在insert执行语句中,tag与tag、field与field之间用都好进行分割,tag与field之间用空格分割
- tag的value都是,String类型,不需要加双引号
- field的String类型数据,需要放在双引号中,否则会报错
- 如果需要显示添加时间戳,在filed后添加空格,再添加时间戳
b. 是否可以没有field
实测不行,输出如下
> insert myabb,host=123,service=index
ERR: {"error":"unable to parse 'myabb,host=123,service=index ': invalid field format"}
是否可以没有tag
根据前面的说明已经实测,可以
> insert myabb qps=123,rt=1231
> select * from myabb
name: myabb
time qps rt
---- --- --
1532597385053030634 123 1231
2. 数据分析
新插入几条数据,目前的数据为
> select * from myapp
name: myapp
time cpu host load mem qps rt service
---- --- ---- ---- --- --- -- -------
1532597158613778583 45.23 127.0.0.1 1.21 4145m 1340 1313 app.service.index
1532597501578551929 45.23 127.0.0.1 1.21 4145m 1341 1312 app.service.index
1532597510225918132 45.23 127.0.0.1 1.21 4145m 1341 1312 app.service.about
1532597552421996033 45.23 127.0.0.2 1.21 4145m 1341 1312 app.service.about
a. series
上面四条数据,对应几个series呢 ?
根据前面的说法,tagKey + tagValue 确定给一个series (实际上是 measurement + retention policy + tags来确定),因此上表总共有三个series
127.0.0.1 | app.service.index
127.0.0.1 | app.service.about
127.0.0.2 | app.service.about
那么这个series到底是什么东西呢?
如果将上面的数据图表化的方式显示出来,我们可以怎么办?
- 首先我们确定好应用及其和服务名,然后查看这个服务在这台机器上,在时间线上的服务性能
- 翻译过来就是,将cpu/service作为检索条件,以time为时间轴,将value(cpu,load,mem,qps,rt)映射到二维坐标上作为一个点(point),然后将所有的point连接成线,最终得到连续的图表
所以series就是上面的检索条件,同时point的概念也容易理解了
III. 保留策略
前面是表数据的相关基础概念,这里还有一个就是数据保存的策略 retention policy, 用于决定数据保存多久(意思是数据可以删除),保存几个备份,集群的处理等
1. 基本说明
influxdb面向大数据的时序数据库,所以数据量可以很大很大,如果全部存储,估计硬盘的费用都不小,而且有些数据可能并不需要永久存储,因此就有了这个rentention policy
InfluxDB本身不提供数据的删除操作,因此用来控制数据量的方式就是定义数据保留策略。
因此定义数据保留策略的目的是让InfluxDB能够知道可以丢弃哪些数据,从而更高效的处理数据。
2. 基本操作
a. 查询策略
> show retention policies on hh_test
name duration shardGroupDuration replicaN default
---- -------- ------------------ -------- -------
autogen 0s 168h0m0s 1 true
- name: 名称
- duration: 保留时间, 0表示永久保存
- shardGroupDuration: shardGroup的存储时间,shardGroup是InfluxDB的一个基本储存结构,应该大于这个时间的数据在查询效率上应该有所降低。
- replicaN: 全称是REPLICATION,副本个数
- default: 是否是默认策略
b. 新建策略
> create retention policy "2_hour" on hh_test duration 2h replication 1 default
> show retention policies on hh_test
name duration shardGroupDuration replicaN default
---- -------- ------------------ -------- -------
autogen 0s 168h0m0s 1 false
2_hour 2h0m0s 1h0m0s 1 true
c. 修改策略
> alter retention policy "2_hour" on hh_test duration 4h default
> show retention policies on hh_test
name duration shardGroupDuration replicaN default
---- -------- ------------------ -------- -------
autogen 0s 168h0m0s 1 false
2_hour 4h0m0s 1h0m0s 1 true
d. 删除策略
> drop retention policy "2_hour" on hh_test
> show retention policies on hh_test
name duration shardGroupDuration replicaN default
---- -------- ------------------ -------- -------
autogen 0s 168h0m0s 1 false
删除默认策略之后,就没有默认策略了,是否会有问题呢?
3. RP理解
设置这个策略之后,会自动删除过期的数据,那么数据时怎么保存的呢?
比如默认的永久保存策略中,有个 shardGroupDuration
参数,为7天,也就是说7天的数据放在一个Shard中,过了之后,新加一个Shard
shard包含实际的编码和压缩数据,并由磁盘上的TSM文件表示。 每个shard都属于唯一的一个shard group。多个shard可能存在于单个shard group中。每个shard包含一组特定的series。给定shard group中的给定series上的所有点将存储在磁盘上的相同shard(TSM文件)中。
2.3 - 时序数据库InfluxDB之备份和恢复策略
influxdb 备份与恢复
参考: influxdb backup and restore
环境:
- influxdb v1.6.0
- 使用influx自动的控制台进行
I. 备份
备份命令
influxd backup
[ -database <db_name> ] --> 指定需要备份的数据库名
[ -portable ] --> 表示在线备份
[ -host <host:port> ] --> influxdb服务所在的机器,端口号默认为8088
[ -retention <rp_name> ] | [ -shard <shard_ID> -retention <rp_name> ] --> 备份的保留策略,注意shard是挂在rp下的;我们需要备份的就是shard中的数据
[ -start <timestamp> [ -end <timestamp> ] | -since <timestamp> ] --> 备份指定时间段的数据
<path-to-backup> --> 备份文件的输出地址
1. 实例演示
首先创建一个数据库 yhhblog, 里面包含两个measurement,对应的数据如下
> show databases
name: databases
name
----
_internal
yhhblog
> use yhhblog
Using database yhhblog
> show measurements
name: measurements
name
----
netLoad
serviceLoad
> select * from netLoad
name: netLoad
time host netIn netOut service
---- ---- ----- ------ -------
1532658769048100401 127.0.0.1 13m 521K app.service.about
> select * from serviceLoad
name: serviceLoad
time cpu host load mem qps rt service
---- --- ---- ---- --- --- -- -------
1532658713805369067 45.23 127.0.0.2 1.21 4145m 1341 1312 app.service.about
1532658718726259226 45.23 127.0.0.1 1.21 4145m 1341 1312 app.service.about
a. 备份所有的数据库
将influxdb中的所有的数据库都备份下来,不加任何的参数
influxd backup -portable /tmp/data/total
b. 备份指定数据库
如果只想要备份上面的yhhblog数据库, 添加 -database
参数指定即可
# influxd backup -portable -database yhhblog /tmp/data/yhhblog
2018/07/27 10:38:15 backing up metastore to /tmp/data/yhhblog/meta.00
2018/07/27 10:38:15 backing up db=yhhblog
2018/07/27 10:38:15 backing up db=yhhblog rp=autogen shard=10 to /tmp/data/yhhblog/yhhblog.autogen.00010.00 since 0001-01-01T00:00:00Z
2018/07/27 10:38:15 backup complete:
2018/07/27 10:38:15 /tmp/data/yhhblog/20180727T023815Z.meta
2018/07/27 10:38:15 /tmp/data/yhhblog/20180727T023815Z.s10.tar.gz
2018/07/27 10:38:15 /tmp/data/yhhblog/20180727T023815Z.manifest
c. 备份数据库中指定时间段的数据
对上面的数据,只备份部分时间满足要求的数据,可以添加start/end参数
# influxd backup -portable -database yhhblog -start 2018-07-27T2:31:57Z -end 2018-07-27T2:32:59Z /tmp/data/yhhblog_per
2018/07/27 10:42:14 backing up metastore to /tmp/data/yhhblog_per/meta.00
2018/07/27 10:42:14 backing up db=yhhblog
2018/07/27 10:42:14 backing up db=yhhblog rp=autogen shard=10 to /tmp/data/yhhblog_per/yhhblog.autogen.00010.00 with boundaries start=2018-07-27T02:31:57Z, end=2018-07-27T02:32:59Z
2018/07/27 10:42:14 backup complete:
2018/07/27 10:42:14 /tmp/data/yhhblog_per/20180727T024214Z.meta
2018/07/27 10:42:14 /tmp/data/yhhblog_per/20180727T024214Z.s10.tar.gz
2018/07/27 10:42:14 /tmp/data/yhhblog_per/20180727T024214Z.manifest
现在备份ok了,问题就是如何确认备份的问题有没有问题呢,备份后的数据如何恢复呢?
II. 恢复
命令如下
influxd restore
[ -db <db_name> ] --> 待恢复的数据库(备份中的数据库名)
-portable | -online
[ -host <host:port> ] --> influxdb 的服务器
[ -newdb <newdb_name> ] --> 恢复到influxdb中的数据库名
[ -rp <rp_name> ] --> 备份中的保留策略
[ -newrp <newrp_name> ] --> 恢复的保留策略
[ -shard <shard_ID> ]
<path-to-backup-files>
首先拿简单的方式来演示恢复策略,并查看下上面的备份数据是否有问题
1. 恢复到不存在的database
下面演示下将前面的导出的备份,恢复到一个新的数据库 yhhblog_bk上,执行命令如下
influxd restore -portable -db yhhblog -newdb yhhblog_bk yhhblog_per
顺带验证下上面备份的数据是否有问题,注意到我们恢复的是时间片段的数据备份,因此恢复的数据,应该会排除掉不再上面日期内的数据
> show databases
name: databases
name
----
_internal
yhhblog
yhhblog_bk
> use yhhblog_bk
Using database yhhblog_bk
> show measurements
name: measurements
name
----
netLoad
serviceLoad
> select * from netLoad
name: netLoad
time host netIn netOut service
---- ---- ----- ------ -------
1532658769048100401 127.0.0.1 13m 521K app.service.about
> select * from serviceLoad
name: serviceLoad
time cpu host load mem qps rt service
---- --- ---- ---- --- --- -- -------
1532658718726259226 45.23 127.0.0.1 1.21 4145m 1341 1312 app.service.about
注意看前面serviceLoad里面只有一条数据, 即表明我们按照时间进行备份没啥问题
2. 恢复到存在的DB
看官网恢复的文档中,如果想将备份恢复到一个已经存在的database中时,并不是上面那么简单的就可以了,这里采用的一个策略是西安备份到一个临时的db中;然后将临时DB中的数据写入已存在的db中
具体的演示步骤如下 (注意本小结的执行可以直接依赖前面恢复的备份数据库中)
将备份恢复到已经存在的数据库 yhhblogNew 中
# 首先是将备份恢复到一个不存在的数据库 yhhblog_bk 中
influxd restore -portable -db yhhblog -newdb yhhblog_bk yhhblog_per
进入 influx 控制台,执行拷贝和删除临时数据库
# 准备 yhhblogNew 数据库
> create database yhhblogNew
# 将临时数据库中的数据导入已存在的数据库中
> use yhhblog_bk
> SELECT * INTO yhhblogNew..:MEASUREMENT FROM /.*/ GROUP BY *
> drop yhhblog_bk
3. 保留策略已存在时,恢复
influxd restore -portable -db yhhblog -newdb yhhblog_tmp -rp autogen -newrp autogen_tmp yhhblog
进入influx控制台,执行拷贝
> user yhhblog_tmp
> SELECT * INTO yhhblogNew.autogen.:MEASUREMENT FROM /yhhblog_tmp.autogen_tmp.*/ GROUP BY *
> drop database yhhblog_tmp
4. 其他
官方还写了其他两种恢复方式,一个被废弃,一个离线的会导致数据丢失,也不推荐使用,而现在大部分的博文中备份和恢复都是这种过时的方案,不太友好,这里不详细叙述
2.4 - InfluxDB之权限管理
influxdb安装完毕之后,默认属于裸奔状态,为了安全起见,当然是需要加上权限管理,下面介绍下如何设置权限
I. 简单使用篇
不考虑细节的情况下,我只希望可以添加一个用户/密码,然后只有输入用户/密码验证准确之后,就可以愉快的进行后续的编码逻辑;至于更多的用户权限管理,不想太了解的,可以直接看这一小节即可
1. 设置用户并赋权
安装完毕之后,默认没有开启权限,因此可以直接连接
# 首先通过cli 连上influxdb
influx
# 创建用户,密码,并赋予所有的权限
create user admin with password 'admin' with all privileges
如下图,需要注意的是密码必须使用引号括起来,否则会出现下图中的报错

2. 开启权限校验
vim /etc/influxdb/influxdb.conf
# 开启配置
auth-enabled = true
3. 重启并测试
# 重启db
service influxdb restart
# 连接测试
influx -username admin -password admin

II. 权限管理
前面介绍的基本上可以满足简单的db使用姿势了,接下来介绍下更多的使用说明
1. 用户管理
创建用户
create user xxx with password 'pwd'
重设密码
set password for xxx='newpwd'
删除用户
查看用户
2. 权限管理
针对用户进行授权和回收
授权
GRANT ALL PRIVILEGES TO <username>
GRANT [READ,WRITE,ALL] ON <database_name> TO <username>
回收
REVOKE ALL PRIVILEGES FROM <username>
REVOKE [READ,WRITE,ALL] ON <database_name> FROM <username>
权限查询
show grants for <username>
2.5 - InfluxDB之配置修改
influxdb安装完毕之后,一般来讲,有些配置有必要改一下的,比如默认的端口号,默认的数据存储位置,本篇将介绍下常用配置的修改姿势
I. 配置
系统环境为centos,influxdb的版本为1.6
1. 配置文件
默认配置文件安装目录为: /etc/influxdb/influxdb.conf
默认配置查看
输出结果如
Merging with configuration at: /etc/influxdb/influxdb.conf
reporting-disabled = false
bind-address = "127.0.0.1:8088"
[meta]
dir = "/var/lib/influxdb/meta"
retention-autocreate = true
logging-enabled = true
[data]
dir = "/var/lib/influxdb/data"
index-version = "inmem"
wal-dir = "/var/lib/influxdb/wal"
wal-fsync-delay = "0s"
validate-keys = false
query-log-enabled = true
cache-max-memory-size = 1073741824
cache-snapshot-memory-size = 26214400
cache-snapshot-write-cold-duration = "10m0s"
compact-full-write-cold-duration = "4h0m0s"
compact-throughput = 50331648
compact-throughput-burst = 50331648
max-series-per-database = 1000000
max-values-per-tag = 100000
max-concurrent-compactions = 0
max-index-log-file-size = 1048576
series-id-set-cache-size = 100
trace-logging-enabled = false
tsm-use-madv-willneed = false
[coordinator]
write-timeout = "10s"
max-concurrent-queries = 0
query-timeout = "0s"
log-queries-after = "0s"
max-select-point = 0
max-select-series = 0
max-select-buckets = 0
[retention]
enabled = true
check-interval = "30m0s"
[shard-precreation]
enabled = true
check-interval = "10m0s"
advance-period = "30m0s"
[monitor]
store-enabled = true
store-database = "_internal"
store-interval = "10s"
[subscriber]
enabled = true
http-timeout = "30s"
insecure-skip-verify = false
ca-certs = ""
write-concurrency = 40
write-buffer-size = 1000
[http]
enabled = true
bind-address = ":8086"
auth-enabled = true
log-enabled = true
suppress-write-log = false
write-tracing = false
flux-enabled = false
flux-log-enabled = false
pprof-enabled = true
debug-pprof-enabled = false
https-enabled = false
https-certificate = "/etc/ssl/influxdb.pem"
https-private-key = ""
max-row-limit = 0
max-connection-limit = 0
shared-secret = ""
realm = "InfluxDB"
unix-socket-enabled = false
unix-socket-permissions = "0777"
bind-socket = "/var/run/influxdb.sock"
max-body-size = 25000000
access-log-path = ""
max-concurrent-write-limit = 0
max-enqueued-write-limit = 0
enqueued-write-timeout = 30000000000
[logging]
format = "auto"
level = "info"
suppress-logo = false
[[graphite]]
enabled = false
bind-address = ":2003"
database = "graphite"
retention-policy = ""
protocol = "tcp"
batch-size = 5000
batch-pending = 10
batch-timeout = "1s"
consistency-level = "one"
separator = "."
udp-read-buffer = 0
[[collectd]]
enabled = false
bind-address = ":25826"
database = "collectd"
retention-policy = ""
batch-size = 5000
batch-pending = 10
batch-timeout = "10s"
read-buffer = 0
typesdb = "/usr/share/collectd/types.db"
security-level = "none"
auth-file = "/etc/collectd/auth_file"
parse-multivalue-plugin = "split"
[[opentsdb]]
enabled = false
bind-address = ":4242"
database = "opentsdb"
retention-policy = ""
consistency-level = "one"
tls-enabled = false
certificate = "/etc/ssl/influxdb.pem"
batch-size = 1000
batch-pending = 5
batch-timeout = "1s"
log-point-errors = true
[[udp]]
enabled = false
bind-address = ":8089"
database = "udp"
retention-policy = ""
batch-size = 5000
batch-pending = 10
read-buffer = 0
batch-timeout = "1s"
precision = ""
[continuous_queries]
log-enabled = true
enabled = true
query-stats-enabled = false
run-interval = "1s"
[tls]
min-version = ""
max-version = ""
2. 数据存储修改
从上面的配置中可以知道,默认的数据存储为/var/lib/influxdb/data
, /var/lib/influxdb/wal
, /var/lib/influxdb/meta
将数据保存在我们挂载的硬盘 /influx
第一步,修改配置文件
vim /etc/influxdb/influxdb.conf
## 修改配置
[meta]
dir = '/influx/meta'
[data]
dir = '/influx/data'
war-dir = '/influx/wal'
第二步,修改用户组
重新制定存储目录之后,需要修改文件夹的owner和分组,否则influxdb将无法正常启动
chown -R influxdb:influxdb /influx
第三步,重启
3. 端口修改
可以修改默认的端口号,首先进入配置文件
[[udp]]
bind-address = ":18089"
[[http]]
bind-address = ":18086"
# 开启下权限验证,相关配置可以参考博文: https://blog.hhui.top/hexblog/2019/05/05/190505-InfluxDB之权限管理/
auth-enabled = true
2.6 - InfluxDb之时间戳显示为日期格式
直接使用influx-cli查询数据时,时间戳格式不太友好,记录下显示日期的方式
连接时添加参数
influx -precision rfc3339
连接后设置参数
# 进入控制台
influx
# 设置参数
precision rfc3339