我需要创建高度可扩展的解决方案——数千个站点中的现场设备将数据实时传送到后端系统,而 SQL Azure 在添加 sql 数据库和应用程序服务器方面似乎非常适合。
每个现场设备每秒有效地发送 400 个传感器值 - 每天大约两个小时,而所有其他时间每 5 分钟发送 400 个传感器值。此外,当该现场设备发生错误时,它还会发送所有 400 个传感器的最后一分钟数据(400 * 60 个读数)——当出现任何问题时会导致大量数据。
我真的很想设计系统,使独立的现场设备及其存储的数据不会影响其他设备。允许每个现场设备不影响其他现场设备的性能。
我开始设计时考虑使用单个数据库来保存所有设备的数据 - 但是在模拟多个站点设备时已经开始出现死锁。因此,我正在转向多数据库解决方案。主数据库保存所有设备的查找表 - 将连接字符串返回到真实数据库
在项目的这个阶段,最重要的是我能够将这些数据实时传递回在 Web 浏览器中运行的用户界面——每秒更新它们的屏幕。
在项目的未来阶段,有必要开始跨多个设备聚合数据,显示统计数据,例如区域 Y 中传感器 X 的总和。我可以看到这对于多数据库方法来说很难做到。
所以会重视任何建议,例如
您认为使用 Sql Azure 托管潜在的 1000 个数据库并使用此主数据库间接指向真实数据库是否明智?
从应用程序到数据库的连接是否会出现问题 - 例如连接池问题?
我将如何从 Sql Azure 中的所有这些不同数据库中聚合数据。
会对您的所有评论感兴趣。问候,克里斯。
由于没有其他人回答,我将分享一些意见并挥手。
只要您不锁定公共资源,或者以相同的顺序锁定资源,就不会出现死锁问题。
我会在单独的数据库之前查看单独的表。每个额外的数据库肯定会花费更多,但额外的表不一定会花费更多。您可能需要使用超过 1 个数据库,因为您将存储大量数据,或者因为您需要存储突发流量的速率。如果您可以管理它,我认为表级粒度将比从数据库级粒度开始更灵活,并且可能便宜很多。
将每个设备的数据放入它自己的表中的问题在于,它使报告变得困难,因为所有表名都不同。
我认为您有某种方法可以检测何时收到“重新发送失败”的数据。您不想将相同的值两次放入表中,我确信设备可能会发生故障(本地电源故障?),而与早期值是否正确存储无关。
WAG:假设每个“值”为 4 个字节,我计算出每台设备每天收集的数据约为 11.5 MB。(这忽略了各种东西,例如设备标识符和时间戳,但我认为粗略估计是可以的。)因此,对于“数千”个站点,我们每天查看数十 GB。您没有提到该数据的任何生命周期。最大的 Azure 数据库目前最大为 150 GB。你可以很快填满这些。
在短时间内在网络浏览器中发生任何事情是不确定的。当您从(可能是多个)具有 GB 数据的数据库中读取数据时,不断地将大量新数据插入到您正在读取的表中并通过开放的 Internet 与 Web 服务器进行交互时,“实时”是一厢情愿的想法。国际海事组织。“足够快”是通常的目标。
如果您无法将所需的所有数据保存在一个 SQL Azure 数据库中的单个报告中,那就是个问题。没有链接服务器或分布式视图(此时)。没有简单的方法可以跨多个 Azure 数据库进行聚合。您必须将所有数据拉到一个中心位置并从那里报告。我猜聚合数据太大而无法存储在单个 SQL Azure 数据库中,因此您必须转到本地或 EC2。具有星型模式结构的数据集市或仓库将是那里的经典答案,但这需要大量的处理时间,这意味着没有“实时”。此外,这可能会导致从 Azure 到任何地方的更多数据传输,这将花费您。
如果没有先行试点计划,我不会采用这种策略。首先要做的是构建一个实例(它可以每秒处理 400 个传感器值吗?(是一系列行、一个大的非规范化行、一个 XML 文档还是其他什么?传入数据的格式会影响数据可以存储多快。您可以进行批量插入,还是必须逐行进行?)每秒 4,000 个传感器值怎么样?单个 SQL Azure 实例可能无法存储该值很快。)并查看它如何以您的预期速率处理插入,并查看报告如何工作。我也会和微软谈谈。仅仅处理成百上千个独立数据库的计费可能很奇怪。
我不知道这是否适用于你,但你看过微软的“Stream Insight”产品吗?它似乎是针对像你这样的情况。警告:我从未使用过它。
营销宣传:有效分析来自多个来源的大量事件数据。使用 Microsoft StreamInsight 近乎实时地从关键信息中获取见解。监控、分析和处理动态数据并几乎立即做出明智的决策
在快速进行谷歌搜索时,我注意到一篇博客文章指出,StreamInsight 去年可作为 CTP 在 SQL Azure 上使用。它现在可能已经准备好迎接黄金时段了。
祝你好运,这听起来是一个有趣的项目。
我想我会发布一个关于项目实际如何运作的快速答案。
最后,我们没有使用 Azure。我们使用标准 SQL 数据库服务器 - 每个引擎都位于不同的数据库中。理论上,主数据库保存每个引擎的连接信息。因此可以在不同的数据库服务器上存储不同的引擎。在实践中,我们还不需要这样做。目前我们在一台机器上有 200 个引擎数据库。我使用连接池。
每个引擎每秒到达的 400 个传感器以 XML 格式发送,转换为 DataTable,并使用自定义数据类型批量插入 SQL 数据库。每秒插入 400 条记录只需要 40ms - 70ms。我对现有数据集进行了外部连接,以应对现有数据重新发送的情况。
该系统的编写方式使得每个引擎在理论上不应减慢其他引擎的速度。每个引擎都在其自己的线程池中进行有效管理。这些线程池可以存在于不同的服务器中。对数据库的写入和每个用户界面(Web 浏览器)的更新是在单独的线程中完成的,因此用户不必等待数据库完成插入。
我们现在处于一个位置,我们准备将这个概念带入 Azure。现在 Azure 中的限制似乎不像撰写本文时那么多。
我对这样的系统没有经验,但我的建议比评论长,所以我会发布作为答案......
您说“每秒发送 400 个传感器值”。这是否意味着每秒有 400 条单独的消息,我会假设每条消息都会触发一个单独的 INSERT 语句?如果是这样,您能否获取所有这些数据,将其包装成单个 XML 消息,并将其发送到 Web 服务,该 Web 服务将这些传入消息存储在临时保存表/队列中,然后将它们分解并作为单独的步骤处理它们?这可能会导致处理速度稍慢,但也可能有助于缓解死锁问题,而无需求助于多个数据库,因为在这种情况下,您有一个进程管理所有插入数据库的数据。我们在这里将消息队列和 Web 服务用于类似的目的,尽管我们离这种数量还很远。