在我看来,这个问题将没有准确的答案,因为需要过于复杂的分析并深入研究我们系统的细节。
我们分发了传感器网。信息收集在一个数据库中并进一步处理。
当前的数据库设计是每月分区一个巨大的表。我们尝试将其保持在10亿(通常为6到8亿条记录),因此填充率为每天20-50万条记录。
数据库服务器目前是MS SQL 2008 R2,但我们从2005年开始,在项目开发期间进行升级。
表本身包含SensorId,MessageTypeId,ReceiveDate和Data字段。目前的解决方案是将传感器数据保存在数据字段(二进制,16字节固定长度)中,并部分解码其类型并将其存储在messageTypeId中。
我们通过传感器发送不同类型的消息类型(当前约为200),并且可以根据需要进一步增加。
主要处理在应用服务器上完成,该服务器按需获取记录(按类型,sensorId和日期范围),解码并执行所需的处理。目前的速度足以满足这样的数据量。
我们要求将系统的容量提高10到20倍,我们担心的是我们当前的解决方案能够做到这一点。
我们还有两个想要“优化”我想要讨论的结构的想法。
1传感器的数据可以分为多种类型,为了简单起见,我将使用2个主要数据:(值)级别数据(具有值范围的模拟数据),状态数据(固定数值)
因此,我们可以使用以下规则将我们的表重新设计为一堆小表:
对于每个固定类型值(状态类型)使用SensorId和ReceiveDate创建自己的表(因此我们避免存储类型和二进制blob),所有依赖(扩展)状态将存储在自己的表中类似的外键,因此,如果我们State
的值为A
和B
,并且依赖(或其他)状态为1
和2
,那么我们会以表格{{1}结尾},StateA_1
,StateA_2
,StateB_1
。因此,表名由它代表的固定状态组成。
对于我们创建单独表格的每个模拟数据,它将是类似的第一类型,但是可以附加具有传感器值的字段;
优点:
缺点:
可能所有人都减轻了一些专业人士,但如果我们获得显着的性能提升和/或(不太优选但也很有价值)存储空间,我们可能会遵循这种方式。
2也许只是每个传感器的分割表(它将是大约10万个表)或更好的传感器范围和/或移动到具有专用服务器的不同数据库,但我们希望尽可能避免硬件跨度。
3保持原样。
4切换到不同类型的DBMS,例如面向列的DBMS(HBase和类似的)。
你怎么看?也许你可以为进一步阅读建议资源?更新 传感器的一些数据甚至可以在一个月的延迟(通常是1-2周延迟)到达系统的性质,有些总是在线,某种传感器最终有内存和上线。每个传感器消息都有相关的事件引发日期和服务器接收日期,因此我们可以区分最近收集的数据。处理包括一些统计计算,参数偏差检测等。我们构建了汇总报告以便快速查看,但是当我们从传感器更新旧数据(已经处理)获取数据时,我们必须从头开始重建一些报告,因为它们取决于所有可用的无法使用数据和聚合值。所以我们通常会保留3个月的数据以便快速访问和其他存档。我们努力减少存储数据所需的数量,但我们认为我们需要一切来保持结果准确。
UPDATE2:
此处包含主要数据的表格。正如我在评论中提到的,我们在“需要速度”期间删除了它的所有依赖关系和约束,因此它仅用于存储。
StateB_2
来自其中一台服务器的示例数据:
CREATE TABLE [Messages](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[sourceId] [int] NOT NULL,
[messageDate] [datetime] NOT NULL,
[serverDate] [datetime] NOT NULL,
[messageTypeId] [smallint] NOT NULL,
[data] [binary](16) NOT NULL
)
答案 0 :(得分:1)
只是想提出一些想法,希望它们有用 - 它们是我正在考虑/思考/研究的一些事情。
分区 - 您提到该表按月分区。是您自己手动分区,还是使用Enterprise Edition中提供的分区功能?如果是手动,请考虑使用内置的分区功能将数据分区更多,这样可以提高可扩展性/性能。 Kimberly Tripp关于MSDN的这篇“Partitioned Tables and Indexes”文章很棒 - 那里有很多很好的信息,我不会通过释义来表达不公正!值得考虑的是,每个传感器手动创建1个表,这可能更难以维护/实施,因此增加了复杂性(简单=好)。当然,只有你有企业版。
已过滤的索引 - 请查看this MSDN article
当然有硬件元素 - 毫无疑问,带有大量RAM /快速磁盘等的内容丰富的服务器将会起作用。
答案 1 :(得分:1)
与数据库无关的一种技术是切换到记录值的变化 - 每分钟至少有n条记录。因此,例如,如果传感器没有1发送类似的东西:
Id Date Value
-----------------------------
1 2010-10-12 11:15:00 100
1 2010-10-12 11:15:02 100
1 2010-10-12 11:15:03 100
1 2010-10-12 11:15:04 105
然后只有第一个和最后一个记录将在DB中结束。为确保传感器处于“实时”状态,每分钟最少输入3条记录。这样就可以减少数据量。
不确定这是否有帮助,或者在您的应用中是否可行 - 只是一个想法。
修改强>
是否可以根据访问概率归档数据?说旧数据比新数据更不可能被访问是否正确?如果是这样,您可能需要查看Bill Inmon的下一代数据仓库的 DW 2.0架构,其中讨论了通过不同DW区域移动数据的模型(交互式,集成式,近端式) Line,Archival)基于访问概率。访问时间从非常快(交互区)到非常慢(存档)。每个区域都有不同的硬件要求。目标是防止大量数据堵塞DW。
答案 2 :(得分:1)
存储方面你可能会好起来的。 SQL Server将处理它。
令我担心的是您的服务器将承担的负载。如果您经常收到交易,那么今天每秒约有400笔交易。将此值提高20倍,您可以查看每秒约8,000笔交易。考虑到您正在报告相同的数据,这不是一个小数字......
顺便说一句,我是否正确理解您在处理传感器数据时丢弃传感器数据?那么你的总数据集将是“滚动”的10亿行?或者你只是附加数据?
答案 3 :(得分:0)
您可以将日期时间戳存储为整数。我相信datetime标记使用8个字节,整数只在SQL中使用4个。你不得不离开这一年,但由于你按月分区,这可能不是问题。
所以'12 / 25/2010 23:22:59'将被存储为1225232259 -MMDDHHMMSS
只是一个想法...