我正在创建一个系统,使用SNMP以(可能)5分钟的间隔轮询设备以获取有关各种指标的数据,例如CPU利用率,磁盘利用率,温度等。最终目标是以时间序列图的形式为系统用户提供可视化。
我过去曾看过使用RRDTool,但拒绝了它,因为无限期地存储捕获的数据对我的项目很重要,我希望更高级别和更灵活地访问捕获的数据。所以我的问题是:
什么是更好的关系数据库(如MySQL或PostgreSQL)或非关系数据库或NoSQL数据库(如MongoDB或Redis)在查询图形数据时的性能。 < / p>
给定关系数据库,我会使用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
是为所有设备记录的累计指标数,{{1} }是轮询数据的频率,f
是系统收集数据的总时间时间。
对于一年中每5分钟记录3个设备的10个指标的用户,我们的记录就在 500万之下。
如果没有t
上的索引和fk_to_device
扫描这个不断扩展的表格会花费太多时间。因此,索引上述字段以及fk_to_metric
(用于创建具有本地化期间的图表)是必需的。
MongoDB具有集合的概念,与表格不同,这些可以通过编程方式创建而无需设置。有了这些,我可以为每个设备划分数据存储,甚至为每个设备记录每个指标。
我没有使用NoSQL的经验,也不知道它们是否提供任何查询性能增强功能,例如索引,但前一段建议在数据存储在NoSQL下的结构中进行大部分传统的关系查询工作。
具有正确索引的关系解决方案是否会在一年内减少爬行?或者NoSQL方法的基于集合的结构(与我存储的数据的心智模型相匹配)是否提供了明显的好处?
答案 0 :(得分:147)
绝对关系。无限的灵活性和扩展。
在概念和应用方面进行两次更正,然后进行提升。
不是“过滤掉不需要的数据”; 仅选择所需数据。是的,当然,如果你有一个索引来支持WHERE子句中标识的列,它非常快,并且查询不依赖于表的大小(从160亿行表中抓取1,000行是瞬时的)
你的桌子有一个严重的障碍。根据您的描述,实际的PK是(Device,Metric,DateTime)。 (请不要将其称为TimeStamp,这意味着其他问题,但这是一个小问题。)行的唯一性由以下标识:
(Device, Metric, DateTime)
Id
列无效,完全冗余。
Id
列永远不是密钥(必须通过其他方式阻止在关系数据库中禁止的重复行)。 Id
列需要一个额外的索引,这显然会阻碍INSERT/DELETE
的速度,并会增加使用的磁盘空间。
你可以摆脱它。请。
既然你已经删除了障碍,你可能没有认出来,但你的桌子是第六范式。速度非常快,只有一个PK指数。要理解,请从什么是第六范式?标题开始阅读this answer。
(我只有一个索引,而不是三个;在非SQL上你可能需要三个索引)。
我有完全相同的表(当然没有Id
“键”)。我还有一个专栏Server
。我远程支持多个客户。
(Server, Device, Metric, DateTime)
该表可用于使用完全相同的SQL代码(是的,切换单元格)来透过数据(即Devices
在顶部和Metrics
下方或旋转)进行透视。我使用该表为客户建立无限种类的图形和图表,以提高其服务器性能。
Monitor Statistics Data Model。
(内联太大;有些浏览器无法加载内联;点击链接。这也是过时的演示版本,由于显而易见的原因,我无法向您展示商业产品DM。)
它允许我使用单个SELECT命令从客户收到原始监控统计文件后生成Charts Like This六次击键。注意混合搭配;操作系统和服务器在同一图表上;各种各样的Pivots。当然,统计矩阵的数量没有限制,因此图表也没有限制。 (与客户的许可一起使用。)
不熟悉关系型数据库建模标准的读者可能会发现IDEF1X Notation很有帮助。
还有一件事
最后但并非最不重要的是,SQL是IEC / ISO / ANSI标准。免费软件实际上是非SQL的;如果他们不提供标准,则使用术语SQL是欺诈性的。他们可能会提供“额外内容”,但他们缺乏基础知识。
答案 1 :(得分:19)
发现以上答案非常有趣。 试着在这里添加一些注意事项。
1)数据老化
时间序列管理通常需要创建老化策略。典型的场景(例如监视服务器CPU)需要存储:
1秒原始样本短期(例如24小时)
5分钟详细汇总样本中期(例如1周)
1小时详细信息(例如最多1年)
虽然关系模型可以肯定(我的公司为一些拥有数万个数据系列的大客户实施了大量的集中式数据库)来适当地管理它,但新一代数据存储增加了有趣的功能,有待探索: / p>
自动数据清除(请参阅Redis的EXPIRE命令)
多维聚合(例如map-reduce job a-la-Splunk)
2)实时收藏
更重要的是,一些非关系数据存储本质上是分布式的,并且允许更高效的实时(或接近实时)数据收集,这可能是RDBMS的问题,因为热点的创建(管理索引)插入单个表时)。 RDBMS空间中的这个问题通常被解决,恢复到批量导入过程(我们过去以这种方式管理),而no-sql技术已成功进行大规模实时收集和聚合(例如,参见Splunk,在之前的回复中提到过)
答案 2 :(得分:7)
您的表在单个表中有数据。所以关系与非关系不是问题。基本上你需要阅读大量的顺序数据。现在,如果你有足够的RAM存储一年的数据,那么就像使用Redis / MongoDB等一样。
大多数NoSQL数据库会将您的数据存储在磁盘上的相同位置并以压缩形式存储,以避免多个磁盘访问。
NoSQL与在设备ID和度量标识上创建索引完全相同,但是以自己的方式。使用数据库即使你这样做,索引和数据可能在不同的地方,并且会有很多磁盘IO。
像Splunk这样的工具正在使用NoSQL后端来存储时间序列数据,然后使用map reduce来创建聚合(这可能是您以后想要的)。所以在我看来使用NoSQL是一个选项,因为人们已经尝试过类似的用例。但是,一百万行会使数据库爬行(可能没有,具有合适的硬件和正确的配置)。
答案 3 :(得分:4)
创建一个文件,将其命名为1_2.data。想法?你得到了什么:
=&GT;按时间戳查询的速度非常快,因为您可以使用二进制搜索在文件中找到正确的位置来读取。
如果你喜欢它甚至更优化,开始考虑分割你的文件;
或者使用来自http://kx.com的kdb +,因为他们会为你做这一切:)以列为导向可以帮助你。
有一个基于云的面向列的解决方案,因此您可能需要查看:http://timeseries.guru
答案 4 :(得分:3)
如果您正在查看GPL包,RRDTool是一个很好的选择。 它是存储,提取和绘制时间序列数据的好工具。 您的用例看起来与时间序列数据完全相同。
答案 5 :(得分:2)
这是我们在ApiAxle必须解决的问题。关于我们如何使用Redis进行操作,我们wrote up a blog post。它已经很久没出现了,但它证明是有效的。
我还将RRDTool用于另一个非常棒的项目。
答案 6 :(得分:2)
我认为这类问题的答案主要应该是关于数据库利用存储的方式。 有些数据库服务器使用RAM和磁盘,有些只使用RAM(可选择磁盘用于持久性)等。 最常见的SQL数据库解决方案使用内存+磁盘存储,并将数据写入基于行的布局(每个插入的原始数据都写在同一物理位置)。 对于时间序列存储,在大多数情况下,工作负载类似于:大量插入的相对较低的间隔,而读取是基于列的(在大多数情况下,您希望从特定列读取一系列数据,表示度量)< / p>
我发现Columnar数据库(google it,你会发现MonetDB,InfoBright,parAccel等)在时间序列方面做得非常好。
至于你的问题,我个人认为这个问题有些无效(因为所有使用故障术语NoSQL-IMO的讨论): 您可以使用一方面可以与SQL交谈的数据库服务器,让您的生活变得轻松,因为每个人都知道SQL多年,并且这种语言已经一次又一次地完善了数据查询;但仍以面向柱状的方式利用RAM,CPU缓存和磁盘,使您的解决方案最适合时间序列
答案 7 :(得分:2)
对于今天的滔滔不绝的数据而言,数百万行并不算什么。预计数据将在几个月内出现在TB或PB中。此时,RDBMS无法扩展到任务,我们需要NoSql数据库的线性可伸缩性。用于存储数据的柱状分区将实现性能,添加更多列和更少行的概念以提高性能。利用在HBASE或MapR_DB等基础上完成的Open TSDB工作。
答案 8 :(得分:1)
我经常面临类似的要求,并且最近开始使用Zabbix收集和存储此类数据。 Zabbix有自己的图形功能,但是很容易从Zabbix的数据库中提取数据并随意处理它。如果您尚未检查Zabbix,您可能会觉得值得花时间这样做。
答案 9 :(得分:0)
你应该研究Time series database。它是为此目的而创建的。
时间序列数据库(TSDB)是一个优化的软件系统,用于处理时间序列数据,按时间(日期时间或日期时间范围)索引的数字数组。
时间序列数据库InfluxDB
的热门示例