热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

OpenTSDB时序数据库

就是以时间为标签存储数据;2数据存储优化如果我们只通过原始的Hbase接口去存时间序列;首先它做了数据存储的优化;则一天时间内sys.cpu.user这个监控指标就会产生17280

一、简介

OpenTSDB(Open time series data base),时间序列数据库。顾名思义,就是以时间为标签存储数据,它的特点是能够提供最高 毫秒级精度 的时间序列数据存储,能够长久保存原始数据并且不失精度。但是OpenTSDB这个db有误导性,他其实只是一层读写服务(基于HBase)

什么是时序数据?

股票的变化趋势、温度的变化趋势、系统某个指标的变化趋势……其实都是时序数据,就是每个时间点上纪录一条数据。 关于数据的存储,我们最熟悉的就是mysql了,但是想想看,每5分钟存储一个点,一天288个点,一年就10万+,这还是单个维度,往往在实际应用中维度会非常多,比如股票交易所,成千上万支股票,每天所有股票数据就可能超过百万条,如果还得支持历史数据查询,mysql是远远扛不住的,必然要考虑分布式存储,最好的选择就是Hbase了,事实上业内基本上也是这么做的。
    了解Hbase的人都知道,它可以通过加机器的水平扩展迅速增加读写能力,非常适合存储海量的数据,但是它并不是关系数据库,无法进行类似mysql那种select、join等操作。 取而代之的只有非常简单的Get和Scan两种数据查询方式。这里不讨论Hbase的相关细节,总之,你可以通过Get获取到hbase里的一行数据,通过Scan来查询其中RowKey在某个范围里的一批数据。如此简单的查询方式虽然让hbase变得简单易用, 但也限制了它的使用场景。针对时序数据,只有get和scan远远满足不了你的需求。
    这个时候OpenTSDB就应运而生。 首先它做了数据存储的优化,可以大幅度提升数据查询的效率和减少存储空间的使用。其次它基于hbase做了常用时序数据查询的API,比如数据的聚合、过滤等。另外它也针对数据热度倾斜做了优化。

二、OpenTSDB术语


  • metric: 指标,比如在系统监控中cpu的利用率、天气数据,温度,湿度等的变化。
  • timestamp: 时间戳(时间戳是指格林威治时间1970年01月01日00时00分00秒起至当下的总秒数)在线时间戳工具网站.
  • tag: 标签。 比如在cpu在某个机器上的数据,就可以把机器ip作为tag打进去。

  1. 在OpenTSDB里tag是个k-v,比如 ip=192.168.0.1 就可以做为一个tag。注意
  2.  OpenTSDB最多只能打8个tag。(每个标签由tagKey和tagValue组成,tagKey和tagValue均为字符串)

  • value: 我们要存的时序数据的值。(64位整数或者单精度浮点数)

举个例子,在监控场景中,我们可以这样定义一个监控指标:

指标名称代表这个监控指标是对用户态CPU的使用监控,引入了两个标签,分别标识该监控位于哪台机器的哪个核。

OpenTSDB支持的查询场景为:指定指标名称和时间范围,给定一个或多个标签名称和标签的值作为条件,查询出所有的数据。

以上面那个例子举例,我们可以查询:

