11 月 19 - 20 日 Apache Pulsar 社区年度盛会来啦,立即报名! 了解详情
写点什么

时间序列数据库的秘密(1)—— 介绍

  • 2015-08-11
  • 本文字数:2687 字

    阅读完需:约 9 分钟

什么是时间序列数据?最简单的定义就是数据格式里包含 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

我们希望时间序列数据库不仅仅可以提供原始数据的查询,而且要支持对原始数据的聚合能力。这种聚合可以是在入库阶段完成的,所谓物化视图。也可以是在查询阶段完成,所谓实时聚合。根据实际情况,可以在这两种方式中进行取舍。

想要在在查询阶段做数据的聚合和转换,需要能够支持以下三点。

  • 用索引检索出行号:能够从上亿条数据中快速过滤出几百万的数据。
  • 从主存储按行号加载:能够快速加载这过滤出的几百万条数据到内存里。
  • 分布式计算:能够把这些数据按照 GROUP BY 和 SELECT 的要求计算出最终的结果集。

要想尽可能快的完成整个查询过程,需要在三个环节上都有绝招。传统上说,这三个步骤是三个不同的技术领域。

  • 检索:这是搜索引擎最擅长的领域。代表产品是 Lucene 。其核心技术是基于高效率数据结构和算法的倒排索引。
  • 加载:这是分析型数据库最擅长的领域。代表产品是 C-store Monetdb 。其核心技术是按列组织的磁盘存储结构。
  • 分布式计算:这是大数据计算引擎最擅长的领域。代表产品是 Hadoop spark 。其核心技术是 sharding 和 map/reduce 等等。

前面提到的时间序列库(比如 opentsdb )有不少从功能上来说是没有问题。它们都支持过滤,也支持过滤之后的聚合计算。在数据量小的时候勉强是可用的。但是如果要实时从十亿条里取百万记录出来,再做聚合运算,对于这样的数据量可能就勉为其难了。满足海量数据实时聚合要求的数据库不多,比较常见的有这么几种:

其中 Elasticsearch 是目前市场上比较很少有的,能够在检索加载和分布式计算三个方面都做得一流的数据库。而且是开源并且免费的。它使用了很多技术来达到飞一般的速度。这些主要的优化措施可以列举如下。

  • Lucene 的 inverted index 可以比 mysql 的 b-tree 检索更快。
  • 在 Mysql 中给两个字段独立建立的索引无法联合起来使用,必须对联合查询的场景建立复合索引。而 lucene 可以任何 AND 或者 OR 组合使用索引进行检索。
  • Elasticsearch 支持 nested document,可以把一批数据点嵌套存储为一个 document block,减少需要索引的文档数。
  • Opentsdb 不支持二级索引,只有一个基于 hbase rowkey 的主索引,可以按行的排序顺序 scan。这使得 Opentsdb 的 tag 实现从检索效率上来说很慢。
  • Mysql 如果经过索引过滤之后仍然要加载很多行的话,出于效率考虑 query planner 经常会选择进行全表扫描。所以 Mysql 的存储时间序列的最佳实践是不使用二级索引,只使用 clustered index 扫描主表。类似于 Opentsdb。
  • Lucene 从 4.0 开始支持 DocValues,极大降低了内存的占用,减少了磁盘上的尺寸并且提高了加载数据到内存计算的吞吐能力。
  • Lucene 支持分 segment,Elasticsearch 支持分 index。Elasticsearch 可以把分开的数据当成一张表来查询和聚合。相比之下 Mysql 如果自己做分库分表的时候,联合查询不方便。
  • Elasticsearch 从 1.0 开始支持 aggregation,基本上有了普通 SQL 的聚合能力。从 2.0 开始支持 pipeline aggregation,可以支持类似 SQL sub query 的嵌套聚合的能力。这种聚合能力相比 Crate.io,Solr 等同门师兄弟要强大得多。

