DocumentDB - 存储遥测数据

时间:2016-06-06 16:25:57

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

快速更新我为什么创建这个问题。

我们目前正在Azure SQL Server中的现场存储我们设备的遥测数据。这很好用(有很多关于EF,LINQ和关系dbs的经验)但是我知道这很可能不是最好的解决方案,特别是对于存储"大"数据(现在数据仍然很小,但会在一年内增长)。

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

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

enter image description here

    [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; }

2 个答案:

答案 0 :(得分:2)

这是几种可能的选择之一。哪个最好取决于您的数据是什么样的。例如,如果您的开始日期/时间和持续时间(或结束日期/时间)不同,或者您跟踪实体的所有状态更改,那么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时间序列分析中的常见操作。那个套牌是我在拉力赛时所做的一个实现,叫做在MongoDB上构建的Lookback API,但概念是相同的,我现在已切换到DocumentDB(但Rally还没有)。

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

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

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

答案 1 :(得分:0)

好的,所以我想我要为每个活动提供1个文件(现在每5分钟1个,​​但每台设备可以改为1个)。原因是附加到文档肯定是昂贵的,因为你需要对该文件进行“替换”? (docdb现在支持附加/部分更新吗?)当然,这涉及一个阅读,然后一个不断增长的替换,这将比每个事件添加一个新的doc更昂贵和及时。唯一的问题是当我们有数百万/数十亿的文件时......这样可以吗?