【问题标题】:Azure Storage Table Does not return whole partitionAzure 存储表不返回整个分区
【发布时间】:2017-06-21 17:54:28
【问题描述】:

我在生产时发现了一些情况

CloudContext.TableData.Where( A => A.PartitionKey == "MYKEY").ToList();

TableData 在哪里

public DataServiceQuery<T> TableData { get { return CreateQuery<T>( _TableName ); } }

不返回整个分区(我那里的记录少于 1000 条)。

在我的情况下,它返回 367 条记录,而在 VS2010 服务器资源管理器或 Azure 存储资源管理器中我得到 414 条记录(条件相同)。

有人遇到过同样的问题吗?

此外,如果我更改查询并将 RowKey 添加到条件中 - 我会毫无问题地获得所需的记录。

【问题讨论】:

  • 基于之前的解决方案:修改代码:TableData -> CreateQuery(_TableName).AsTableServiceQuery(); ToList() -> public static List ToFullList( this IQueryable Source ) { if( Source == null ) { throw new ArgumentNullException( "Source" ); } return Source.AsTableServiceQuery().Execute().ToList(); }

标签: azure storage


【解决方案1】:

您必须更好地了解 Table Service。在官方文档here 中列出了影响返回记录数的其他条件。如果要检索整个分区,则必须检查 TableResult 中的 Continuation Token 并使用提供的 continuation 令牌一遍又一遍地执行相同的查询,直到所有结果出现。

您可以使用类似于以下的方法:

    private IEnumerable<MyEntityType> GetAllEntities()
    {
        var result = this._tables.GetSegmentedEntities(100, null); // null is for continuation token
        while (result.Results.Count > 0)
        {
            foreach (var ufs in result.Results)
            {
                yield return new MyEntityType(ufs.RowKey, ufs.WhateverOtherPropertyINeed);
            }
            if (result.ContinuationToken != null)
            {
                result = this._tables.GetSegmentedEntities(100, result.ContinuationToken);
            }
            else
            {
                break;
            }
        }
    }

其中GetSegmentedEntities(100, result.ContinuationToken)定义为:

    public TableQuerySegment<MyEntityType> GetSegmentedEntities(int pageSize, TableContinuationToken token)
    {
        var partKey = "My_Desired_Partition_key_passed_via_Const_or_method_Param";
        TableQuery<MyEntityType> query = new TableQuery<MyEntityType>()
            .Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partKey));
        query.TakeCount = pageSize;
        return this.azureTableReference.ExecuteQuerySegmented<MyEntityType>(query, token);
    }

您可以根据自己的情况使用和修改此代码。

【讨论】:

    【解决方案2】:

    这是一种已知且记录在案的行为。表服务 API 将在 5 秒内返回 1000 个实体或尽可能多的实体。如果查询的执行时间超过 5 秒,它将返回一个继续令牌。

    通过添加行键,您可以使查询更加具体,因此更快,因此您可以获得所有实体。

    详情请参阅 MSDN 上的TimeOuts and Pagination

    【讨论】:

      【解决方案3】:

      如果您获得部分结果集,那么将有两个因素。

      i) 您有超过 1000 条匹配过滤器的记录 ii) 查询时间超过 5 秒。 iii) 查询跨越分区边界。

      由于您的记录少于 1000 条,因此第一个因素不会成为问题。并且当您基于 PartitionKey 相等性进行检索时,第三个因素也不会导致任何问题。由于第二个因素,您面临这个问题。

      您需要处理两个处理继续令牌。您可以参考此link 了解更多信息。

      【讨论】:

        猜你喜欢
        • 2013-09-17
        • 1970-01-01
        • 2013-02-04
        • 2013-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-05
        • 1970-01-01
        相关资源
        最近更新 更多