InfluxDB 是一个开源的时序数据库, 使用 GO 语言开发, 特别适合用于处理和分析资源监控数据这种时序相关数据. 而 InfluxDB 自带的各种特殊函数如求标准差, 随机取样数据, 统计数据变化比等, 使数据统计和实时分析变得十分方便.
influxdb 的单机版是开源的, 而集群版是商业版, influxdb 被设计运行在 SSD 上, 如果使用机器或者网络磁盘作为存储介质, 会导致性能下降至少一个数量级. influxdb 支持 restful API, 同时也支持 https, 为了保证安全性, 非局域网建议使用 https 与 Influxdb 进行通信.
influxdb 基础
infludb 中存储的是时间序列数据, 比如说某个时间点系统负载, 服务耗时等信息, 时间序列数据可以包含多个值. 关于什么是时间序列数据, 简单来来说就是数据是和一个时间点关联的, 结合 MySQL 中的记录与 id 关系来看就是时间序列数据的主键就是时间点(timestrap).
infludb 中的一条数据至少包括 measurement(对应 MySQL 中表概念),timestamp, 至少一个 k-v 结构的 field, 再加上 0 个或者多个 k-v 结构的 tag. 对比 MySQL 来看, measurement 就是一张表, 其主键是 timestamp 时间戳, tag 和 field 对应就是表中列, tag 和 field 都是 k-v 接口, k 对应列的名字, v 对应该列存储的值, tag 和 field 不同的是, tag 是有索引的而 field 没有(如果查询条件为 tag 则会扫描所有查询到的数据), 对于 MySQL 表的有索引列和无索引列. 注意 MySQL 中的表需要提前定义结构, 而 influxdb 中的 measurement 无需提前定义, 其 null 值也不会被存储.
influxdb 中 measurement 无需定义, 即无模式设计, 开发者可以在任意添加 measurement,tags 和 fields, 不过针对同一个 field, 第二次和第一次写入的数据类型不匹配, influxdb 会报错(由于默认 tag 的 v 都是字符串类型, 所有不存在这个问题, 不管输入是什么数据都当做字符串来处理).
数据读写
influxdb 数据写入需满足如下格式:
insert <measurement>[,<tag-key>=<tag-value>...] <field-key>=<field-value>[,<field2-key>=<field2-value>...] [unix-nano-timestamp]
注意: measurement 和至少一个 fileld 的 k-v 是必须的, tag 和 timestrap 时间戳是可选的.
说实话, 这个写入格式还是有点小严格的, 因为它要求 measurement 和可能的 0 个或多个 tag 之间必须是紧挨着的, 中间不能有空格; 同时多个 filed 之间也是不能有空格, tag 和 field 的 k,tag 的 v 都是字符串类型; 时间戳不是必须的, 如果为空则使用服务端的本地时间作为时间戳. 相同时间戳的数据第二次写入会覆盖第一次写入的数据, 相当于更新操作.
为什么至少有一个 filed 是必须的, 而 tag 是可选的呢?
这是 influxdb 的存储模型决定的, measurement+tag set+field key 作为 key,field value 作为 value, 如果没有 field 则没有了对应的 value 了.
插入数据的 tag key 和 field key 能一样么?
数据插入没问题, 这是由于 infludb 底层存储 tag 和 field 是在不同地方的, 只不过为了区分会加上_序号而已, 如下图:
当在 use 某个 db 之后, 就可以执行数据读写操作, 比如下面往名字为 CPU 的 MEASUREMENT(对应 MySQL 中的表概念)中写入如下数据:
insert CPU,host=s01,region=hangzhou value=0.64 1520052020000000000
命令说明:
- 插入数据对应的 MEASUREMENT 名字为 CPU;
- 数据 tag 分别是 host 和 region,field 是 value;
- 数据的最后一项是时间戳(1520052020000000000), 时间戳不是必须的, 如果不传则使用 influxdb 服务端本地时间戳, 注意时间戳都是 UTC 时间
数据保留策略
Influxdb 可支持每秒十万级别的数据量, 如果长时间保存会对存储造成很大压力, 因此和一般数据存储系统一样有一个数据保留策略, 同时针对大流量量数据可采样保存, 小流量数据可全量保存. influxdb 通过保留策略 (RP,Retention Policy) 来管理过期数据, 使用连续查询 (CR,Continuous Queries) 来进行数据采样.
RP: 数据保留策略, 过期数据会被清除, 每个数据库可拥有多种 RP 策略;
CQ: 数据连续查询, 定时跑的一个查询语句, 比如周期性统计某个数据指标, 查询语句需要在 select 语句中使用并且包含 group by time 子句(这里有点类似 Flink 中流数据处理的按时间窗口统计功能).
默认写数据不指定保留策略 (RP,Retention Policy) 时, 默认使用 influxdb 默认的 RP, 名字叫做 autogen 的 RP 会永久保留数据. 如果使用命令 create retention policy "default2" on "db2" duration 2h replication 1 default, 执行该命令后 default2 会取代默认的 autugen 作为 db2 数据库的默认 RP, 默认 influxdb 会间隔半个小时执行一次 RP 操作.
比如有一个服务请求日志 measurement 的名字为 log(RP 策略是 2 小时, 数据库是 db2), 其中数据有服务耗时(字段对应名字 time), 我们想统计每分钟平均服务耗时, 然后将平均耗时数据写入到名字为 log2 的 measurement(RP 策略是 2 天), 该如何做呢?
首先创建 2 小时和 2 天的 RP 策略:
- create retention policy "tow_hour" on db2 duration 2h replication 1
- # 对数据库 db2 创建一个名字叫 "tow_hour" 的 RP 策略, 数据保存 2 小时, 由于最后没有加 default, 所以数据读写如果没有执行 RP 仍然使用的是 influxdb 默认的 RP
- create retention policy "tow_day" on db2 duration 2d replication 1
- # 对数据库 db2 创建一个名字叫 "tow_day" 的 RP 策略, 注意对于单机版 influxdb 来说 replication 无意义
然后使用 create continuous query 创建 CQ 策略:
- create continuous query "cq_avg_time" on db2
- begin
- select mean("time") as "mean_time" into "tow_day"."log2" from log
- group by time(1m)
- end
这样就创建了一个名字叫 cq_avg_time 的 CQ 作用于 db2 数据库, 每 1 分钟一次计算 measurement 为 log 的 time 字段的平均值, 然后写入到另一个 measurement 为 log2 中.
来源: https://www.cnblogs.com/luoxn28/p/12242128.html