建议从Azure表存储中提取多条1000条个别记录?

时间:2017-06-21 20:51:21

标签: azure azure-table-storage

我有一个Azure表存储,其中包含来自数百个远程设备的微小遥测。数据由连接设备ID,位置ID,年份和年份的密钥分区。因此,举例来说,如果我想为任何给定的设备提取整整一个月的数据,我需要从30个分区中提取所有数据。

对于一个特定的计算,我只需要在小时的顶部和底部加上时间戳的记录,即分钟分别为0和30的时间。目前,为了做到这一点,我创建了一个任务数组来单独拉出每个记录并并行获取它们(一个月这是1440年 - 我知道每个记录的分区键和行键,所以我可以使用TableOperation.Retrieve< >(partitionKey,rowKey)方法。下面的代码说明了方法:

var tasks = new List<Task<TableResult>>();
foreach (var date in dates)
{
    foreach (var timeOfDay in checkTimes)
    {
        var dateTimeLocal = date.Add(TimeSpan.Parse(timeOfDay));
        var dateTimeUtc = Helper.ConvertLocalTimeToUtcTime(location.TimeZoneId, dateTimeLocal);

        var partitionKey = location.RowKey + "_" + deviceGuid + "_" + dateTimeUtc.DayOfYear + "_" + dateTimeUtc.Year;
        var rowKey = dateTimeUtc.ToString("yyyy-MM-ddTHH:mm:00");

        var table = TableHelper.GetTable(Data.StorageString, "table");
        var retrieveOperation = TableOperation.Retrieve<DataEntities.EnergyData>(partitionKey, rowKey);
        tasks.Add(table.ExecuteAsync(retrieveOperation));
    }
}

await Task.WhenAll(tasks.ToArray());

var demandData = tasks.Where(c => c.Result.Result != null).Select(c => (DataEntities.EnergyData)c.Result.Result).ToArray();

日期数组包含我想要聚合的每一天的午夜时间,而checkTimes是我每天对每天感兴趣的时间。

对于一个月的数据(约1440条记录),这种方法可能需要花费更长的时间,而不仅仅是拉动每个记录一个月,并在内存中过滤我感兴趣的记录 - 我期待它要快得多。

关于为什么这么慢运行的任何想法(例如,对于Table Storage来说,这是一个限制问题)吗?有更快更可靠的方法吗?我开始认为最好的方法就是将分钟为0或30的每一行的副本复制到另一个表中,以便我可以在一些较大的查询中检索我需要的内容。

1 个答案:

答案 0 :(得分:0)

正如Query Entities所述:

  

针对Table服务的查询可能一次返回最多1,000个实体,并且最多可以执行5秒。如果结果集包含超过1,000个实体,如果查询未在五秒内完成,或者查询跨越分区边界,则响应包括包含一组延续令牌的自定义标头。继续令牌可用于构造对下一页数据的后续请求。

根据您的方案,您已指定partitionKeyrowKey来检索单个记录。根据我的理解,此时,您的客户端会针对表格服务发送1000多个请求,而对于Partition Range ScanRow Range Scan,它只会发送多个请求。

我认为使用Point Queries时可能会导致网络延迟(使用等式谓词指定单个PartitionKey和RowKey)。您可以enable azure storage metrics用于表格存储,并通过Microsoft Azure Storage Explorer检查AverageE2ELatencyAverageServerLatency指标,如下所示:

enter image description here

有关表存储指标的更多详细信息,请参阅Transactions Table Schema

  

关于为什么这么慢运行的任何想法(例如,对于Table Storage来说,这是一个限制问题)吗?有更快更可靠的方法吗?我开始认为最好的方法就是将分钟为0或30的每一行的副本复制到另一个表中,以便我可以在一些较大的查询中检索我需要的内容。

根据我的理解,您可以通过在一个月范围内指定RowKey(例如rowKey>="2016-06-01T00:00:00" and rowKey<="2016-06-30T23:59:59")来利用Row Range Scan来检索给定设备的记录,然后按照您的预期在内存中过滤