什么是时间序列数据?最简单的定义就是数据格式里包含timestamp字段的数据。比如股票市场的价格,环境中的温度,主机的CPU使用率等。但是又有什么数据是不包含timestamp的呢?几乎所有的数据都可以打上一个timestamp字段。时间序列数据更重要的一个属性是如何去查询它。在查询的时候,对于时间序列我们总是会带上一个时间范围去过滤数据。同时查询的结果里也总是会包含timestamp字段。
时间序列数据无处不在。而几乎任意数据库都可以存时间序列数据。但是不同的数据能支持的查询类型并不相同。按照能支持的查询类型,我们可以把时间序列数据库分为两类,第一类的数据库按照关系型数据库的说法,其表结构是这样的:
[metric_name] [timestamp] [value]
其优化的查询方式是:
SELECT value FROM metric WHERE metric_name=”A” AND timestamp >= B AND timestamp < C
也就说这类数据库是什么样子的数据存进去,就什么样子取出来。
在这种模式下,首先要知道你需要的图表是什么样子的。然后按照这个图表的数据,去把数据入库。查询的字段,就是数据库存储的字段。然后再按照数据库存储的字段,去从原始数据里采集上报。存储什么字段,就上报什么字段。这种模式很容易优化,可以做到非常快。但是这种模式有两个弊端。
这类时间序列数据库最多,使用也最广泛。一般人们谈论时间序列数据库的时候指代的就是这一类存储。按照底层技术不同可以划分为三类。
另外一类数据库其表结构是:
[timestamp] [d1] [d2] .. [dn] [v1] [v2] .. [vn]
其优化的查询方式不限于查询原始数据,而是可以组合查询条件并且做聚合计算,比如:
SELECT d2, sum(v1) / sum(v2) FROM metric WHERE d1 = “A” AND timestamp >= B AND timestamp < C GROUP BY d2
我们希望时间序列数据库不仅仅可以提供原始数据的查询,而且要支持对原始数据的聚合能力。这种聚合可以是在入库阶段完成的,所谓物化视图。也可以是在查询阶段完成,所谓实时聚合。根据实际情况,可以在这两种方式中进行取舍。
想要在在查询阶段做数据的聚合和转换,需要能够支持以下三点。
要想尽可能快的完成整个查询过程,需要在三个环节上都有绝招。传统上说,这三个步骤是三个不同的技术领域。
前面提到的时间序列库(比如 opentsdb )有不少从功能上来说是没有问题。它们都支持过滤,也支持过滤之后的聚合计算。在数据量小的时候勉强是可用的。但是如果要实时从十亿条里取百万记录出来,再做聚合运算,对于这样的数据量可能就勉为其难了。满足海量数据实时聚合要求的数据库不多,比较常见的有这么几种:
其中Elasticsearch是目前市场上比较很少有的,能够在检索加载和分布式计算三个方面都做得一流的数据库。而且是开源并且免费的。它使用了很多技术来达到飞一般的速度。这些主要的优化措施可以列举如下。
后面我们分为两篇文章用科普的方式,具体来看看Elasticsearch是基于什么原理如何做到比mysql和opentsdb更快地查询和聚合时间序列数据的。
陶文,曾就职于腾讯IEG的蓝鲸产品中心,负责过告警平台的架构设计与实现。2006年从ThoughtWorks开始职业生涯,在大型遗留系统的重构,持续交付能力建设,高可用分布式系统构建方面积累了丰富的经验。
感谢张凯峰对本文的策划,丁晓昀对本文的审校。
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ,@丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入InfoQ读者交流群 )。