InfluxDB 是一个开源分布式时序、事件和指标数据库,使用 Go 语言编写,无需外部依赖,其设计目标是实现分布式和水平伸缩扩展。
InfluxData 提供了 TICK 一套解决方案,不过使用比较多的是 InfluxDB,在此就介绍下 InfluxDB 以及 Telegraf 。
简介
在对时序数据进行存储时,常见的有多种格式:A) 使用文件 (如: RRD, Whisper);B) 使用 LSM 树 (如: LevelDB, RocksDB, Cassandra);C) 使用 B-Tree 排序和 k/v 存储 (如: BoltDB, LMDB) 。
如下,就是 InfluxDATA 提供的一整套监控解决方案,包括了数据采集 (Telegraf)、数据存储 (InfluxDB)、数据展示 (Chronograf) 以及报警 (Kapacitor) 。
而实际上,使用比较多的是 InfluxDB ,这是一个时序数据库,关于时序数据库的排名,可以直接在 db-engines.com 查看,InfluxDB 的活跃度基本排在第一。
除了上述 InfluxDATA 提供的解决方案之外,通常还可以使用如下的方案。
采集数据 (collectd) ==>>==>> 存储数据 (InfluxDB) ==>>==>> 显示数据 (Grafana)
0.8.4 版本之前只能通过 influxdb-collectd-proxy 采集 collectd 上报的数据,之后 InfluxDB 自动提供了接口;当然,默认是不开启的,需要在配置文件中设置。
在此,还是重点介绍下 InfluxDB 。
特性
简单列举下 InfluxDB 所支持的特性:
- 支持 Regular Timeseries 以及 Irregular Timeseries,前者是指时间间隔固定,后者指不固定,例如报警、入侵事件等;
- 可以将秒级监控在后台转换为分钟级,减小存储空间 (Continuous Queries);
- 采用 Schemaless ,列存储,压缩率高,可以存储任意数量的列;
- 提供 min, max, sum, count, mean 等聚合函数;
- 使用类 SQL 语句;
- Built-in Explorer 自带管理工具,默认不打开,需要在配置文件中配置;
- Native HTTP API,采用内置 HTTP 服务 (Protobuf API 暂时不提供)。
常用概念
简单列举下常见的概念。
Database
数据库,可以创建多个,不同数据库中的数据文件存放在磁盘上的不同目录。
Measurement
数据库中的表,例如 memory 记录了内存相关统计,其中包括了 used、cached、free 等。
Point
表里的一行数据,由 A) 时间戳 (timestamp,每条记录的时间,数据库的主索引,会自动生成);B) 数据 (field,记录的 Key/Value 例如温度、湿度);C) 标签 (tags,有索引如地区、海拔)组成。
Tag/tag key/tag value
有点不太好解释,可以理解为标签,或者二级索引,例如采集机器的 CPU 信息的时候,可以设置两个 tag 分别是机器 IP 以及第几个 CPU,在查询的时候放在 where 条件中,从而不需要遍厉整个表,这是一个 map[stirng]string
结构。
Fields
也就是实际记录的数据值,是 map[string]interface{}
类型,类似于 C 语言中的 void * ,这里的 interface{}
可以是 int、int32、int64、float32、float64,也就是真正需要显示或者计算的值,例如 CPU 的 sys, user, iowait 等。
Retention Policy
存储策略,InfluxDB 会自动清理数据,可以设置数据保留的时间,默认会创建存储策略 autogen (保留时间为永久),之后用户可以自己设置,例如保留最近 30 天的数据。
+----------+
+-->| series |
| +----------+
+-------------+ | +----------+
| measurement | ---+-->| series |
+-------------+ | +----------+
| +----------+
+-->| series |
+----------+
安装
实际上,编译好的二进制程序,可以直接从官网 www.influxdata.com/downloads/ 上下载,例如,在 CentOS 中,可以通过如下方式安装,安装后数据默认保存在 /var/lib/influxdb
目录下。
----- 下载二进制安装包
$ wget https://dl.influxdata.com/influxdb/releases/influxdb-1.1.1.x86_64.rpm
----- 查看二进制包的内容
$ rpm -qpl influxdb-1.1.1.x86_64.rpm
----- 解压二进制包
$ rpm2cpio influxdb-1.1.1.x86_64.rpm | cpio -div
----- 安装二进制包
# rpm -ivh influxdb-1.1.1.x86_64.rpm
----- 启动服务,可以查看/usr/lib/systemd/system/influxdb.service文件
# systemctl start influxdb
安装完之后,可以看到如下的可执行文件。
- influxd,服务器,可以直接通过该命令启动;
- influx,InfluxDB 命令行客户端,可链接服务器,执行一些常见的命令;
- influx_inspect,用于查看磁盘 shards 上的详细信息;
- influx_stress,压力测试工具;
- influx_tsm,数据库转换工具,可以将数据库从 b1 或 bz1 格式转换为 tsm1 格式。
源码编译
当然,主要介绍下 influxdb 和 telegraf 的源码编译。
build.py
在源码中,有一个编译脚本 build.py,可以通过该脚本进行编译、打包等操作。
实际上,在 build.py 脚本中,会通过 git 检查相应的版本 (详见 get_current_XXX 类函数),所以需要保证这是一个 git 版本库,也就是说,如果通过该工具编译,需要通过 git clone 下载源码。
另外,代码库的依赖是通过 Go Dependancy Manager, GDM 管理的,当然如果没有安装,则会自动安装;然后下载依赖的代码库;最后,会直接调用 go install 安装。
TIP: 如果无法直接连接到网络,可以将 get_current_XXX()、go_get()、local_changes() 返回正常的值即可,例如 get_current_commit() 返回 “foobar” ,go_get() 返回 true 等等;当然,此时,依赖的代码库需要手动下载 (执行go install时会显示依赖包)。
编译后的程序,会最终安装到 $GOPATH/bin/ 目录下;也可以打包成 rpm 包,不过没仔细研究,后面再看看。
influxdb
对于 InfluxDB 可以通过如下方式安装。
----- 1. 下载相关的分支
$ git clone -b v1.1.1 https://github.com/influxdata/influxdb.git .
----- 2. 直接进行编译,如果并非通过git下载源码,需要如上修改build.py文件
$ ./build.py
----- 3. 直接复制到$GOPATH/bin目录下即可
$ cp build/* $GOPATH/bin
telegraf
对于 telegraf 可以直接使用 make 安装,对于其中一些依赖库,如 golang.org/x/crypto ,可能会导致无法下载,可以直接从 github 上下载,然后删除 Godeps 相关依赖。
另外,通过上述方法下载时,需要使用 git clone 下载,否则会由于缺少 .git 目录导致报错;这也意味着,如果可以确保相关的依赖都已经下载之后,直接将 build.py 脚本中的 go_get() 注释掉即可,这样就不会通过 gdm 下载依赖包了。
$ go get github.com/influxdata/telegraf
$ cd $GOPATH/src/github.com/influxdata/telegraf
$ make
如官方所述,该工具是插件式的,这也就导致其在编译时,会依赖很多的插件,如果只需要部分插件,可以在 plugins 目录下,修改相应分类的 all/all.go 文件,将不需要的注释掉即可。
其实,主要修改 plubins/{inputs,outputs}/all/all.go
即可。
tips
需要注意的是,通过 gdm 安装依赖时,可能会由于墙 (你懂得) 部分包无法下载,但是现象是 hang 住 :-( 所以,可以从 github 上手动下载,一般都会有镜像的。
配置文件
默认使用 /etc/influxdb/influxdb.conf
,默认会使用如下的端口:
- 8083: Web-Admin管理服务的端口,如果是本地可以直接通过 http://localhost:8083 打开,不过默认没有开启,需要在配置文件中打开;
- 8086: HTTP-API的端口,用于接收请求和发送数据;
- 8088: 集群端口,用于 InfluxDB 集群通讯使用,不过 0.11.1 版本之后就不再提供集群化的解决方案了,只有企业版才提供该功能;
简单列举下常见的配置。
# 管理面需要打开如下配置
[admin]
enabled = true
bind-address = ":8083"
# 如果不指定,则会通过os.hostname()通过系统获取,可能会报错
hostname = '192.168.1.23'
# 默认每隔24小时会向usage.influxdata.com发送一些统计数据,可以关闭掉
reporting-disabled = true
Python访问
通过 Python 访问 InfluxDB 需要安装 InfluxDB Python,然后通过如下方式访问即可。
$ python
>>> from influxdb import InfluxDBClient
>>> json_body = [
{
"measurement": "cpu_load_short",
"tags": {
"host": "server01",
"region": "us-west"
},
"time": "2009-11-10T23:00:00Z",
"fields": {
"value": 0.64
}
}
]
>>> client = InfluxDBClient('localhost', 8086, 'root', 'root', 'example')
>>> client.create_database('example')
>>> client.write_points(json_body)
>>> result = client.query('select value from cpu_load_short;')
>>> print("Result: {0}".format(result))
常用操作
在 InfluxDB 中,写入数据采用行格式,可以粗略的将要存入的一条数据看作一个虚拟的 key 和其对应的 value (field value),格式如下:
<measurement>[,<tag-key>=<tag-value>...] <field-key>=<field-value>[,<field2-key>=<field2-value>...] [timestamp]
cpu,host=serverA,region=west value=0.64 服务器默认时间
temperature,zipcode=384250,province=zhejiang value=75,humidity=20 1434067467000000000
常见操作列举如下,可以通过 -precision
参数指定时间格式以及精度,例如 rfc3339 。
----- 写入数据
$ curl -i -XPOST 'http://localhost:8086/write?db=testDB'
--data-binary 'weather,altitude=1000,area=北 temperature=11,humidity=-4'
$ curl -i -XPOST 'http://localhost:8086/write?db=testDB&precision=s'
--data-binary 'weather,altitude=1000,area=北 temperature=11,humidity=-4'
influx> INSERT weather,altitude=1000,area=北 temperature=11,humidity=-4;
----- 查询
$ curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=mydb" -precision 'rfc3339'
--data-urlencode "q=SELECT * FROM weather ORDER BY time DESC LIMIT 3"
$ curl -G 'http://localhost:8086/query?u=readonly&p=password&pretty=true' --data-urlencode "db=mydb"
--data-urlencode "q=SELECT * FROM weather ORDER BY time DESC LIMIT 3"
----- 设置过期策略
$ curl -G http://localhost:8086/query --data-urlencode
"q=CREATE RETENTION POLICY bar ON foo DURATION 300d REPLICATION 3 DEFAULT"
另外,支持 JSON 格式写入、GZIP 压缩数据插入及查询,详细可以参考源码中的 tests 目录。
运维操作
基本的数据保存目录如下。
.
├── data
│ ├── _internal
│ │ └── monitor
│ │ ├── 16 Shard-ID
│ │ │ └── 000000004-000000003.tsm
│ │ └── 3
│ └── telegraf
│ └── autogen 存储策略
│ ├── 12
│ │ └── 000000132-000000002.tsm
│ └── 7
│ └── 000000003-000000002.tsm
├── meta
│ └── meta.db 元数据
└── wal
├── _internal
│ └── monitor
│ ├── 16
│ │ └── _00015.wal
│ └── 3
│ ├── _00001.wal
│ ├── _00002.wal
│ ├── _00003.wal
│ └── _00006.wal
└── telegraf
└── autogen
├── 12
│ └── _00395.wal
└── 7
└── _00010.wal
系统监控
可以查看 官方文档,关于 GoLang 的内部运行状态,可以参考 https://golang.org/pkg/runtime 。
----- InfluxDB本身的监控统计数据,保存在内存中,重启后会丢失
SHOW STATS FOR <'module'>
----- 包括编译信息、主机名、系统配置、启动时间、内存使用率、GoLang运行环境信息
SHOW DIAGNOSTICS FOR <'module'>
----- 内部监控进程保存的数据,包含了各种监控的历史数据
_internal
元数据查看
仅简单列举一下常见的命令,详细可以查看 官方文档 。
SHOW SERIES;
SHOW SERIES ON telegraf FROM mysql;
SHOW FIELD KEYS;
SHOW FIELD KEYS ON telegraf FROM cpu;
SHOW MEASUREMENTS
用户权限管理
InfluxDB 的权限设置比较简单,只有读、写、ALL 三种,详细参考 官方文档 。默认不开启用户认证,需要修改配置文件:
[http]
auth-enabled = true
常见命令如下:
----- 授权
GRANT [READ,WRITE,ALL] ON <database_name> TO <username>
GRANT ALL PRIVILEGES TO "username"
----- 撤销权限
REVOKE [READ,WRITE,ALL] ON <database_name> FROM <username>
REVOKE ALL PRIVILEGES FROM "username"
----- 查看权限
SHOW GRANTS FOR <user_name>
----- 显示用户
SHOW USERS
----- 创建用户
CREATE USER "readonly" WITH PASSWORD 'password'
----- 创建管理员权限的用户
CREATE USER "readonly" WITH PASSWORD 'password' WITH ALL PRIVILEGES
----- 删除用户
DROP USER "readonly"
----- 修改密码
SET PASSWORD FOR <username> = '<password>'
备份恢复
只支持全量备份,不支持增量,包括了元数据以及增量数据的备份,可以参考 官方文档 。
----- 元数据备份
$ influxd backup <path-to-backup>
----- 数据备份
$ influxd backup -database <mydatabase> <path-to-backup>
$ influxd backup -database telegraf -retention autogen -since 2016-02-01T00:00:00Z /tmp/backup
$ influxd backup -database mydatabase -host 10.0.0.1:8088 /tmp/remote-backup
----- 恢复
$ influxd restore -metadir /var/lib/influxdb/meta /tmp/backup
$ influxd restore -database telegraf -datadir /var/lib/influxdb/data /tmp/backup
数据保存策略
也就是 Retention Policies,可以设置保存的时间,例如保存 30 天。
----- 查询
SHOW RETENTION POLICIES ON "database_name";
----- 新建
CREATE RETENTION POLICY "rp_name" ON "db_name" DURATION 30d REPLICATION 1 DEFAULT;
----- 修改
ALTER RETENTION POLICY "rp_name" ON db_name DURATION 3w DEFAULT;
----- 删除
DROP RETENTION POLICY "rp_name" ON "db_name";
连续查询
也就是 Continuous Queries,当数据超过保存策略里指定的时间之后,就会被删除;可以通过连续查询把原来的秒级数据,保存为分钟级或者小时级的数据,从而减小数据的占用空间。
----- 查看
SHOW CONTINUOUS QUERIES;
----- 创建
CREATE CONTINUOUS QUERY cq-name ON db-name BEGIN
SELECT mean(tbl-name) INTO newtbl-name FROM tbl-name GROUP BY time(30m) END;
----- 删除
DROP CONTINUOUS QUERY <cq-name> ON <db-name>;
其它
1. 获取最近更新数据,并转换为当前时间
select threads_running from mysql order by time desc limit 1;
date -d @`echo 1483441750000000000 | awk '{print substr($0,1,10)}'` +"%Y-%m-%d %H:%M:%S"
2. 检查系统是否存活
$ curl -sl -I localhost:8086/ping
3. 常用操作
----- 简单查询
SELECT * FROM weather ORDER BY time DESC LIMIT 3;
----- 指定时间范围,时间格式也可以为'2017-01-03 00:00:00'
SELECT usage_idle FROM cpu WHERE time >= '2017-01-03T12:40:38.708Z' AND time <= '2017-01-03T12:40:50.708Z';
----- 最近40min内的数据
SELECT * FROM mysql WHERE time >= now() - 40m;
----- 最近5分钟的秒级差值
SELECT derivative("queries", 1s) AS "queries" from "mysql" where time > now() - 5m;
----- 最近5min的秒级写入
$ influx -database '_internal' -precision 'rfc3339'
-execute 'select derivative(pointReq, 1s) from "write" where time > now() - 5m'
----- 也可以通过日志查看
$ grep 'POST' /var/log/influxdb/influxd.log | awk '{ print $10 }' | sort | uniq -c
$ journalctl -u influxdb.service | awk '/POST/ { print $10 }' | sort | uniq -c
存储引擎
Bolt 是一个 Go 语言编写的嵌入式 KV 数据库,提供了一个简单可靠的方式做数据持久化,按照作者在 Github BoltDB 中的介绍:
Bolt is a pure Go key/value store inspired by Howard Chu's LMDB project. The goal
of the project is to provide a simple, fast, and reliable database for projects
that don't require a full database server such as Postgres or MySQL.
与 LevelDB 有所区别,BoltDB 支持完全可序列化的 ACID 事务;而且,提供稳定的 API 接口,而非类似 SQLite 的 SQL 接口;从而也就意味着它更加方便地整合到其它系统。
安装、使用
在设置好 golang 的环境变量之后,可以很简单的通过 go get 获取源码并安装到 $GOPATH/bin
目录下,其命令如下:
$ go get github.com/boltdb/bolt/...
参考
- 关于时序数据库的排名,可以参考 db-engines.com。
- 官方网站 www.influxdata.com,包括了相关的文档。
- 源码可以直接从 Github 下载,Github InfluxDB、Github Telegraf 。