使用Ad-Hoc查询对DB选择和建模时间序列数据

时间:2014-12-17 15:13:02

标签: time-series data-modeling rdbms influxdb

我必须开发一个用于跟踪/监控蜂窝网络性能的系统。

域包括一组分层元素,每个元素都有一组相关的计数器,这些计数器定期报告(每15分钟一次)。系统应收集这些计数器值(可用作大型XML文件)并定期在两个维度上聚合: 时间 (从15到小时和从小时到小时)和< strong> 层次结构 (较低级别到较高级别的元素)。聚合通常是简单的SUM,但有时需要平均/最小/最大等。当然,对于元素维度聚合,它需要按层次结构进行分组(将所有子项分组到一个父记录)。用户应该能够定义和查看KPI(关键绩效指标) - 也就是说,对各种计数器进行一些计算。对于多个元素(为每个元素生成数据系列)或作为多个元素的聚合(仅产生一个聚合数据的数据系列),可能只需要一个元素的KPI。

系统将有大约10-15个用户,每小时可能有20-30个查询。查询响应时间应该是几秒钟(对于非常大的报告,包括许多元素和长时间段,最多10-15)。

在高级别,这是流程:

  1. 解析和输入计数器数据 - 有一组XML文件,其中包含元素的计数器数据的定期更新。所有文件的大小约为4GB / 15分钟(大约400GB /天)。
  2. 每小时汇总 - 每小时一次所有收集的计数器,应汇总所有元素 - 每4个与元素相关的记录汇总到一个应存储的小时记录中。
  3. 每日汇总 - 每天一次,所有元素的2个所有收集的计数器应该汇总 - 每24个与元素相关的记录汇总到一个日常记录中。
  4. 元素聚合 - 对于每个时间维度聚合,可能需要沿元素的层次结构聚合 - 子元素的所有记录都聚合到父元素的一个记录中。
  5. KPI定义 - 用户应该有一些方法来定义KPI。 KPI是基于相同粒度(时间维度)的计数器的计算定义。计算可以(并且将)涉及多个元素级别(例如p1.counter1 + sum(c1.counter1),其中p1是c1中一个或多个记录的父级)。
  6. 用户交互 - 用户可以选择一个或多个元素和一个或多个计数器/ KPI,要使用的粒度,要查看的时间段以及是否要聚合所选数据。

    • 如果是聚合,则结果是一个数据系列,其中包含&#34;已添加&#34;每个相关时间点的所有选定元素的值。在&#34; SQL&#34;:

      SELECT p1.time SUM(p1.counter1)/ SUM(p1.counter2)* SUM(c1.counter1) 从p1_hour p1,c1_hour c1 在哪里p1.time&gt; :minTime和p1.time&lt; :maxTime AND p1.id in:id_list和join GROUP BY p1.time

    • 如果无聚合需要保留p1中的标识符并为每个所选元素设置数据系列

      SELECT p1.time,p1.id,SUM(p1.counter1)/ SUM(p1.counter2)* SUM(c1.counter1) 从p1_hour p1,c1_hour c1 在哪里p1.time&gt; :minTime和p1.time&lt; :maxTime AND p1.id in:id_list and join

  7. 系统必须保存10,100和1000天的数据,持续15分钟,小时和每日记录。考虑尺寸估计,考虑4个字节的仅整数列用于存储,400个计数器用于P类型的元素,50个用于C类元素,400个用于GP类型:

    Sizes Estimate

    随着它的加起来,我假设基于DDL(实际上,DB优化存储)到3.5-4 TB的数据加上大约20-30%的额外索引所需。对于孩子&#34;表&#34;,每个表可以获得接近20亿条记录。

    值得注意的是,随着网络的发展,我偶尔会添加计数器(可能每2-3个月一次)。

    我曾经使用Oracle实现了一个非常相似的系统(虽然可能用较少的数据)。这一次,我可能不会使用商业数据库,必须恢复到开源解决方案。随着无SQL和专用时间序列数据库的日益普及,也许关系不是要走的路?

    你会如何处理这种发展?可以使用哪些产品?

    经过几天的研究,我想出了以下内容

    • 使用MySQL / PostGres
    • InfluxDB(或类似产品)
    • Cassandra + Spark
    • 其他?

    如何使用每种解决方案以及每种方法的优点/缺点是什么?如果可以,请详细说明或建议整体(硬件)架构以支持此类开发。

    欢迎提出意见和建议 - 最好是那些有类似项目经验的人。

2 个答案:

答案 0 :(得分:0)

使用开源RDBMS:

使用MySQL或Postgres

表结构将是(虚构的SQL):

CREATE TABLE LEVEL_GRANULARITY (
    TIMESTAMP DATE,
    PARENT_ID INT,
    ELEMENT_ID INT,
    COUNTER_1 INT
    ...
    COUNTER_N INT
    PRIMARY_KEY (TIMESTAMP, PARENT_ID, ELEMENT_ID)
)

例如,我们将有P1_HOUR,GP_HOUR,P_DAY,GP_DAY等。

这些表可以按日期分区,以增强查询时间并简化数据管理(可以删除整个分区)。

为了便于快速加载,请使用随DB提供的加载器 - 这些加载器通常速度更快,并且可以批量插入数据。

使用`SELECT ... INTO ...'查询可以很容易地进行聚合(因为聚合的范围有限,我认为这不会有问题。)

查询很简单,因为内置了聚合,分组和连接。考虑到表的大小,我不确定查询性能。

由于它是写密集型的,我不认为群集可以在这里提供帮助。

优点:

  • 简单配置(假设没有集群等)。
  • SQL查询功能 - 灵活

缺点:

  • 查询效果 - 会有效吗?
  • 管理费用
  • 刚性架构
  • 缩放?

答案 1 :(得分:0)

使用InfluxDB(或类似的东西):

我没有使用过这个数据库,而是通过玩它来写一些

该模型将为每个级别和粒度的每个元素创建一个时间序列。

数据系列名称将包含元素的标识符和粒度。

例如P.P_ElementID.G.15MINP.P_ElementID.C.C1_ELEMENT_ID.G.60MIN

数据系列将包含与该级别相关的所有计数器。

在插入新数据点之前,输入必须解析XML并构建数据系列名称。

InfluxDB有一种类似SQL的查询语言。并允许以类似SQL的方式指定计算。它还支持分组。通过使用正则表达式,例如,可以按元素分组。 SELECT counter1/counter2 FROM /^P\.P_ElementID\.C1\..*G\.15MIN/获取ElementID的所有孩子。

有一种按时间分组的概念,一般来说就是这种数据。

优点:

  • 应该快点
  • 支持查询等与SQL
  • 非常相似
  • 支持按日期删除(但必须在每个系列中执行...)
  • 灵活架构

缺点:  *目前,似乎不容易支持集群(  *集群=更多维护  *它可以支持数百万个数据系列(并且仍能快速工作)  *不太常见,记录较少(目前)