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

您所在的位置:网站首页 小米数据库txt下载 小米正用时序数据库,解决这个“硬核”问题

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

2024-06-05 16:57| 来源: 网络整理| 查看: 265

640?wx_fmt=jpeg

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

作者 | 许俊红

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

时序数据

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

时序数据

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

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

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

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

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

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

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

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

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

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

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

TSDB

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

640?wx_fmt=png

图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还提供了其他工具。

640?wx_fmt=png

图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,这样做主要是为了节省空间。

640?wx_fmt=png

图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]。

640?wx_fmt=png

图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地址:[email protected]:infra/opentsdb-demo.git。欢迎使用及反馈,也欢迎公司外部的技术爱好者一起交流讨论。

640?wx_fmt=png

图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点

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

640?wx_fmt=png

推荐阅读:

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

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

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

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

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

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

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

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

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

640?wx_fmt=png

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



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3