a. sys.cpu.user (host&#61;,cpu&#61;)(1465920000 <&#61; timestamp <1465923600)&#xff1a;查询凌晨0点到1点之间&#xff0c;所有机器的所有CPU核上的用户态CPU消耗。

b. sys.cpu.user (host&#61;10.101.168.111,cpu&#61;*)(1465920000 <&#61; timestamp <1465923600)&#xff1a;查询凌晨0点到1点之间&#xff0c;某台机器的所有CPU核上的用户态CPU消耗。

c. sys.cpu.user (host&#61;10.101.168.111,cpu&#61;0)(1465920000 <&#61; timestamp <1465923600)&#xff1a;查询凌晨0点到1点之间&#xff0c;某台机器的第0个CPU核上的用户态CPU消耗。

2 数据存储优化
如果我们只通过原始的Hbase接口去存时间序列&#xff0c;我们可能会设计出这样的Rowkey。
  metric|timestamp|tagK1:tagV1|tagK2:tagV2…
  
  如上图是一个简单的表结构设计&#xff0c;rowkey采用metric name &#43; timestamp &#43; tags的组合&#xff0c;因为这几个元素才能唯一确定一个指标值。
  如果我们每秒存储一个数据点&#xff0c;每天就有86400个数据点&#xff0c;在hbase里就意味着86400行的数据&#xff0c;不仅浪费存储空间&#xff0c;而且还查起来慢&#xff0c;所以OpenTSDB做了数据压缩上的优化&#xff0c;多行一列转一行多列&#xff0c;一行多列转一行一列。数据开始写入时其实OpenTSDB还是一行一个数据点&#xff0c;如果用户开启了数据压缩的选项&#xff0c;OpenTSDB会在一个小时数据写完或者查询某个小时数据时对其做多行转一行的数据压缩&#xff0c;压缩后那些独立的点数据就会被删除以节省存储空间。

2.1 优化一&#xff1a;缩短row key
例&#xff08;接上文的例子&#xff09;&#xff1a;
 观察这张表内存储的数据&#xff0c;在rowkey的组成部分内&#xff0c;其实有很大一部分的重复数据&#xff0c;重复的指标名称&#xff0c;重复的标签。以上图为例&#xff0c;如果每秒采集一次监控指标&#xff0c;cpu为2核&#xff0c;host规模为100台&#xff0c;则一天时间内sys.cpu.user这个监控指标就会产生17280000行数据&#xff0c;而这些行中&#xff0c;监控指标名称均是重复的。如果能将这部分重复数据的长度尽可能的缩短&#xff0c;则能带来非常大的存储空间的节省。
 OpenTSDB采用的策略是&#xff0c;为每个metric、tag key和tag value都分配一个UID&#xff0c;UID为固定长度三个字节。
  
 上图为优化后的存储结构&#xff0c;可以看出&#xff0c;rowkey的长度大大的缩短了。rowkey的缩短&#xff0c;带来了很多好处&#xff1a;

a. 节省存储空间

b. 提高查询效率&#xff1a;减少key匹配查找的时间

c. 提高传输效率&#xff1a;不光节省了从文件系统读取的带宽&#xff0c;也节省了数据返回占用的带宽&#xff0c;提高了数据写入和读取的速度。

d. 缓解Java程序内存压力&#xff1a;Java程序&#xff0c;GC是老大难的问题&#xff0c;能节省内存的地方尽量节省。原先用String存储的metric name、tag key或tag value&#xff0c;现在均可以用3个字节的byte array替换&#xff0c;大大节省了内存占用。

2.2 优化二&#xff1a;减少Key-Value数
优化一是OpenTSDB做的最核心的一个优化&#xff0c;很直观的可以看到存储的数据量被大大的节省了。原理也很简单&#xff0c;将长的变短。但是是否还可以进一步优化呢&#xff1f;

在上面的存储模型章节中&#xff0c;我们了解到。HBase在底层存储结构中&#xff0c;每一列都会以Key-Value的形式存储&#xff0c;每一列都会包含一个rowkey。如果要进一步缩短存储量&#xff0c;那就得想办法减少Key-Value的个数。

OpenTSDB分了几个步骤来减少Key-Value的个数&#xff1a;

将多行合并为一行&#xff0c;多行单列变为单行多列。

将多列合并为一列&#xff0c;单行多列变为单行单列。

2.2.1 将多行合并为一行&#xff0c;多行单列变为单行多列。

 OpenTSDB将同属于一个时间周期内的具有相同TSUID&#xff08;相同的metric name&#xff0c;以及相同的tags&#xff09;的数据合并为一行存储。OpenTSDB内默认的时间周期是一个小时&#xff0c;也就是说同属于这一个小时的所有数据点&#xff0c;会合并到一行内存储&#xff0c;如图上所示。合并为一行后&#xff0c;该行的rowkey中的timestamp会指定为该小时的起始时间&#xff08;所属时间周期的base时间&#xff09;&#xff0c;而每一列的列名&#xff0c;则记录真实数据点的时间戳与该时间周期起始时间&#xff08;base&#xff09;的差值。
 
 这里列名采用差值而不是真实值也是一个有特殊考虑的设计&#xff0c;如存储模型章节所述&#xff0c;列名也是会存在于每个Key-Value中&#xff0c;占用一定的存储空间。如果是秒精度的时间戳&#xff0c;需要4个字节&#xff0c;如果是毫秒精度的时间戳&#xff0c;则需要8个字节。但是如果列名只存差值且时间周期为一个小时的话&#xff0c;则如果是秒精度&#xff0c;则差值取值范围是0-3600&#xff0c;只需要2个字节&#xff1b;如果是毫秒精度&#xff0c;则差值取值范围是0-360000&#xff0c;只需要4个字节&#xff1b;所以相比存真实时间戳&#xff0c;这个设计是能节省不少空间的。

2.2.2 单行多列合并为单行单列
多行合并为单行后&#xff0c;并不能真实的减少Key-Value个数&#xff0c;因为总的列数并没有减少。所以要达到真实的节省存储的目的&#xff0c;还需要将一行的列变少&#xff0c;才能真正的将Key-Value数变少。

OpenTSDB采取的做法是&#xff0c;会在后台定期的将一行的多列合并为一列&#xff0c;称之为『compaction』&#xff0c;合并完之后效果如下。

同一行中的所有列被合并为一列&#xff0c;如果是秒精度的数据&#xff0c;则一行中的3600列会合并为1列&#xff0c;Key-Value数从3600个降低到只有1个。

2.3 并发写优化
上面两个优化主要是OpenTSDB对存储的优化&#xff0c;存储量下降以及Key-Value个数下降后&#xff0c;除了直观的存储量上的缩减&#xff0c;对读和写的效率都是有一定提升的。

时间序列数据的写入&#xff0c;有一个不可规避的问题是写热点问题&#xff0c;当某一个metric下数据点很多时&#xff0c;则该metric很容易造成写入热点。OpenTSDB采取了和这篇文章中介绍的一样的方法&#xff0c;允许将metric预分桶&#xff0c;可通过『tsd.storage.salt.buckets』配置项来配置。

如上图所示&#xff0c;预分桶后的变化就是在rowkey前会拼上一个桶编号&#xff08;bucket index&#xff09;。预分桶后&#xff0c;可将某个热点metric的写压力分散到多个桶中&#xff0c;避免了写热点的产生。

2.4 总结
OpenTSDB作为一个应用广泛的时间序列数据库&#xff0c;在存储上做了大量的优化&#xff0c;优化的选择也是完全契合其底层依赖的HBase数据库的存储模型。表格存储拥有和HBase一样的存储模型&#xff0c;这部分优化经验可以直接借鉴使用到表格存储的应用场景中&#xff0c;值得我们好好学习。

3 数据写入与查询API


推荐阅读
  • RouterOS 5.16软路由安装图解教程
    本文介绍了如何安装RouterOS 5.16软路由系统,包括系统要求、安装步骤和登录方式。同时提供了详细的图解教程,方便读者进行操作。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 嵌入式处理器的架构与内核发展历程
    本文主要介绍了嵌入式处理器的架构与内核发展历程,包括不同架构的指令集的变化,以及内核的流水线和结构。通过对ARM架构的分析,可以更好地理解嵌入式处理器的架构与内核的关系。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • Java和JavaScript是什么关系?java跟javaScript都是编程语言,只是java跟javaScript没有什么太大关系,一个是脚本语言(前端语言),一个是面向对象 ... [详细]
  • 本文介绍了OkHttp3的基本使用和特性,包括支持HTTP/2、连接池、GZIP压缩、缓存等功能。同时还提到了OkHttp3的适用平台和源码阅读计划。文章还介绍了OkHttp3的请求/响应API的设计和使用方式,包括阻塞式的同步请求和带回调的异步请求。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • 本文讨论了在使用Git进行版本控制时,如何提供类似CVS中自动增加版本号的功能。作者介绍了Git中的其他版本表示方式,如git describe命令,并提供了使用这些表示方式来确定文件更新情况的示例。此外,文章还介绍了启用$Id:$功能的方法,并讨论了一些开发者在使用Git时的需求和使用场景。 ... [详细]
  • 基于分布式锁的防止重复请求解决方案
    一、前言关于重复请求,指的是我们服务端接收到很短的时间内的多个相同内容的重复请求。而这样的重复请求如果是幂等的(每次请求的结果都相同,如查 ... [详细]
  • [翻译]微服务设计模式5. 服务发现服务端服务发现
    服务之间需要互相调用,在单体架构中,服务之间的互相调用直接通过编程语言层面的方法调用就搞定了。在传统的分布式应用的部署中,服务地 ... [详细]
author-avatar
手机用户2502859667
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有