191

我正在创建一个系统,该系统使用 SNMP 以(可能)5 分钟的间隔轮询设备以获取不同指标的数据,例如 CPU 利用率、磁盘利用率、温度等。最终目标是以时间序列图的形式向系统用户提供可视化。

我过去曾研究过使用 RRDTool,但拒绝了它,因为无限期地存储捕获的数据对我的项目很重要,我希望更高级别和更灵活地访问捕获的数据。所以我的问题是:

在查询图形数据时的性能方面,关系数据库(例如 MySQL 或 PostgreSQL)或非关系数据库或 NoSQL 数据库(例如 MongoDB 或 Redis)更好。

关系型

给定一个关系数据库,我将使用一个data_instances表,其中将存储为所有设备测量的每个指标捕获的每个数据实例,其中包含以下字段:

领域:id fk_to_device fk_to_metric metric_value timestamp

当我想为特定设备上的特定指标绘制图表时,我必须查询这个单一的表,过滤掉其他设备,以及为此设备分析的其他指标:

SELECT metric_value, timestamp FROM data_instances
    WHERE fk_to_device=1 AND fk_to_metric=2

此表中的行数为:

d * m_d * f * t

其中d设备数量,是为所有设备记录的指标m_d的累积数量,是轮询数据的频率,是系统收集数据的总时间。ft

对于一年中每 5 分钟记录 3 台设备的 10 个指标的用户,我们将有不到500 万条记录。

索引

如果没有索引fk_to_device并且fk_to_metric扫描这个不断扩展的表会花费太多时间。因此,索引上述字段以及timestamp(用于创建具有本地化周期的图表)是一项要求。

非关系型 (NoSQL)

MongoDB 具有集合的概念,与表不同,这些表可以通过编程方式创建而无需设置。有了这些,我可以对每个设备的数据存储进行分区,甚至可以对每个设备记录的每个指标进行分区。

我没有使用 NoSQL 的经验,也不知道它们是否提供任何查询性能增强功能,例如索引,但是上一段建议在 NoSQL 下存储数据的结构中完成大部分传统的关系查询工作。

未定

具有正确索引的关系解决方案会在一年内减少到爬行吗?或者 NoSQL 方法的基于集合的结构(与我存储数据的心理模型相匹配)是否提供了明显的好处?

4

10 回答 10

157

绝对是关系型的。无限的灵活性和扩展性。

在概念和应用上进行了两次更正,然后是高度。

更正

  1. 它不是“过滤掉不需要的数据”;它只选择需要的数据。是的,当然,如果你有一个Index来支持WHERE子句中标识的列,它是非常快的,并且查询不依赖于表的大小(从160亿行的表中抓取1000行是瞬时的) .

  2. 你的桌子有一个严重的障碍。根据您的描述,实际的 PK 是(设备、公制、日期时间)。(请不要称它为 TimeStamp,这意味着其他东西,但这是一个小问题。)该的唯一性通过以下方式标识:

       (Device, Metric, DateTime)
    
    • Id列什么都不做,它完全是多余的。

      • 列永远不是键(在关系数据库中被禁止的Id重复行必须通过其他方式来防止)。
      • Id列需要一个额外的索引,这显然会阻碍 的速度INSERT/DELETE,并增加使用的磁盘空间。

      • 你可以摆脱它。请。

海拔

  1. 既然您已经消除了障碍,您可能还没有认识到它,但您的桌子处于第六范式。速度非常快,PK上只有一个Index。为了理解,请阅读什么是第六范式前进。

    • (我只有一个索引,而不是三个;在非 SQL 上,您可能需要三个索引)。

    • 我有完全相同的表(Id当然没有“钥匙”)。我有一个额外的专栏Server。我远程支持多个客户。

      (Server, Device, Metric, DateTime)

    该表可用于使用完全相同的 SQL 代码(是的,切换单元格)来透视数据(即Devices,在顶部和底部,或旋转)。Metrics我使用该表为客户建立了无数种图形和图表,以了解他们的服务器性能。

    • 监控统计数据模型
      (内联太大;某些浏览器无法加载内联;点击链接。也是过时的演示版本,出于显而易见的原因,我无法向您展示商业产品 DM。)

    • 它允许我在收到客户的原始监控统计文件后使用单个 SELECT 命令生成这样的图表,六次击键。注意混搭;操作系统和服务器在同一张图表上;各种枢轴。当然,统计矩阵和图表的数量没有限制。(经客户许可使用。)

    • 不熟悉关系数据库建模标准的读者可能会发现IDEF1X 表示法很有帮助。

还有一件事

最后但同样重要的是,SQL 是 IEC/ISO/ANSI 标准。免费软件实际上是非 SQL;如果他们不提供标准,则使用 SQL 一词是欺诈性的。他们可能提供“额外”,但缺乏基础知识。

于 2011-02-03T09:33:59.107 回答
21

发现上述答案非常有趣。尝试在此处添加更多注意事项。

1)数据老化

时间序列管理通常需要创建老化策略。一个典型的场景(例如监控服务器 CPU)需要存储:

  • 短时间(例如 24 小时)的 1 秒原始样本

  • 中期(例如 1 周)的5 分钟详细汇总样本

  • 超过1 小时的详细信息(例如长达 1 年)

尽管关系模型可以肯定地(我的公司为一些拥有数万个数据系列的大客户实施了大规模的集中式数据库)来适当地管理它,但新型数据存储增加了一些有趣的功能,有待探索,例如:

  • 自动数据清除(参见 Redis 的 EXPIRE 命令)

  • 多维聚合(例如 map-reduce 作业 a-la-Splunk)

