• 利用可排序Key-Value DB构建时间序列数据库(简论)


    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/ShiJiaqi。

    http://www.cnblogs.com/shijiaqi1066/p/5855064.html 

    本文使用LevelDB,HBase这类列式存KV储数据来构建时间序列数据库。

    时间序列数据的特征

    经典物理世界,若需要进行测量,则首先需要标注出来。所以首先物体需要有一个ObjectName。

    物体有一些静态属性。静态属性不随时间发送变化。时间序列数据一般不关注静态属性。

    还有一些动态属性。动态属性的值会随时间发送变化,一般的动态属性被称为指标。指标的名称即metricName。

    基础表

    Meta

    物体与指标都具有名称。而名称字符串应该与一个无符号整数映射起来。即存储ObjectName与ObjectId的对应关系。

    Data

    使用SSTable存储KV型数据。支持Scan查询。存储Key与Value的关系。

    时间序列数据库的查询需求

    在不考虑聚合问题的前提下,一般的时间序列数据的查询有以下需求:

    查询一段时间([timestamp0,timestam1])内某个object的所有metric的值。   ==> 抽象成函数即  query( objectId , timestamp0 , timestamp1 )

    查询一段时间([timestamp0,timestam1])内某个object的某个metric的值。  ==> 抽象成函数即  query( objectId , metricId  , timestamp0 , timestamp1 ) 

    查询一段时间内所有object的某个metric的值。 == > 抽象成函数即  query( metricId , timestamp0 , timestamp1 ) 

    查询一段时间内所有object的所有metric的值。 == > 抽象成函数即  query( timestamp0 , timestamp1 ) 

    一般的 query( objectId , metricId  , timestamp0 , timestamp1 ) 这种查询更为常见。

    Key的构造

    方法1:

    timestampobjectIdmetricId

    数据按时间顺序排序。是一种比较合理的构造方法,适合object较少的情况。

     

    方法2:

    timestamp | metricId | objectId

    与方法1的应用场景一致。适合object较少的情况。且适合指定metricId的查询。

     

    方法3:

    objectIdtimestampmetricId

    可以方便的查询,查询一段时间([timestamp0,timestam1])内某个object的所有指标值。即:query( objectId , timestamp0 , timestam1 )

    但对一段时间([timestamp0,timestam1])内某个object的某个metric值,性能会稍显不足。这是因为在查询过程中需要过滤掉非指定metricId的指标。

    比如一个object有30个metric,当前只需要查询object的metric1。则需要跳过{metric2 , metric3 , ...... , metric30 }的值。效率明显降低了。

    方法4:

    objectIdmetricIdtimestamp

    可以方便查询一段时间([timestamp0,timestam1])内某个object的某个metric值。

    但是如果需要查询一段时间([timestamp0,timestam1])内某个object的所有指标值,就会有所困难。

     

     

    方法5:

    改进方法4:在Meta中记录每个objectId与metricId的映射关系。即需要增加一张Mapping表。

    查询一段时间([timestamp0,timestam1])内某个object的所有指标值,需要先从Mapping表中查询objectId具有的metricIds集合:

    objectId  ==> {metric1,metric2,metric3,metric4,...metricN}

     

    然后按照对每一个metricId进行查询:

    query( objectId , metric1  , [timestamp0,timestam1] )

    query( objectId , metric2  , [timestamp0,timestam1] )

    query( objectId , metric3  , [timestamp0,timestam1] )

     ......

    query( objectId , metricN  , [timestamp0,timestam1] )

    查询后,把各个merge起来。

     

     

    数值存储

    数据存储于磁盘上都是以字节数组存储的。当读出来时需要知道存储时的数据格式。所以,需要把存储时的值格式记录下来。

    静态数值类型

    存储前,定义存储格式,并记录下来。存储时按照定义的存储格式进行序列化。类似于MySQL的使用方式。

     

    动态数值类型

    在数值序列化成byte[]后,用1个byte标记数值类型。并将整个byte添加到byte[]之前。合一起后存储下来。

    即: typeByte  | valueBytes

    读取数值时,按照第一个typeByte的值来解析后面的byte[]。

    动态数值类型更加灵活,但每一条数据都需要多存储1个byte的额外信息。对于静态数值类型,会造成存储空间的浪费。

     

     

    设计一个完整的时间序列数据库

    元信息层

    ObjectMeta表

    objectName-objectId

    MetricMeta表

    metricName-metricId

    ObjectMetricMeta表

    objectId-metricId

    静态层存储

    业务层存储(不存在于时间序列数据库中)

    staitcData

    objectId-metricId-value

      

    动态属性值存储

    objectId|metricId|timestamp <--> (valueType)  value 

     

     

     

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/ShiJiaqi。

    http://www.cnblogs.com/shijiaqi1066/p/5855064.html 

     

     

  • 相关阅读:
    docker容器的基本操作
    python3 Softmax函数
    变量命名 函数命名 方法 Naming cheatsheet
    [操作系统]LINUX进程状态说明
    Pytorch Linear ()简单推导
    [ubuntu18.04 python3.6] 清华源 CondaHTTPError: HTTP 000 CONNECTION
    /proc/meminfo 解释
    神经网络 CNN 名词解释
    C++ 运行时多态
    Rust 与 Windows 的字符串编码问题
  • 原文地址:https://www.cnblogs.com/shijiaqi1066/p/5855064.html
Copyright © 2020-2023  润新知