参加 2019 Python开发者日,请扫码咨询 ↑↑↑

作者 | 许俊红

来源 | 小米云技术(id:mi-cloud-tech)

时序数据

根据维基百科的定义[1],时间序列是一组按照时间发生先后顺序进行排列的数据点序列。时序数据库(Time Series Database,以下简称TSDB)就是存放时序数据的数据库。近年来,随着物联网等概念的流行,TSDB成为数据库一个相对独立的子领域逐渐受到重视,广泛应用于物联网、监控系统、金融、医疗和零售等多种场景。

时序数据

除了具备一般数据的共同特点外,受限于时间的因素,时序数据有很多独有的特点:

  • 数据通常按照时间顺序抵达

  • 抵达的数据几乎总是作为新条目被记录

  • 数据写入QPS通常远远大于读取QPS,而且读操作往往基于指标(即metric)读取与之相关的一簇数据

  • 数据写入速度通常比较平稳,无明显的波峰和波谷

  • 相邻数据之间通常具有一定的相似性

  • 在多数情况下,时序数据的价值会随着时间的推移而迅速下降

根据上述特点,时序数据系统设计有以下考虑:

  • 同一指标相关的数据最好分布在一起

  • 写操作侧重于高吞吐,读操作侧重于低延时

  • 因为时序数据的值都是数值,且前后有较大的相似性,因此数据压缩是有意义的,往往能显著提高读写效率,节约空间和其他成本

TSDB

如前所述,目前时序数据库普遍受到重视,各种TSDB也层出不穷[2],图1是著名数据库排名网站db-engine[3]过去两年有关数据库的趋势排名,TSDB增速最为明显。时序数据由于其独有的特点,很少直接使用关系型数据库或NoSQL数据库,而是经过独立设计、优化和实现的。

图1 过去两年数据库趋势排名(2019年3月)

OpenTSDB

OpenTSDB是一款能在不降低精度的情况下存储和处理海量数据的可扩展TSDB,其结构如图2所示[4]。此图以监控这个常用场景为例,展示了各个部分之间的关系。其中,Server节点为被监控的服务器,通常暴露一个HTTP接口供OpenTSDB调用、收集状态信息。

TSD是OpenTSDB的一个实例,内部结构如空心箭头所示,主要分为两个部分,一部分是Netty,用来读取用户的请求,以及返回用户操作的结果;另一部分是异步的Callback调用链,这些callback的主要作用是把用户参数转换为hbase client的scan或put的参数,包括参数校验、转换,HBase Client参数设置、读操作时的过滤器设置,最后通过异步客户端读写HBase集群。这两部分都是异步的,使得OpenTSDB以相对较低的资源消耗保证高吞吐。此外,为了方便用户的交互和维护,OpenTSDB还提供了其他工具。

图2 OpenTSDB系统架构图

关于OpenTSDB,大家比较关注的有Row key设计、compaction等几个方面。

RowKey设计

OpenTSDB使用外部NoSQL存储引擎存储数据,支持HBase、BigTable等,因为NoSQL往往是schema-free或者semi-schema的key-value形式进行存储,所以其row key的设计对于读写性能有非常重要的影响。这里以使用最广泛的HBase存储引擎为例进行分析。

Row Key的数据模型如图3所示[5],第一个字节表示是否开启盐化,然后三个字节表示metric,接下来四个字节表示数据时间戳,最后是数据的若干个tag,默认情况下OpenTSDB允许最多8个tag key。另外,需要注意的是,实际存入HBase数据表中的是各个metric、tag的uid,即OpenTSDB把metric映射为一个固定字节的id(即uid)存储HBase的另一张表中,而在数据表中用uid标识某一个metric或者tag,这样做主要是为了节省空间。

图3 OpenTSDB存储在HBase中的Row Key设计

