【问题标题】:DocumentDB - Storing telemetry dataDocumentDB - 存储遥测数据
【发布时间】:2016-06-06 16:25:57
【问题描述】:

所以快速更新一下我为什么创建这个问题。

我们目前将设备的遥测数据存储在 Azure SQL Server 的现场。这很好用(在 EF、LINQ 和关系数据库方面有大量经验)但我知道这很可能不是最好的解决方案,尤其是对于存储“大”数据(数据现在仍然很小,但会在一年内增长) )。

我选择了 DocumentDB 作为我们可能的解决方案来存储我们的事件历史。其余的将留在 SQL 中 - 用户、配置文件、设备信息、SIM、车辆等,因为我不想完全停止开发,因为我们将 100% 迁移到 docdb,而只是做短期内最好的事情 - 成本 + 性能。

通过这个视频,我终于想出了一个关于如何存储遥测数据的可能解决方案 - https://www.youtube.com/watch?v=-o_VGpJP-Q0 他们建议每个时间段一个文档(示例使用每小时 1 个)。这仍然是推荐的方法吗?

    [Index]
    public DateTime TimestampUtc { get; set; }
    public DateTime ReceivedTimestampUtc { get; set; }
    [Index]
    public EventType EventType { get; set; }
    public Guid ConnectionId { get; set; }
    public string RawEventMessage { get; set; }
    [Index]
    public Sender Sender { get; set; }
    [Index]
    public Channel Channel { get; set; }
    public DbGeography Location { get; set; }
    public double? Speed { get; set; }
    public double? Altitude { get; set; }
    public Int16? Heading { get; set; }
    public Byte? HDOP { get; set; }
    public Byte? GPSFixStatus { get; set; }
    public Byte? GPSFixType { get; set; }
    public string Serial { get; set; }
    public string HardwareVersion { get; set; }
    public string FirmwareVersion { get; set; }
    public string Relay1 { get; set; }
    public string Relay2 { get; set; }
    public string Relay3 { get; set; }
    public string Ign { get; set; }
    public string Doors { get; set; }
    public string Input1 { get; set; }
    public string Input2 { get; set; }
    public string Out1 { get; set; }
    public string Out2 { get; set; }
    public int V12 { get; set; }
    public int VBat { get; set; }

【问题讨论】:

  • 免责声明 - 我是您引用的 //build 视频的共同作者之一 - 实际上没有“推荐”的方法来存储遥测数据。我们展示的用于存储遥测数据的是一个特定的建模案例,它基于我们处理过的一些实际解决方案,特定于 DocumentDB 等文档数据库(它可能适用于您的特定案例,也可能不适用)。还有其他建模方法,甚至是不同的数据库引擎类型。
  • 嘿,戴夫,感谢您的回复 :) 是的,今天头脑风暴,发现了这个好视频,它给了我另一个选择。在 SQL 中一切正常,只是长期关注
  • 很高兴你喜欢它 - 谢谢。 :) 如果它给了你一些新的思考,那么我认为它是成功的。
  • 是的,我唯一担心的是为每个事件创建一个文档 ~ 每台设备每 5 分钟创建一个文档。将来可能会更改为每秒基准数:/ 需要考虑很多。
  • 所以我认为我的 2 个选项是每个事件 1 个文档(可以是每秒:/)或每个时间段 1 个文档(每小时 1 个)。数据完全不同 - 纬度、经度、时间、#sats、HDOP 等。每台设备每秒创建一个文档的缺点是什么?成本/性能?如果是这样,我将在每个时间段(一小时或一天)的每个设备上制作一个文档。

标签: azure azure-cosmosdb document-database telemetry nosql


【解决方案1】:

这是几种可能的选择之一。哪个最好取决于您的数据是什么样的。例如,如果您的事件的开始日期/时间和持续时间(或结束日期/时间)有所不同,或者如果您跟踪实体的所有状态变化,那么像 Richard Snodgrass' 这样的时间数据模型是理想的。有趣的是,Microsoft SQL Server 2016 最近添加了对temporal tables 的直接支持,但它们在 SQL 规范中作为 TSQL2 已经有一段时间了。请注意,TSQL2 规范同时包含 valid-timetransaction-time 支持,但我相信最近添加的 MS SQL 2016 仅支持有效时间......但这没关系,因为这是最有价值的。我只是指出这一点,因为如果不增加事务时间的复杂性,了解有效时间表的工作原理就足够困难了。

