小米正用时序数据库,解决这个“硬核”问题
参加 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 没找对路到底有多惨?
❤点击“阅读原文”,查看历史精彩文章。
相关文章:

【Qt】通过QtCreator源码学习Qt(八):插件生命周期及对应状态(代码走读)
1、简介 PluginManager管理插件IPlugin的生命周期,从初始化插件到删除插件共八个状态。插件状态表——PluginSpec::enum State { Invalid, Read, Resolved, Loaded, Initialized, Running, Stopped, Deleted}; 插件IPlugin的状态记录在与插件对应的插件说明PluginSpec中,状态…

第七课 环境变量PATH,cp、mv及查看文档cat/more/less/head/tail命令
一、环境变量(PATH)echo $PATH 查看环境变量的目录PATH$PATH:/tmp/ (目录)给一个目录赋值环境变量; 让以上环境变量永久生效: 编辑 vi /etc/profile/ 把以上参数加入到文本的最后,退出&#x…

asp.net获取页面url参数值的实现代码实例
asp.net获取页面url参数值的实现代码实例 file: default.aspx.cs using system; using system.data; using system.configuration; using system.collections; using system.web; using system.web.security; using system.web.ui; using system.web.ui.webcontrols; using sys…

【Qt】编译QtCreator
一、Ubuntu14.04编译QtCreator 4.0.3 1、准备工作 编译工具要求 Qt >= 5.5.0; g++ >= 4.7; 2、编译步骤 cd <QtCreator源码目录> qmake -r make 3、安装 make install INSTALL_ROOT=<指定目录> 二、Win10编译QtCreator 4.7.1 1、准备工作 编译工具…

Go Pro 半小时上手指南
Jack刚买了台Go Pro 6,商品包装内没有说明书,希望尽快拍那种慢动作或者酷炫的照片,去网上看了些贴都是注重结果,很少讲具体设置或技巧,光靠自己研究什么时候才能入门?《Go Pro 半小时上手指南》为你解决这些…

出身清华,大神朱俊彦再出GauGAN:AI让你变身神笔马良
参加 2019 Python开发者日,请扫码咨询 ↑↑↑作者 | Just出品 | AI科技大本营(ID:rgznai 100)一次 TED 演讲中,前锤子科技设计总监罗子雄分享如何入门学设计的经验。要想学好设计,他提醒观众要先看基础实例教程。由于互…

delphi中的第三方控件如何安装 (转)
最佳答案 由于组件提供的方式不同,所以安装的方法也是不一样的,下面就目前常见的各种形式的组 件的安装方法介绍一下。 1只有一个DCU文件的组件。DCU文件是编译好的单元文件,这样的组件是作者不想把源码公 布。一般来说,作…

【Qt】Qt中使用ssl时报错:qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method
一、问题 在Qt中使用https,运行时报错: qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method二、原因分析 SSLv2由于某些漏洞导致的不安全原因, 在某些linux发行版里的openssl库禁用掉了SSLv2 三、解决办法 重新编译openssl 1、下载openssl git clone …

渡鸦创始人离职百度后的下一个“真相”
参加 2019 Python开发者日,请扫码咨询 ↑↑↑作者 | 琥珀出品 | AI科技大本营(ID:rgznai100)一直以来,渡鸦科技被外界看做是百度一次失败的收购。彼时彼刻,国内外智能音箱市场成为最火爆的兵家必争之地。渡鸦创始人、原…

QuickBI助你成为分析师——数据源FAQ小结
摘要: 添加数据源的时候经常会遇到各种问题,下面来讲解一下常见情况,若仍有疑问扫码咨询哦!使用 Quick BI 分析数据时,需要先指定原始数据所在的数据源,测试连通数据源是数据分析的基础,下面让我…

HTML5 学习笔记(一)- video
直到现在,仍然没有一项可以让网页上显示视频的标准。大多数的视频都是通过插件(如Flash)来实现播放的,但是并不是所有的浏览器拥有同样的插件。 而伟大的HTML5规定了一个元素<video>来实现这种功能。 <video>支持Ogg、…

【Qt】通过QtCreator源码学习Qt(九):容器算法总结
一、简介 本节总结QtCreator中封装的容器算法接口,源码文件的路径src/libs/utils/algorithm.h。 算法接口包括:判断、查找、删除、统计、排序、转换、拆分、过滤 二、算法源码讲解 1、判断 Utils::anyOf、Utils::allOf Utils::anyOf如果容器中有任一符合条件的元素,则返…

今晚8点直播 | 详解聊天机器人落地及进阶实战
近年来,聊天机器人技术及产品得到了快速的发展。聊天机器人作为人工智能技术的杀手级应用,发展得如火如荼,各种智能硬件层出不穷。本次公开课中,AI科技大本营联合电子工业出版社博文视点邀请到上海瓦歌智能科技有限公司总经理&…

webpack源码之tapable
引言 去年3月的时候当时写了一篇webpack2-update之路,到今天webpack已经到了4.2,更新挺快的,功能也在不断的完善,webpack4特性之一就是零配置, webpack生命力真的很顽强,积极跟上环境的变化,响应社区的需求,不断的迭代,因为parcel在其之前就有这个特性了。直接运行webpack命令,…

常用的 linux命令
为什么80%的码农都做不了架构师?>>> 将目录dir1复制成目录dir2 cp -R file1 file2 同时将文件file1、file2、file3与目录dir1复制到dir2 cp -R file1 file2 file3 dir1 dir2 mv dir1 dir2 移动或修改目录名称 rm -rf 删除文件&目录 vi :q! :wq mk…