除了通过uid节约存储空间外,row key的构成也是很有趣的,即metric + timestamp + tagk1 + tagv1...,采用这种顺序,是为了访问模式和性能的考虑:

  • 首先,timestamp 不适合作为前缀。timestamp作为前缀容易造成热点问题,而且对于多数较大时间跨度的查询都需要对这段时间内的绝大多数数据做扫描,效率比较低下。

  • 其次,tag 也不适合作为前缀。tag作为前缀避免了热点问题,但无法避免查询的低效。主要原因是用户关心的是以包含metric的一簇数据,如果使用metric作为前缀,不但避免了热点问题,还能大大缩小扫描数据的范围。

  • 再次,timestamp应该放在tag之前。前面两点决定了必须以metric为前缀,那么如果tag放在timestamp前面有什么坏处呢?这里必须提到OpenTSDB设计的初衷。对于时序数据而言,我们不可能在保证高性能的情况下,同时满足高精度、长时间跨度和多标签(即tag)的查询。不同的TSDB对此有不同的折中。OpenTSDB选择限制tag(限制tag key数量,虽然可以配置)以保证比较长的时间跨度。因此,tag的筛选度低于时间这一因素,也就是说timestamp应该放在tag前面。

另外,这里的timestamp是整点小时的时间戳。qualifier是事件发生的时间戳相对整点时间的偏移,分为秒、毫秒和秒与毫秒混合三种类型。在某些场景下(比如下文的compaction),qualifier也支持将多个时间戳拼接在一起,构成一个qualifier,与拼接的value值一一对应。图4以秒为例展示了整个HBase数据表的结构[6]。

图4 OpenTSDB存储在HBase中的数据表结构

Compaction

OpenTSDB compaction是把存储在HBase数据表中的每一行中的多个qualifier按照时间顺序拼接成一个qualifier,多个value拼接成一个value,以节约存储空间、提高查询效率。这一设计,主要基于以下事实:

  • 由于时序数据的特点,用户很少会只读取某一个时刻的数据,往往是读取一个时序序列,实际上OpenTSDB也没有API提供对某一特定时间点的读操作。

  • 存储引擎HBase对每个时间点的存储格式是row key + column family + qualifier + value(略去无关内容)。显然,对于每行的多列数据来说,row key、column family是冗余的

Compaction的实现是有一个单独的线程从HBase中把每行数据读出来,然后把这些数据进行合并,写入新的qualifier和对应的value,最后把过期数据从HBase中删除。这一过程加重了HBase客户端与HBase服务器端的负载,会造成HBase性能的抖动,在生产环境中一般关闭这一特性,也可以在时序数据库所在的物理资源消耗相对低峰的时候,定期执行compaction,来实现数据压缩的目的。

最佳实践

OpenTSDB作为一款高性能TSDB,有很多优点,但使用不当也会造成预料之外的后果,以下是一些实践上的参考:

  • 优化HBase:在很多情况下,HBase是读写处理流程的核心,也是耗时最多的环节,优化OpenTSDB首先要优化HBase。这些措施包括调整BlockCache、优化GC和开启压缩等。优化HBase本身是一个复杂的话题,这里不展开。

  • 使用explicitTags:对于基数(Cardinality)比较高的tag来说,使用explicitTags时,OpenTSDB会为HBase Client添加一个额外的过滤器Fuzzy Filter,使筛选过程更高效;对于多个tag的metric,使用explicitTags能过滤掉多余的数据,保证结果正确。

  • 启用盐化:启用盐化之后,OpenTSDB会启动多个线程并发对请求进行处理,降低请求的延时。

  • 控制tag的状态空间:合理选择tag,使所有tag的组合数不要过大。如前所述,tag key状态空间过大会导致HBase RegionServer的scan操作加载过多的无关数据,导致响应缓慢。Tag key的最大个数是可以配置的,谨慎考虑改变这个配置项。

小米时序数据库服务

我们使用Kubernetes来解决时序服务的申请、创建、扩容和删除等繁琐的流程,快速响应流量突变等需求,提升效率、节约成本,其结构如图5所示。整个结构分为两个部分,一部分是OpenTSDB的管理系统,一部分是OpenTSDB集群。两者都运行在Kubernetes的Pod里,应用的状态由Kubernetes维护。

OpenTSDB管理系统负责创建、编辑和删除OpenTSDB集群以及监控等管理功能。该系统对接了公司内部的身份认证系统,给不同的角色以不同的权限。管理系统共有三种角色:

  • 一种是普通用户,可以使用所属的OpenTSDB资源进行读写,还可以通过管理系统查看本集群的信息,比如读写QPS、所占用的空间等信息。

  • 另一种是管理员权限,可以申请、编辑和删除集群,集中管理某个具体业务线的OpenTSDB资源。

  • 还有一种是超级管理员,负责审批资源和其他一切权限。整个流程只需线上操作,申请通过后,一般在一分钟之内OpenTSDB集群即可创建成功,并自动生成可供用户读写的域名。用户根据OpenTSDB协议即可进行读写操作。整个过程避免了用户申请物理机器和域名、搭建集群、监控和维护集群状态等繁琐的线上线下操作,大大提高了效率。