这种方法的美妙之处在于,您不必在收集数据时决定所需的时间粒度,只需在您聚合数据时/何时进行。

但是,正如您所说,SQL 对于如此大的数据集并不理想。因此,我在我的 Lumenize 库中的 DocumentDB 之上实现了有效时间 Richard Snodgrass 样式的时间模型,特别是 TimeSeriesCalculator 及其其他时间序列功能。阅读第 10-19 页here,了解有关 Lumenize 时间序列分析中的数据模型和常见操作的背景知识。该套牌是我在 Rally 时所做的一个实现,称为基于 MongoDB 构建的 Lookback API,但概念是相同的,我现在已经切换到 DocumentDB(但 Rally 没有)。

对您提出的模型的另一个评论,您可能需要考虑为每次阅读单独的文档。如果每分钟有一个文档或每个设备有一个文档,那么这个例子有点令人困惑。如果是每台设备每小时一个,那么你可以放心,你永远不会超过 60 分钟,这没关系,但在我能想到的几乎所有其他方式中,看起来你有一个风险文档无限增长,这在 DocumentDB(以及所有 NoSQL 数据建模)中是一个很大的禁忌。此外,正如您所说,即使它不是无限的,它也会涉及大量的就地更新。由于您的系统可能会写得很重,我建议您最好每次阅读一个文档。如果您以后必须存储非规范化聚合以提高速度,那么您仍然可以选择这样做。你甚至可能不需要它。让生产系统的性能为该决定提供依据。

我建议您阅读星型模式的时间维度。它看起来很像您的计划,但它也是我描述的非规范化聚合存储的理想选择。我没有看到任何关于 NoSQL 星型模式概念的文章,但 here 是来自传统 SQL 世界的一篇文章,可以帮助您了解这些概念。

正如我所说,有很多选择,如果不了解您的情况,我无法知道哪个是最好的。

【讨论】:

  • 感谢您的精彩回答!将尽快更彻底地完成它,同时我将解释数据速率,数据是什么样的以及它是如何使用的。现在我们可以安全地说每 5-10 分钟 1 包,所以很少……现在!可以肯定地说我应该设计为每秒 1 次,但以 30-60 秒的时间块从设备获取数据(有点无关紧要)。我在原始帖子中添加了一些代码优先数据模型。
  • 大部分内容将为空,因为只有某些消息会填充某些字段,我不知道这是否也会影响...
  • 可以通过省略该字段来表示null。您必须对查询小心一点,因为实际的空值和缺失值的响应会有所不同。使用IS_DEFINED(...) 而不是IS_NULL(...)。这种方法在存储方面具有优势,但它也使您的索引更小更快。
  • 好的,非常感谢,所以我认为我的 2 个选项是每个事件 1 个文档(可以是每秒 :/)或每个时间段 1 个文档(每小时 1 个)。数据完全不同 - 纬度、经度、时间、#sats、HDOP 等。每个设备每秒创建一个文档的缺点是什么?成本/性能?如果是这种情况,我将在每个时间段(一个小时或一天)为每个设备制作一个文档。
  • 又是我......在正确阅读 Azure 临时表之后,我现在再次对 SQL 感到兴奋,哈哈,并且可能有一天会考虑处理一张大表(索引/比例神;)) .这将非常有效,我相信监控变化(门状态,点火等)非常好!我想我需要回答的是——SQL 对我的设计设置真的那么糟糕吗?有这么大的桌子有那么糟糕吗?
【解决方案2】:

好的,所以我想我要为每个事件创建 1 个文档(现在每 5 分钟 1 个,但可以更改为每个设备每秒 1 个)。附加到文档的原因肯定会很昂贵,因为您需要对该文档进行“替换”? (docdb 现在是否支持追加/部分更新?)当然,这涉及读取,然后是不断增长的替换,这比仅为每个事件添加新文档更昂贵和及时。唯一需要担心的是,当我们有数百万/数十亿的文档时……这样可以吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多