后面我们分为两篇文章用科普的方式,具体来看看 Elasticsearch 是基于什么原理如何做到比 mysql 和 opentsdb 更快地查询和聚合时间序列数据的。

作者简介

陶文,曾就职于腾讯 IEG 的蓝鲸产品中心,负责过告警平台的架构设计与实现。2006 年从 ThoughtWorks 开始职业生涯,在大型遗留系统的重构,持续交付能力建设,高可用分布式系统构建方面积累了丰富的经验。


感谢张凯峰对本文的策划,丁晓昀对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-08-11 08:3135101

评论 4 条评论

发布
用户头像
写的很棒
2020-07-24 16:10
回复
用户头像
2020-04-08 09:13
回复
用户头像
厉害
2020-03-22 23:29
回复
用户头像
是不是大神写的文章就能看出来, 厉害啊,通俗易懂,膜拜一下
2019-10-10 18:05
回复
没有更多了
发现更多内容

开发利器——C语言必备实用第三方库

码哥比特

c c++ Linux 后端 框架

C语言第三方库Melon开箱即用之词法分析器使用

码哥比特

c c++ Linux 后端 框架

第十二周命题作业

cc

week12-conclusion

J

数据量大读写缓慢如何优化(5)【读缓存】

我爱娃哈哈😍

redis 缓存 架构设计实战 缓存设计

微信红包封面,2021年为啥突然火了?

架构精进之路

春节 微信红包封面 商业洞察

sonarLint与IntelliJ IDEA 集成

夏兮。

【活动回顾】4步2小时,搭建爆火的语音聊天室

ZEGO即构

写公号大半年,看看我都收获了些啥

架构精进之路

技术 总结 微信公众号 成长笔记

DO、DTO、BO、VO、POJO区别

安琪拉的博客

系统设计

日记 2021年2月16日(周二)

Changing Lin

2月春节不断更

分布式任务框架:xxl-job使用问题整理

程序员架构进阶

开源 分布式任务调度 七日更 2月春节不断更 XXL-JOB

【STM32】TIM---基本定时器

AXYZdong

硬件 stm32 2月春节不断更

诊所数字化:诊所老板为什么拒绝预约制?

boshi

数字化转型 医院 七日更

翻译:《实用的Python编程》01_05_Lists

codists

人工智能 后端 python 爬虫 列表 数据结构与算法

揭秘登上2021春晚舞台的黑科技-XR技术

架构精进之路

黑科技 vr 春晚 XR MR

第十二周学习心得

cc

这是我的第一次JavaScript初级技巧

我是哪吒

JavaScript 学习 程序员 大前端 2月春节不断更

ElasticSearch.03 - 基本原理

insight

elasticsearch 2月春节不断更

LeetCode题解:62. 不同路径,动态规划,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

消息队列Kafka:入门基础

正向成长

kafka

第一次异地过年有感

石君

思考 情感

13. 如果自己写的 Python 程序出错了,怎么办?

梦想橡皮擦

python 爬虫 2月春节不断更

翻译:《实用的Python编程》01_04_Strings

codists

人工智能 爬虫 后端 数据结构与算法 Python Monad

深度讲解背包问题:面试中每五道动态规划就有一道是背包模型 ...

宫水三叶的刷题日记

深度思考 面试 LeetCode 动态规划 数据结构与算法

今日笔记

Nydia

1480. 一维数组的动态和

小马哥

算法 七日更

【LeetCode】数组拆分Java题解

Albert

算法 LeetCode 2月春节不断更

C语言实用第三方库Melon开箱即用之多线程模型

码哥比特

c c++ Linux 后端 框架

1.开篇(听说你还在艰难的啃react源码)

全栈潇晨

React React Hooks react源码

2.react心智模型(来来来,让大脑有react思维吧)

全栈潇晨

React React Hooks react源码

时间序列数据库的秘密(1)—— 介绍_数据库_陶文_InfoQ精选文章