时间序列数据库OpenTSDB设计
Posted gangpao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了时间序列数据库OpenTSDB设计相关的知识,希望对你有一定的参考价值。
日常开发中,我们经常会遇到如下实时监控需求:
样例1:横轴时间,纵轴平均每秒写请求此时。
样例2:横轴时间,纵轴系统负载。
样例3:横轴时间,纵轴写请求延迟。
该类监控的需求:
如何高效存储时间序列的数据;
如何处理高并发的读写操作;
如何在存储的时候,节省磁盘内存开销。
解决方案:tsdb(Time Series Database),先来看看tsdb相关的关键字和基本概念。(如下图所示)
数据点:(time,value)
原型:proc.loadavg.1m,每分钟一个原型
其他注释:host=web42 pool=static
时间序列:ts=原型+其他注释。
处理量级:百万级的时间序列,亿级的数据点。
OpenTSDB基本概念:
基于Hbase构建的
分布式,可伸缩的时间序列数据库
秒级数据采集所有metrics(原型),支持永久存储,可以做存储规划。
可以从大规模的集群(包括集群中的网络设备,操作系统,应用程序)中获取相应的metrics进行存储,索引及服务
OpenTSDB开发建议
适用于宽行(比如每行上百个列),可以用行合并技巧让窄行变宽行。
把时间轴的数据按照一定频率切割,使得各个时间段读写独立。
在每对kv中存尽可能多的数据,如果k过多,会导致大量开销。
OpenTSDB开发避免
在应用端,不要使用HTable/HTablePool来访问OpenTSDB,因为这两个操作是同步操作的,不适合高并发。建议使用asynchbase(Hbase异步库)+Netty(高并发的server端)。Htable操作和asynchbase性能比较如下图:
key尽可能做到等长,变长的key会降低scan的效率。
每个RegionServer中的regions个数不要超过万级,预防挂掉后恢复速度慢。
step1:时间序列数据在Hbase上的简单存储。
查询方法scan key的到column的value,以时间轴的方式展示。
step2:如果多个metric在不分表的情况下存放在一起,在hbase上的存储如下:
把metric名字放在前面,使的同类型数据物理汇聚,快速批量查询。
step3:setp2存在问题是metric本身在key中占用很长的字符串,存储开销比较大,而且长度不一不易于scan查询,可以用字典值替换,如下:
另存字典表(字典表数据量极少):
step4:OpenTSDB适合存放宽行,而现在没每个key只有一个value,可以用拉链方式让“窄行”变“宽行”,每行存放的列数可以根据页面展示粒度来控制,当然不宜太多。
每行用偏移量递增存放,这样每个key可以拉出一批数据。大大提升scan的速度。
step5:从step4可以看出原先的3个key对应3个value列变成新的一个key对于3个列,表面上来看存储开销降低了,但实际上并非如此。这里简要介绍一下Hbase的物存储逻辑。Hbase是列式存储,数据是按列存储-每一列单独存放,每一列由key来处理-查询的并发处理。
只是同一个column-family在物理上是连续的。
Hbase存储单元是region,而region由region-server来维护。
Region由一个或者多个Store组成,每个store保存一个columns family;
每个Strore又由一个memStore和0至多个StoreFile组成
memStore存储在内存中,StoreFile存储在HDFS上。结论是:宽行并不比窄行节省存储空间。
step6:可以使用行压缩技术,预先定义一种存储和解析协议,把多列值压缩成单列存储,可以达到节省空间的效果。
当然代价有多个:
数值中不能包含解析关键字“:;”
原本多列独立的值被捆绑在了一起,单列值单独修改代价变大
当然本次讨论问题是OpenTSDB设计,上面的设计在这个业务环境中非常完美。任何脱离应用需求的设计都是纸上谈兵,不存在完美的能解决所有业务需求的库,只有巧妙的人才。
以上是关于时间序列数据库OpenTSDB设计的主要内容,如果未能解决你的问题,请参考以下文章