另一部分是OpenTSDB的读写系统。用户可通过域名读写OpenTSDB,同时OpenTSDB集群天然继承了Kubernetes服务治理的一整套机制和工具,包括日志、监控、自动重启等。我们还将对每个OpenTSDB集群提供对应的图形化的访问和监控界面Grafana。对于用户来说,访问部署在Kubernetes上的OpenTSDB集群与访问部署在物理机器上的集群没有体验上的差别。

目前内部产品已经上线,产品文档:http://docs.api.xiaomi.net/opentsdb-manager/ ,使用demo gitlab地址:git@v9.git.n.xiaomi.com:infra/opentsdb-demo.git。欢迎使用及反馈,也欢迎公司外部的技术爱好者一起交流讨论。

图5 小米时序数据库服务

展望


未来,我们将在以下方面改进我们的服务:

  • 密切关注社区最新进展。特别地,OpenTSDB 3.0提供了更多更新的特性,功能强大,值得期待。同时,我们也将积极参与和回馈社区。

  • 如有需要,我们将使系统的执行过程更加弹性和可观测:比如根据负载情况自动伸缩;可以方便地观测每个读写请求的执行路径、耗时情况、失败或者异常发生的位置等,以便能更快地定位和解决问题。

  • 针对公司内部的需求做定制。比如对tag提供更强大的支持、与云原生技术更好地结合等

  • 对标商业化产品,为用户提供更方便易用的功能。

总之,OpenTSDB本身的设计迎合了计算与存储分离的趋势,并兼具高性能、高精度和易扩展等诸多优点。我们基于此开发的这个时序数据服务已于近日上线,欢迎试用。同时,我们也将密切关注时序数据库的技术潮流,拥抱开源,提供越来越好的用户体验。

参考文献:

[1]https://zh.wikipedia.org/wiki/%E6%99%82%E9%96%93%E5%BA%8F%E5%88%97

[2]https://misfra.me/2016/04/09/tsdb-list/

[3]https://db-engines.com/en/ranking/time+series+dbms

[4] http://opentsdb.net/overview.html

[5] http://www.nosqlnotes.com/technotes/opentsdb-tabledesign/

[6] https://blog.csdn.net/b6ecl1k7bs8o/article/details/84207777

(本文为 AI科技大本营转载文章,转载请微信联系 1092722531)

公开课推荐

今晚8点

近年来,聊天机器人技术及产品得到了快速的发展,本课程将全面阐述聊天机器人的技术框架及工程实现细节,并对于聊天机器人的下一代范式:虚拟生命,进行了详细的剖析,同时,聚焦知识图谱在实现认知智能过程中的重要作用,给出了知识图谱的落地实践。

推荐阅读:

  • 数学界“诺奖”Abel Prize迎来首位女性得主

  • NLP实践:对话系统技术原理和应用

  • 提升效率,这十个Pandas技巧必不可少!

  • 超常用的Python代码片段 | 备忘单

  • 没有新芯片,没有大核弹,黄教主这次给大家带来了个PRADA

  • 淘宝、飞猪、闲鱼都挂了,阿里云却正常?!

  • 要钱还是要命? 比特币正悄悄杀死你...

  • 前阿里 P9 级员工称离婚是模拟测试,已回滚复婚!

  • 教训!学 Python 没找对路到底有多惨?

❤点击“阅读原文”,查看历史精彩文章。