2) 实时采集

更重要的是,一些非关系数据存储本质上是分布式的,并且允许更有效的实时(或接近实时)数据收集,这可能是 RDBMS 的问题,因为热点的创建(在插入时管理索引)一个表)。RDBMS 空间中的这个问题通常通过恢复到批量导入过程来解决(我们过去是这样管理的),而 no-sql 技术已经成功地实现了大规模的实时收集和聚合(例如,参见 Splunk,在之前的回复中提到) .

于 2011-03-20T13:18:32.623 回答
7

您的表在单个表中有数据。所以关系与非关系不是问题。基本上你需要读取大量的顺序数据。现在,如果您有足够的 RAM 来存储价值数年的数据,那么没有什么比使用 Redis/MongoDB 等更重要了。

大多数 NoSQL 数据库会将您的数据以压缩形式存储在磁盘上的同一位置,以避免多个磁盘访问。

NoSQL 与在设备 ID 和指标 ID 上创建索引的操作相同,但以自己的方式。使用数据库,即使您这样做,索引和数据也可能位于不同的位置,并且会有很多磁盘 IO。

Splunk 等工具使用 NoSQL 后端存储时间序列数据,然后使用 map reduce 来创建聚合(这可能是您以后想要的)。因此,在我看来,使用 NoSQL 是一种选择,因为人们已经在类似的用例中尝试过它。但是一百万行是否会使数据库爬行(也许不会,具有不错的硬件和适当的配置)。

于 2011-01-27T12:53:18.163 回答
4

创建一个文件,将其命名为 1_2.data。奇怪的想法?你得到什么:

  • 您最多可以节省 50% 的空间,因为您不需要为每个数据点重复 fk_to_device 和 fk_to_metric 值。
  • 您节省了更多空间,因为您不需要任何索引。
  • 通过附加数据将 (timestamp,metric_value) 对保存到文件中,这样您就可以免费获得按时间戳排序的订单。(假设您的来源不会为设备发送乱序数据)

=> 按时间戳查询运行得非常快,因为您可以使用二进制搜索在文件中找到要读取的正确位置。

如果您喜欢它甚至更优化,请开始考虑像这样拆分文件;

  • 1_2_january2014.data
  • 1_2_february2014.data
  • 1_2_march2014.data

或使用来自http://kx.com的 kdb+,因为它们会为您完成所有这些工作:) 面向列的内容可能会对您有所帮助。

有一个基于云的面向列的解决方案弹出,所以你可能想看看:http ://timeseries.guru

于 2014-09-26T12:59:40.050 回答
3

如果您正在查看 GPL 包,RRDTool是一个不错的选择。它是存储、提取和绘制时间序列数据的好工具。您的用例看起来与时间序列数据完全一样。

于 2012-07-06T06:05:33.530 回答
3

您应该查看时间序列数据库。它是为此目的而创建的。

时间序列数据库 (TSDB) 是一种针对处理时间序列数据、按时间(日期时间或日期时间范围)索引的数字数组进行优化的软件系统。

时间序列数据库InfluxDB的流行示例

于 2017-07-14T19:14:00.063 回答
2

这是我们必须在 ApiAxle 解决的问题。我们写了一篇关于我们如何使用 Redis 做到这一点的博客文章。它没有出现很长时间,但它被证明是有效的。

我还在另一个非常好的项目中使用了RRDTool

于 2013-04-05T11:32:05.417 回答
2

我认为这类问题的答案应该主要围绕您的数据库利用存储的方式。一些数据库服务器使用 RAM 和磁盘,一些仅使用 RAM(可选磁盘以实现持久性)等。最常见的 SQL 数据库解决方案是使用内存+磁盘存储,并以基于行的布局写入数据(每个插入的原始数据都写入相同的物理位置)。对于时间序列存储,在大多数情况下,工作负载类似于:大量插入的间隔相对较短,而读取是基于列的(在大多数情况下,您希望从特定列中读取一系列数据,代表一个指标)

我发现列式数据库(谷歌它,你会发现 MonetDB、InfoBright、parAccel 等)在时间序列方面做得非常好。

至于你的问题,我个人认为这有点无效(因为所有讨论都使用错误术语 NoSQL - IMO):你可以使用一方面可以谈论 SQL 的数据库服务器,因为每个人都知道 SQL,所以你的生活非常轻松多年来,这种语言在数据查询方面已经一次又一次地完善;但仍以面向列的方式利用 RAM、CPU 缓存和磁盘,使您的解决方案最适合时间序列

于 2013-08-16T19:46:13.260 回答
2

500 万行对于今天的洪流数据来说不算什么。预计数据将在短短几个月内达到 TB 或 PB。在这一点上,RDBMS 不能扩展到任务,我们需要 NoSql 数据库的线性可扩展性。用于存储数据的列式分区将实现性能,添加更多列和更少行的概念以提高性能。利用在 HBASE 或 MapR_DB 等之上完成的 Open TSDB 工作。

于 2015-05-30T13:17:14.093 回答
1

我经常遇到类似的需求,最近开始使用 Zabbix 来收集和存储此类数据。Zabbix 有自己的绘图功能,但很容易从 Zabbix 的数据库中提取数据并根据需要进行处理。如果您还没有检查过 Zabbix,您可能会发现值得花时间这样做。

于 2011-01-27T11:11:58.520 回答