Ove*_*ack 4 c# azure azure-storage
我正在处理一个涉及Azure IOT集线器和Azure功能的Azure项目。
我大约有50个传感器,每10秒会向IOT集线器发送一条新消息。
每次Azure IOT Hub收到新消息时,我都想执行一个函数,该函数读取发送的消息并将其保存到Azure表存储中。
此刻,我对应该使用哪种Azure Table存储设计有些困惑。到目前为止,这是我建议的表存储设计:
[PartitionKey][RowKey][TimeStamp][SensorSerial][Reading][Type]
Run Code Online (Sandbox Code Playgroud)
这是Azure存储资源管理器中数据外观的模拟:
[GroupA][?][2017-05-03T12:20:22.713Z][xxx][60][Temperature]
[GroupA][?][2017-05-03T12:25:22.713Z][xxx][61][Temperature]
[GroupA][?][2017-05-03T12:30:22.713Z][xxx][59][Temperature]
[GroupB][?][2017-05-03T12:35:22.713Z][yyy][90][Humidity]
[GroupB][?][2017-05-03T12:40:22.713Z][yyy][92][Humidity]
Run Code Online (Sandbox Code Playgroud)
我将RowKey留在“?” 目前,因为它与手头的问题有关。
该问题是,那我希望能够查询既基于SensorSerial表存储的数据和规定的时间框架 - 如得到最后15秒所有XXX读数。
以下查询始终不返回任何数据:
TableQuery<Readings> rangeQuery = new TableQuery<Readings>().Where(
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition("SensorSerial", QueryComparisons.Equal, "xxx"),
TableOperators.And,
TableQuery.GenerateFilterConditionForDate("TimeStamp",
QueryComparisons.GreaterThanOrEqual, DateTime.Now.AddSeconds(-15))));
Run Code Online (Sandbox Code Playgroud)
从到目前为止的内容来看,我不确定为什么会这样- 无法基于TimeStamp字段过滤数据。因此,必须将RowKey用作某种伪TimeStamp日期时间刻度字段。
因此,为了解决此问题,我计划将其用作RowKey值
var RowKey = string.Format("{0:D19}", DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks);
Run Code Online (Sandbox Code Playgroud)
这将满足此查询并返回必要的值:
TableQuery<Readings> query = new TableQuery<SensorEntity>().Where(
TableQuery.CombineFilters(
(TableQuery.GenerateFilterCondition("SensorSerial", QueryComparisons.Equal, "xxxx")),
TableOperators.And,
(TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThanOrEqual,
"2519084875883616261"))));
Run Code Online (Sandbox Code Playgroud)
但是,在这里我可能是错的,由于以下原因,这种方法可能会引起一些问题:
如果两个或多个传感器同时/间隔传输数据怎么办?RowKey必须是唯一的,当一个传感器向Azure存储中插入新行时,另一传感器将无法继续。
我可以运行该代码,希望传输/数据处理/插入会导致足够的延迟,而不会导致任何问题,但是依靠它会很糟糕。
有没有更好的办法?一种更安全的故障排除方法,允许我根据指定的时间和唯一的设备标识符查询Azure数据表存储吗?
让我们首先谈谈您当前的方法。
您目前采用的方法还可以。这种方法的好处是,reverse ticks (DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks)只要您要查询最近x分钟/小时的数据,就可以确保将最新数据添加到表的顶部而不是表的底部。 ,检索将非常快。
后来我发现这种方法存在一些问题:
Partition Scans正在发生的情况。这要好一些,Full Table Scans但是如果可能的话应该避免。scalability limits受到表服务的强加,因为所有读/写操作都只发生在一张表上。这将对性能产生不利影响。可能的解决方案
一种可能的解决方案(现在考虑将查询针对某个传感器)是为每个传感器创建一个单独的表,然后将该传感器的数据存储在指定的表中。我看到的这种方法的优点是:
PartitionKey用作反向刻度和RowKey其他所需的值。我建议使用较高的粒度(例如一个小时)存储刻度线,PartitionKey并保持RowKey相同。这样可以确保您最终不会创建很多分区。SensorAtable可以在Storage Account A,Sensor Btable可以在Storage Account B。这样,您实际上可以在不同表/存储帐户之间实现流量负载平衡,并获得更好的可伸缩性和吞吐量。显然,此方法的缺点是,它会使您增加管理麻烦。您将需要某种主数据库,以保持传感器及其关联存储帐户之间的关联。这种方法的另一个缺点是您将无法仅根据时间戳查询(我的第二个问题)。为此,您可以采用所采用的方法在另一个存储帐户中仅保留一个表。
关于您的评论What if two or more sensors being to transmit data at the same time/interval? RowKey must be unique, the moment one sensor inserts a new row into Azure Storage, the other will no linger be able to.,本质上RowKey必须在一个表中唯一,Partition换句话说,PartitionKey + RowKey组合在表中必须是唯一的。因此,我认为这不会成为问题。
| 归档时间: |
|
| 查看次数: |
1456 次 |
| 最近记录: |