从传感器阵列存储大量数据


14

我受命实施一个解决方案(应用程序和数据库),以存储来自巨大传感器阵列的数据样本。该阵列目前由大约20,000个传感器组成,但是很快就会增长到多达100,000个传感器。每个传感器每10秒发送一次数据样本,每个样本的大小为28个字节。

这样求和会导致:

  • 每个传感器每天8640个样本
  • 每个传感器每天242kB的数据
  • 每天8.64亿个样本

现在,我一直在想最好的方法是存储/检索数据?在指定了软件之后,我“加入”了这个项目,因此需要使用SQL Server在Windows平台上实现它。

我目前的解决方案是创建一个具有两个表的数据库来存储数据样本。第一个用作第二个的索引,第二个以每个传感器每天的基础将整理后的样本存储在二进制字段中:

Table 1:

  RecordID - BigInt - Identity
  SensorID - BigInt - Primary Key
  Date - DateTime - Primary Key (yyyy-mm-dd)

Table 2:

  RecordID - BigInt - Primary Key (from an insert into Table 1)
  Data - Binary 

基本上,我会将所有传感器的样本写入临时文件(每个传感器1个)。每天结束时,我将在表1中创建一个条目,使用生成的RecordID并将文件转储到表2的“数据”字段中。

这样,我最终每天只向该表添加100,000个条目,而不是8.64亿个条目。数据应该在LAN或高速WAN上可用,因此可以全天检索传感器数据。

尽管必须存储所有数据,但大多数数据可能永远不会被读取。因此,在表上读取的数量将不会比写入的数量多得多。

我知道我可以通过仅存储数据文件的路径来使用文件系统来实现某些功能,但是我读到SQL Server的性能优于NTFS,而您的二进制字段则少了256kB。(在256kB和1MB之间存在一个灰色区域,而对于二进制大小> 1 MB,NTFS远远优于SQL Server)。

我还略微谨慎地将来自100,000个传感器的数据存储到自己的文件中,而不会在文件系统中引起问题,原因是文件夹中包含大量文件,或者每个文件夹中都有一些文件的复杂树结构,而没有甚至考虑到文件碎片。

  1. 有人可以向我提供有关上述内容的一些实用建议/意见吗?

  2. 我会陷入明显的陷阱吗?

  3. 样本数据确实压缩得很好。一个242 kB的文件压缩到大约85 kB。但是,我可以在数据库级别实施某种类型的压缩,以便自动压缩示例数据(列)吗?

  4. 对于该项目,SQL Server是否显然是错误的选择?

  5. 我对这两个表的设计是明智的,还是可以将它组合成一个仍会像两个表一样“高效”的表呢?


5
SQL Server确实支持诸如此类的行级和表级压缩。
JNK

2
由于每天只有1个条目/传感器,因此您是否需要表1?
GalacticJello 2012年

2
一旦这些数据存储在数据库中,您打算如何处理它们?我无法想象能够以二进制格式聚合传感器数据,至少在这些级别上不容易或快速。
datagod 2012年

1
100,000个传感器X每秒10个样本X每个样本28字节x每天24小时=每天2.2TB。可放入两个表中的很多东西。
datagod 2012年

2
@AlexKuznetsov:我本人想知道SQL Server的选择,但是他们是Microsoft的黄金合作伙伴,所以我想这是主要原因。
奥利弗(Oliver)

Answers:


12

是的,您将很快遇到一个很大的陷阱,那就是表的大小和维护。您说自己想每天将数据放入一个临时表中,然后再将其移到永久表中,这在某种程度上是对的,但很快就会遇到这种方案的麻烦。

例如,假设您要在两年后“滚存”最旧月份的数据。在您的设计中,您将必须针对您的大表发出DELETE语句。这可能会有些慢,具体取决于您拥有的索引数。而且,这将导致索引碎片,并且解决该问题的唯一方法是在此非常大的表上重建或重新组织索引,这也将导致性能问题。大型单表类型设计还有很多其他问题。例如,对于一个大的单表,您无法执行基于FILEGROUP的备份,这意味着,如果您要对数据库进行完整备份,则备份将非常庞大,并且需要很长时间才能完成。

有什么解决办法? 表分区。尽可能多地深入了解此内容。基本上,分区允许您将数据拆分到“表中的表”上-每个分区共享相同的架构,并且可以通过表对象进行访问,但是可以对索引进行不同的维护。分区基本上是表,由一些有用的键分割而成。您的情况可能是日期。可以像删除表一样快(和删除表一样快),这意味着如果按日期对大数据表进行分区,则可以立即删除旧分区,而不会对其他任何分区上的索引产生不利影响。您可以将分区放置在不同的文件组上,这意味着可以将较旧的分区转存,或者如果不常用,则可以转存到便宜的商品存储中。最后但并非最不重要的一点,在SQL 2012中,在较旧的只读分区上,而在要插入所有传感器数据的活动分区上具有不同的,更面向插入的索引方案。

希望这可以帮助。关于分区和分区方案,您需要进行大量研究,但是希望现在您知道了要寻找的方向。

PS:哦,我忘记了您列出的问题清单...答案1、2和5。请参见上文。答案3:在SQL Server中,您可以在每个分区的基础上进行压缩,因此可以使用PAGE压缩主动地压缩较旧的分区。但是我相信,如果这样做,将不会压缩行外大型数据类型-再次,您可能希望通过标准化传感器值来缓解此问题。答案4:绝对不是,但是,如果您要做的只是每天存储静态数据,并且从不进行其他任何搜索,那么压缩平面文件可能是一种更容易使用的方法。

PPS:哦,还有一件事。您不需要您的两表解决方案即可完成所有工作。大型二进制传感器数据应为VARBINARY(MAX)类型,因为其值可以“ 在行外 ” 存储但仍是单个表中的一列(请参见sp_tableoption文档)。不过,您可能要考虑从表中的二进制数据中标准化某些传感器数据,因为如果您不按时间检索传感器数据块,那么数据库将无济于事。


很棒的信息,谢谢。在这种情况下,我不确定您对“规范化”的含义。我假设尽管您的意思是我应该在数据块中提取一些更有用的字段,并将其存储在自己的列中。如果是这样,我最初不想这样做的原因是,这意味着我每天将要完成8.64亿行。整理所有内容并将其存储在一个块中意味着每天仅100,000行。或者,还有更好的方法 ?
奥利弗(Oliver)

1
如果您使用的是数据库,那么是的,这正是我的意思。如果您拥有合适的硬件,索引方案和分区方案以使其正常运行,则每天可以有效处理8.64亿行。这完全取决于您的实际需求,以及为什么要存储所有这些数据。如果仅出于存档目的,二进制列就可以了。如果您想使用SQL Server从中获取业务价值,那就完全不同了。
Dave Markle 2012年

0

考虑Hadoop解决方案。每天2 Tb会迅速增加。还应考虑仅记录增量记录(即初始值),然后仅在发生更改时记录。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.