小米正用时序数据库,解决这个“硬核”问题相关推荐

  1. 云原生数据库POLARDB专场“硬核”解析

    POLARDB是阿里巴巴自主研发的云原生关系型数据库,目前兼容三种数据库引擎:MySQL.PostgreSQL.Oracle.POLARDB的计算能力最高可扩展至1000核以上,存储容量可达100TB ...

  2. SQLServer “无法对数据库‘XXX‘ 执行删除,因为它正用于复制”的解决方法

    SQLServer "无法对数据库'XXX' 执行删除,因为它正用于复制"的解决方法 参考文章: (1)SQLServer "无法对数据库'XXX' 执行删除,因为它正用 ...

  3. mysql数据库主要用来做什么的_为什么有了 MySQL ,还要有时序数据库?

    " 你应该敬畏时间 , 因为那是一切的密码. --电影<星际穿越> "近日,UCloud新发布了一款时间序列数据库UTSDB (UCloud TimeSeries Da ...

  4. 时序数据库永远的难关 — 时间线膨胀(高基数 Cardinality)问题的解决方案

    简介: 本文主要讨论 influxdb 在遇到写入的数据出现高基数 Cardinality 问题时,一些可行的解决方案. 作者 | 徐建伟 (竹影) 前序 随着移动端发展走向饱和,现在整个 IT 行业 ...

  5. 从前世今生聊一聊,大厂为啥亲睐时序数据库

    摘要:本文会从时序数据库的基本概念.应用场景.需求与能力等方面一一展开,带你了解时序数据库的前世今生. 时序数据库忽然火了起来.Facebook开源了beringei时序数据库,基于PostgreSQ ...

  6. 阿里云成为国内首个时序数据库标准工作组成员

    摘要: 国内首个时序数据库标准制定中,阿里云成为标准工作组认证成员 近期,在中国信息通信研究院的牵头下,阿里云参与了国内首个时间序列数据库标准的制定,也正式成为该标准工作组成员.此标准属于中国通信标准 ...

  7. 博士五年,我在清华做时序数据库

    本文字数:8888字 阅读时间:23分钟 序 先自我介绍一下,乔嘉林,网名铁头乔,2016年西安交大计算机系本科毕业之后,来到清华大学软件学院直博,师从王建民教授,大师兄黄向东,今年顺利毕业.回首往事 ...

  8. 时序数据到底是什么,为什么我们需要时序数据库?

    作者:刘东华 什么是时序数据?如何存储?如何分析并挖掘其中的价值? 先看个问题:自动驾驶的特斯拉.自动华尔街交易算法.智能家居.当日送达的快递.跟踪每日新冠统计数据和社区空气质量,这些有什么共同之处? ...

  9. [渣翻]从零开始写一个时序数据库

    来源:https://fabxc.org/tsdb/ 作者:Fabian Reinartz 适用人群:对于时序数据库底层设计有兴趣的开发人员,和对底层技术工程管理有兴趣的管理人员 此版本为翻后精简版, ...

最新文章

  1. 2022-2028年中国草炭土行业市场研究及前瞻分析报告
  2. “后 PC”时代,应用为王
  3. c语言pow函数用法_C语言基础的不能再基础的程序知识!“hello world”!
  4. 运维常说的 5个9、4个9、3个9 的可靠性,到底是什么???
  5. android服务自动重启,安卓service关闭后怎么自动重启
  6. java课程设计实验报告_javaweb课程设计实验报告
  7. 09:向量点积计算【一维数组】
  8. 如何安装Exchange2010上安装更新汇总(Update Rollup)
  9. 解决NetworkOnMainThreadException
  10. zabbix邮件报警功能的验证
  11. 团队-科学计算器-代码设计规范
  12. SpringMVC 注解 @Scope、@PostConstruct、@PreDestroy、@ComponentScan
  13. Linux作业--利用RAID技术实现磁盘阵列的管理方法
  14. 详解大型分布式电商系统架构
  15. mysql python insert 添加数据
  16. OpenSSL 生成CA证书及终端用户证书
  17. C语言扫雷游戏代码以及基本原理教学(一看就会)
  18. Linux学习笔记2—常见指令的使用
  19. [渝粤教育] 无锡商业职业技术学院 团队管理 参考 资料
  20. 蓝桥ROS机器人系统更新和功能包安装记录

热门文章

  1. [轉]在jQuery1.5中使用deferred对象 - 拿着放大镜看Promise
  2. 特斯拉研究报告:产品、工厂、技术、生态展望
  3. 各系统QT安装ROS后不显示src问题
  4. [Machine Learning with Python] Data Visualization by Matplotlib Library
  5. spark之scala快速入门
  6. Nexus Repository Manager 3.0 发布
  7. 从svn下载的Mavn项目,到本地后不识别(MyEcplise)
  8. java 的回调函数
  9. 关于百度编辑器UEditor在asp.net中的使用方法!
  10. C#对象数组排序方法