当前位置: 首页 > 知识库问答 >
问题:

如何在Azure Cosmos DB(表API)上调试/排除元数据DTU限制?

李跃
2023-03-14

我们使用Azure cosmos DB来保存作业处理管道的状态信息。为此,我们使用了table API和相应的SDK。最近,我们注意到系统频繁运行到429——请求率误差太大。我们的事务性DTU利用率远低于表上配置的最大值,但是我们注意到在metrics选项卡下,系统dtu被枚举表等操作使用..被耗尽,因此429。

我们删除“CreateIfNotExists”方法调用的初始修复程序帮助修复了一段时间,但最近我们又开始遇到这个问题(尽管不像以前那么频繁)。很难对此进行调试/故障排除,因为在那里我找不到足够的文档,说明哪个SDK方法调用耗尽了这个不可扩展的资源。我已在 CosmosDB 实例上启用日志记录,但我不确定在日志中查找什么来解决此问题

这是我们用于与Azure Cosmos DB接口的单例类

public class CosmosDbTableFacade : ICosmosDbTableFacade
{
        /// <summary>
        /// Initializes a new instance of the <see cref="CosmosDbTableFacade"/> class.
        /// </summary>
        /// <param name="connectionString">
        /// The connection string.
        /// </param>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        public CosmosDbTableFacade(string connectionString)
        {
            var storageAccount = CloudStorageAccount.Parse(connectionString);
            this.CosmosTableClient = storageAccount.CreateCloudTableClient();
        }

        /// <summary>
        /// Gets or sets the cosmos table.
        /// </summary>
        public CloudTableClient CosmosTableClient { get; set; }

        /// <summary>
        /// The execute async.
        /// </summary>
        /// <param name="tableName">
        /// The table Name.
        /// </param>
        /// <param name="operation">
        /// The operation.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        public Task<TableResult> ExecuteAsync(string tableName, TableOperation operation)
        {
            var table = this.CosmosTableClient.GetTableReference(tableName);
            return table.ExecuteAsync(operation);
        }

        /// <summary>
        /// The execute query segmented async.
        /// </summary>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        /// <param name="query">
        /// The query.
        /// </param>
        /// <param name="continuationToken">
        /// The continuation token.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/> which returns the list of entities.
        /// </returns>
        public Task<TableQuerySegment<DynamicTableEntity>> ExecuteQuerySegmentedAsync(string tableName, TableQuery query, TableContinuationToken continuationToken)
        {
            var table = this.CosmosTableClient.GetTableReference(tableName);
            return table.ExecuteQuerySegmentedAsync(query, continuationToken);
        }
}

以下片段列出了我们正在使用的不同查询-

public async Task InsertOrMergeEntityAsync<T>(string tableName, T entity)
            where T : TableEntity
{
            var insertOrMergeOperation = TableOperation.InsertOrMerge(entity);
            var result = await this.CosmosDbTableFacade.ExecuteAsync(tableName, insertOrMergeOperation).ConfigureAwait(false);
            ValidateCosmosTableResult(result, "Failed to write to Cosmos Table");
}

public async Task<T> GetEntityAsync<T>(string tableName, string partitionKey, string rowKey)
            where T : TableEntity
{
            var retrieveOperation = TableOperation.Retrieve<T>(partitionKey, rowKey);
            TableResult result = await this.CosmosDbTableFacade.ExecuteAsync(tableName, retrieveOperation).ConfigureAwait(false);
            ValidateCosmosTableResult(result, "Failed to read from Cosmos Table");
            return result.Result as T;
}

public async Task<IEnumerable<T>> GetEntitiesAsync<T>(string tableName, string filterCondition)
            where T : TableEntity
{
            var query = new TableQuery().Where(filterCondition);
            var continuationToken = default(TableContinuationToken);
            var results = new List<T>();
            do
            {
                var currentQueryResults = await this.CosmosDbTableFacade.ExecuteQuerySegmentedAsync(tableName, query, continuationToken).ConfigureAwait(false);
                results.AddRange(currentQueryResults.Select(currentQueryResult =>
                    {
                        var currentEntity = TableEntity.ConvertBack<T>(currentQueryResult.Properties, null);
                        currentEntity.RowKey = currentQueryResult.RowKey;
                        currentEntity.PartitionKey = currentQueryResult.PartitionKey;
                        currentEntity.Timestamp = currentQueryResult.Timestamp;
                        currentEntity.ETag = currentQueryResult.ETag;
                        return currentEntity;
                    }));
                continuationToken = currentQueryResults.ContinuationToken;
            }
            while (continuationToken != null);

            return results;
}

下面最后一个方法中的筛选器包含分区键和自定义列

共有1个答案

卫学真
2023-03-14

对于遇到类似问题的人来说,在我的例子中,元数据DTU限制的根本原因是:GetTableReference(tableName)方法(通过部署将该行移动到启动代码并监视DTU利用率的更改来找到)。我有这个,以便我可以在运行时动态指向要读/写到哪个表,但由于这会消耗元数据DTU,因此我将代码更改为使用单例作为表引用。

 类似资料:
  • 我试图使用Twilio API(使用节点Twilio包装器)实现语音调用,如果调用没有应答,则需要重试x次。似乎如果我忽略了Twilio的呼叫,它会自动继续尝试。那么,我有没有办法将retying限制设置为特定的次数? 提前谢谢。

  • 虽然我的其他Codeception测试正在运行(验收、api等),但很少有单元测试会运行。它没有看到任何Test.php类型的测试,只有Cept.php和Cest.php。它不接受(错误)任何断言测试,例如“$this”- PHPUnit似乎已安装,因为我在供应商目录中看到它。我可以直接从命令行运行它来查看它的帮助。但仅此而已。Laravel/代码欺骗组合的单元测试通常是片状的吗?有一些配置我错过

  • 问题内容: 我有一个执行简单的sql select语句的sql函数: 现在,我正在像这样调用此函数: 如果我需要使用order byandlimit子句对结果进行排序和限制,我有哪些选择? 我猜这样的查询: 效率不是很高,因为表中的所有行都stuff将由函数返回,getStuff然后才按限制排序和切片。 但是,即使我是对的,也没有简单的方法来通过sql语言函数的参数传递命令。只能传递值,不能传递s

  • 我的项目结构如下: 在Jenkins工作中,根pom是(因为我希望整个项目是为功能覆盖的JaCoCo报告构建的),当运行覆盖报告生成的Maven目标时,我将pom指定为模块FT/pom.xml. 现在,当显示测试结果时,它向我显示了一个总的being=FTs其他模块中的所有单元测试,而我想从报告生成中排除UTs。 但我不认为这与杰科科有关,因为我说的不是杰科科的报告,而是测试结果。单元测试也被计算

  • 我要从Thorntail搬到Quarkus。在我的测试中,我曾创建一个@deployment方法,在该方法中,我只放置测试所需的内容。特别是,我没有把一个类放在@Startup注释中(因为我不想测试它…)。当我移动到QUARKUS时,我抑制了de@deployment静态方法,然后当我启动测试时@Startup是。。。一开始,发生了很多不好的事情,阻止我测试我想要测试的东西(好吧,它崩溃了,因为它

  • 问题内容: 我开始采用TDD开发态度,并为django应用程序编写单元测试。我知道固定装置,并且知道应该执行测试的方式,但是对于给定的测试,我确实需要在整个数据库上执行它,而我想处理的10百万以上行数据库的json固定装置,此外,此测试是“只读”的。 因此,问题是如何设置测试套件以在生产数据库上运行?我想这就像在某些测试的setUp方法中添加DATABASE_NAME设置一样容易。但是运行测试时,