68款大规模机器学习数据集,涵盖CV、语音、NLP | 十年资源集
参加 2019 Python开发者日,请扫码咨询 ↑↑↑作者 | 琥珀出品 | AI科技大本营(ID:rgznai100)此前营长为大家分享过不少机器学习相关数据集的资源,例如 Mozilla 的 1400 小时开源语音数据集;ApolloScape 的大规模自动驾…

【Qt】Q_PROPERTY():属性系统
一、简介 Qt属性系统基于元对象Meta-Object系统,因此在使用时,需要继承QObject类并添加宏Q_OBJECT,属性除了具有类成员的功能外,还可以通过元对象系统访问,比如可以使用信号和槽机制。 二、使用方法 在继承QObject的类中,使用宏Q_PROPERTY()来注册属性。 Q_PROPERTY(…

从零开始学 Python 之运算符
从零开始学 Python 之运算符 前言 大家好,这里是「痴海」从零开始学习 Python 系列教程。此文首发于「痴海」公众号,欢迎大家去关注。学习一门语言最好的办法,就是教懂别人。在这公众号,我会从 Python 最基础的教程写起࿰…

今天照了大肚照
今天陪老婆去照了大肚照,本来累了一周了好不容易盼到周六想睡个懒觉,结果比平时起床还早!要去照相!然而一想到俺家小小,我就很激动,为了俺家小小,我一定加倍努力,做一个好爸爸。 …

【Qt】QT_BEGIN_NAMESPACE 和 QT_END_NAMESPACE
在看QtCreator源码时,总遇到QT_BEGIN_NAMESPACE 和 QT_END_NAMESPACE两个宏,源码中对这两个宏的定义伪代码如下 #if !defined(QT_NAMESPACE) # define QT_BEGIN_NAMESPACE # define QT_END_NAMESPACE #else # define QT_BEGIN_NAMESPACE namespace QT_NAMESPACE {# define Q…

Java排序算法:冒泡排序
Java排序算法:冒泡排序//创建数组并赋值int[] data new int[] {11,10,55,78,100,111,45,56,79,90,345,1000};for(int i0;i < arr.length-1;i){for(int j 0; j < arr.length-i-1;j){if(arr[j] > arr[j1]){int temp arr[j];arr[j] arr[j1];arr[j1] temp;…

前腾讯AI Lab负责人张潼加入创新工场,任港科大创新工场联合实验室主任
参加 2019 Python开发者日,请扫码咨询 ↑↑↑整理 | 琥珀出品 | AI科技大本营(ID:rgznai100)不过三个月,前腾讯 AI 主任张潼已对外公布了他离职后的新动态。3 月 20 日,创新工场宣布,张潼博士已加盟创新工场…

ESX上ORACLE 10.2RAC(4.在REHAT4.7中安装ORACLE RAC)
四、 安装CRS软件 上传cluster软件到rac1,rac2的/home/oracle目录下 [rootrac1 ~]# cd /home/oracle [rootrac1 oracle]# ls 10201_clusterware_linux32.zip Desktop ocfs2 oracleasm [rootrac1 oracle]# unzip 10201_clusterware_linux32.zip [rootrac2 oracle]# unzip 10201_…

【Qt中文手册】QObject
Qt几乎所有的类都是从QObject直接或间接继承的,但是你真的了解QObject吗?下面先看看QObject在官方手册中的介绍。 一、QObject简介 1、信号和槽 QObject是所有Qt类的基类,是Qt对象模型的核心。该模型的核心功能是信号和槽的通信机制(有吐槽Qt信号和槽的,个人建议不要用…

整理下.net分布式系统架构的思路
最近看到有部分招聘信息,要求应聘者说一下分布式系统架构的思路。今天早晨正好有些时间,我也把我们实际在.net方面网站架构的演化路线整理一下,只是我自己的一些想法,欢迎大家批评指正。 首先说明的是.net下开源内容较少ÿ…

柔性生态布局未来,小鱼易连 2019“深耕视界逐梦小鱼”北京火爆招募
3 月 21 日,小鱼易连 “深耕视界逐梦小鱼”——2019 春季伙伴招募大会北京站在北京东方美爵酒店成功召开。 小鱼易连联合创始人兼 CEO 袁文辉以“深耕视界逐梦小鱼” 为主题,为到场的四百家合作伙伴和媒体完整展示了小鱼易连全面布局产业互联网…

perl XML创建XML文件
首先安装XML::Writer,XML::Parser等模块 1.执行/usr/bin/perl -MCPAN -e install "YAML" 安装YAML模块 2.进入CPAN模式,进行下载模块操作 $ sudo perl -MCPAN -e shell 3.在CPAN模式下进行安装,nolock_cpan> install XML::Writer XML::Pars…

开发自己的山寨Android注解框架
目录 开发自己的山寨Android注解框架开发自己的山寨Android注解框架 参考 Github黄油刀 Overview 在上一章我们学习了Java的注解(Annotation),但是我想大家可能感觉,虽然理解了也会学会,但是不知道干什么用,那么请继续忍受我这枯燥…

特斯拉起诉小鹏汽车员工窃取商业机密,何小鹏回应
参加 2019 Python开发者日,请扫码咨询 ↑↑↑整理 | 琥珀出品 | AI科技大本营(ID:rgznai100)3 月 21 日,外媒 TheVerge 报道称,特斯拉正针对多名前雇员和自动驾驶汽车公司 Zoox 提起诉讼,涉嫌盗用公司商业机…

【Qt】一个使用QEventLoop时,遇到的教训
1、问题描述 伪代码如下: QEventLoop eventLoop; QObject::connect(this, &Class::signal, [](){doSomething();eventLoop.exit(0); }); emit signal(); eventLoop.exec();在执行eventLoop.exec()时,造成永不退出。 2、原因分析 本打算在&#x…