OpenTSDB 详解
- - 运维生存时间OpenTSDB用HBase存储所有的时序(无须采样)来构建一个分布式、可伸缩的时间序列数据库. 它支持秒级数据采集所有metrics,支持永久存储,可以做容量规划,并很容易的接入到现有的报警系统里. OpenTSDB可以从大规模的集群(包括集群中的网络设备、操作系统、应用程序)中获取相应的metrics并进行存储、索引以及服务,从而使得这些数据更容易让人理解,如web化、图形化等.
yum install gnuplot autoconf apt-get install gnuplotOpenTSDB是用java编写的,但是项目构建不是用的java的方式而是使用的C、C++程序员构建项目的方式。运行时依赖:
yum install gnuplot automake autoconf git -y
git clone git://github.com/OpenTSDB/opentsdb.git cd opentsdb ./build.sh
COMPRESSION
和 HBASE_HOME
,前者设置是否启用压缩,或者设置hbase home目录。如果使用压缩,则还需要安装lzosrc/create_table.sh
tsdtmp=${TMPDIR-'/tmp'}/tsd # For best performance, make sure mkdir -p "$tsdtmp" # your temporary directory uses tmpfs ./build/tsdb tsd --port=4242 --staticroot=build/staticroot --cachedir="$tsdtmp" --auto-metric
--zkquorum
, --cachedir
对应的目录会产生一些临时文件,你可以设置cron定时任务进行删除。添加 --auto-metric
,则当新的数据被搜集时自动创建指标。
你可以将这些参数编写到配置文件中,然后通过 --config
指定该文件所在路径。
# List of Zookeeper hosts that manage the HBase cluster tsd.storage.hbase.zk_quorum = 192.168.1.100配置参数优先级: 命令行参数 > 配置文件 > 默认值 你可以在命令行中通过
--config
指定配置文件所在路径,如果没有指定,OpenTSDB会从以下路径寻找配置文件:
metric
不包括一个数值或一个时间,其仅仅是一个标签,包含数值和时间的叫 datapoints
,metric是用逗号连接的不允许有空格,例如:
TSUID
。在OpenTSDB的存储中,对于每一个metric、tagk或者tagv都存在从0开始的计数器,每来一个新的metric、tagk或者tagv,对应的计数器就会加1。当data point写到TSD时,UID是自动分配的。你也可以手动分配UID,前提是 auto metric
被设置为true。默认地,UID被编码为3Bytes,每一种UID类型最多可以有16,777,215个UID。你也可以修改源代码改为4Bytes。UID的展示有几种方式,最常见的方式是通过http api访问时,3 bytes的UID被编码为16进制的字符串。例如,UID为1的写为二进制的形式为 000000000000000000000001
,最为一个无符号的byte数组,其可以表示为 [0,0,1]
,编码为16进制字符串为 000001
,其中每一位左边都被补上0,如果其不足两位。故,UID为255的会显示为 [0,0,255]
和 0000FF
。
关于为什么使用UID而不使用hashes,可以参考: why-uids
TSUID。当一个data point被写到OpenTSDB时,其row key格式为: <metric_UID><timestamp><tagk1_UID><tagv1_UID>[...<tagkN_UID><tagvN_UID>]
,不考虑时间戳的话,将其余部分都转换为UID,然后拼在一起,就可以组成为TSUID。
Metadata。主要用于记录data point的一些附加的信息,方便搜索和跟踪,分为UIDMeta和TSMeta。
每一个UID都有一个metadata记录保存在 tsdb-uid
表中,每一个UID包括一些不可变的字段,如 uid
、 type
、 name
和 created
字段表示什么时候被创建,还可以有一些额外字段,如 description
、 notes
、 displayName
和一些 custom
key/value对,详细信息,可以查看 /api/uid/uidmeta
同样,每一个TSUID可以对应一个TSMeta,记录在 tsdb-uid
中,其包括的字段有 tsuid
、 metric
、 tags
、 lastReceived
和 created
,可选的字段有 description
, notes
,详细信息,可以查看 /api/uid/tsmeta
开启Metadata有以下几个参数:
tsd.core.meta.enable_realtime_uid
tsd.core.meta.enable_tsuid_tracking
tsd.core.meta.enable_tsuid_incrementing
tsd.core.meta.enable_realtime_ts
Annotations
,详细说明,请参考 annotations
Tree
src/create_table.sh
创建hbase表。建表语句如下:
create '$UID_TABLE', {NAME => 'id', COMPRESSION => '$COMPRESSION', BLOOMFILTER => '$BLOOMFILTER'}, {NAME => 'name', COMPRESSION => '$COMPRESSION', BLOOMFILTER => '$BLOOMFILTER'} create '$TSDB_TABLE', {NAME => 't', VERSIONS => 1, COMPRESSION => '$COMPRESSION', BLOOMFILTER => '$BLOOMFILTER'} create '$TREE_TABLE', {NAME => 't', VERSIONS => 1, COMPRESSION => '$COMPRESSION', BLOOMFILTER => '$BLOOMFILTER'} create '$META_TABLE', {NAME => 'name', COMPRESSION => '$COMPRESSION', BLOOMFILTER => '$BLOOMFILTER'}
tsdb
的表中,这是为了充分利用hbase有序和region分布式的特点。所有的值都保存在列族 t
中。
rowkey为 <metric_uid><timestamp><tagk1><tagv1>[...<tagkN><tagvN>]
,UID默认编码为3 Bytes,而时间戳会编码为4 Bytes
OpenTSDB的tsdb启动之后,会监控指定的socket端口(默认为4242),接收到监控数据,包括指标、时间戳、数据、tag标签,tag标签包括tag名称ID和tag值ID。例如:
myservice.latency.avg 1292148123 42 reqtype=foo host=web42对于指标myservice.latency.avg的ID为:[0, 0, -69],reqtype标签名称的ID为:[0, 0, 1], foo标签值的ID为:[0, 1, 11], 标签名称的ID为:[0, 0, 2] web42标签值的ID为:[0, -7, 42],他们组成rowkey:
[0, 0, -69, 77, 4, -99, 32, 0, 0, 1, 0, 1, 11, 0, 0, 2, 0, -7, 42] `-------' `------------' `-----' `------' `-----' `-------' metric ID base timestamp name ID value ID name ID value ID `---------------' `---------------' first tag second tagrow表示格式为: 每个数字对应1 byte
000
表示1个byte, 010
表示2byte, 011
表示4byte, 100
表示8byte1
或者 F
000
表示1个byte, 010
表示2byte, 011
表示4byte, 100
表示8byte1111011
,因为该值为整数且长度为8位(对应为2byte,故最后3bit为 100
),故其对应的列族名为: 0000011110110100
,将其转换为十六进制为 07B4
value 使用8bytes存储,既可以存储long,也可以存储double。
总结一下, tsdb
表结构如下:
tsdb-uid
用来存储UID映射,包括正向的和反向的。存在两列族,一列族叫做 name
用来将一个UID映射到一个字符串,另一个列族叫做 id
,用来将字符串映射到UID。列族的每一行都至少有以下三列中的一个:
metrics
将metric的名称映射到UIDtagk
将tag名称映射到UIDtagv
将tag的值映射到UIDname
列族还可以包括额外的metatata列。
sys.cpu.user
或者对于一个标签其值可能为 42
Column Qualifiers - 上面三种列类型中一种。
Column Value - 一个无符号的整数,默认被编码为3个byte,其值为UID。
例如以下几行数据是从 tsdb-uid
表中查询出来的数据,第一个列为row key,第二列为"列族:列名",第三列为值,对应为UID
proc.stat.cpu id:metrics \x00\x00\x01 host id:tagk \x00\x00\x01 cdh1 id:tagv \x00\x00\x01
metrics_meta
、 tagk_meta
、 tagv_meta
Column Value - 与UID对应的字符串,对于一个 *_meta
列,其值将会是一个UTF-8编码的JSON格式字符串。不要在OpenTSDB外部去修改该值,其中的字段顺序会影响 CAS
调用。
例如,以下几行数据是从 tsdb-uid
表中查询出来的数据,第一个列为row key,第二列为"列族:列名",第三列为值,对应为UID
\x00\x00\x01 name:metrics proc.stat.cpu \x00\x00\x01 name:tagk host \x00\x00\x01 name:tagv cdh1 \x00\x00\x01 name:tagk_meta {"uid":"000001","type":"TAGK","name":"host","description":"","notes":"","created":1395213193,"custom":null,"displayName":""} \x00\x00\x01 name:tagv_meta {"uid":"000001","type":"TAGV","name":"cdh1","description":"","notes":"","created":1395213193,"custom":null,"displayName":""} \x00\x00\x01 name:metric_meta {"uid":"000001","type":"METRIC","name":"metrics proc.stat.cpu","description":"","notes":"","created":1395213193,"custom":null,"displayName":""}总结一下,
tsdb-uid
表结构如下:
上图对应的一个datapoint如下:
proc.stat.cpu 1292148123 80 host=cdh1从上图可以看出
tsdb-uid
的表结构以及数据存储方式,对于一个data point来说,其被保存到opentsdb之前,会对 metrics
、 tagk
、 tagv
、 metric_meta
、 tagk_meta
、 tagv_meta
生成一个UID(如上图中的 000001
),然后将其插入hbase表中,rowkey为UID,同时会存储多行记录,分别保存 metrics
、 tagk
、 tagv
、 metric_meta
、 tagk_meta
、 tagv_meta
到UID的映射。
tsdb-meta
,该表只有一个列族 name
,两个列,分别为 ts_meta
、 ts_ctr
,该表中数据如下:
\x00\x00\x01\x00\x00\x01\x00\x00\x01 name:ts_ctr \x00\x00\x00\x00\x00\x00\x00p \x00\x00\x01\x00\x00\x01\x00\x00\x01 name:ts_meta {"tsuid":"000001000001000001","displayName":"","description":"","notes":"","created":1395213196,"custom":null,"units":"","dataType":"","retention":0,"max":"NaN","min":"NaN"} \x00\x00\x02\x00\x00\x01\x00\x00\x01 name:ts_ctr \x00\x00\x00\x00\x00\x00\x00p \x00\x00\x02\x00\x00\x01\x00\x00\x01 name:ts_meta {"tsuid":"000002000001000001","displayName":"","description":"","notes":"","created":1395213196,"custom":null,"units":"","dataType":"","retention":0,"max":"NaN","min":"NaN"}Row Key 和
tsdb
表一样,其中不包含时间戳, <metric_uid><tagk1><tagv1>[...<tagkN><tagvN>]
TSMeta Column 和UIDMeta相似,其为UTF-8编码的JSON格式字符串
ts_ctr Column 计数器,用来记录一个时间序列中存储的数据个数,其列名为 ts_ctr
,为8位有符号的整数。
Graphite
[root@cdh1 build]# ./tsdb usage: tsdb <command> [args] Valid commands: fsck, import, mkmetric, query, tsd, scan, uid
./tsdb mkmetric mysql.bytes_received mysql.bytes_sent
metrics mysql.bytes_received: [0, 0, -93] metrics mysql.bytes_sent: [0, 0, -92]