将高级诊断查询与 Azure Cosmos DB for Apache Cassandra 配合使用来解决问题

适用对象: NoSQL MongoDB Cassandra Gremlin

本文介绍如何使用发送到特定于资源的表的诊断日志编写更高级查询,以便排查 Azure Cosmos DB for Cassandra 帐户的问题。

对于 Azure 诊断表,所有数据都写入一个表中。 用户指定要查询的类别。 若要查看请求的全文查询,请参阅使用 Azure 中的诊断设置监视 Azure Cosmos DB 数据,了解如何启用此功能。

对于特定于资源的表,数据将写入每个资源类别的各个表中。 出于以下目的,我们建议采用此模式:

  • 简化数据处理程序。
  • 可提高架构的可发现性。
  • 改善了引入延迟和查询时间的性能。

先决条件

警告

为 API for Cassandra 帐户创建诊断设置时,请确保“DataPlaneRequests”保持未选中状态。 此外,对于 Destination 表,请确保选择“特定于资源”,因为它比 Azure 诊断节省大量成本。

注意

请注意,启用全文诊断时,返回的查询会包含 PII 数据。 此功能不仅会记录带模糊参数的查询主干,而且还会记录参数本身的值。 这可能有助于诊断针对某个特定主键(或某组主键)的查询所消耗的 RU 数是否远多于针对其他主键的查询。

不同方案的 Log Analytics 查询

Image of a bubble word map with possible questions on how to leverage Log Analytics within Azure Cosmos DB

RU 消耗

  • 高 RU/秒型消耗的 Cassandra 操作。

    CDBCassandraRequests 
    | where DatabaseName=="azure_comos" and CollectionName=="user" 
    | project TimeGenerated, RequestCharge, OperationName,
    requestType=split(split(PIICommandText,'"')[3], ' ')[0]
    | summarize max(RequestCharge) by bin(TimeGenerated, 10m), tostring(requestType), OperationName;
    
  • 监视逻辑分区键上的每个操作的 RU 消耗。

    CDBPartitionKeyRUConsumption
    | where DatabaseName=="azure_comos" and CollectionName=="user"
    | summarize TotalRequestCharge=sum(todouble(RequestCharge)) by PartitionKey, PartitionKeyRangeId
    | order by TotalRequestCharge;
    
    CDBPartitionKeyRUConsumption
    | where DatabaseName=="azure_comos" and CollectionName=="user"
    | summarize TotalRequestCharge=sum(todouble(RequestCharge)) by OperationName, PartitionKey
    | order by TotalRequestCharge;
    
    CDBPartitionKeyRUConsumption
    | where DatabaseName=="azure_comos" and CollectionName=="user"
    | summarize TotalRequestCharge=sum(todouble(RequestCharge)) by bin(TimeGenerated, 1m), PartitionKey
    | render timechart;
    
  • 影响 RU 消耗的最常用查询是什么?

    CDBCassandraRequests
    | where DatabaseName=="azure_cosmos" and CollectionName=="user"
    | where TimeGenerated > ago(24h)
    | project ActivityId, DatabaseName, CollectionName, queryText=split(split(PIICommandText,'"')[3], ' ')[0], RequestCharge, TimeGenerated
    | order by RequestCharge desc;
    
  • 基于读取和写入操作的有效负载大小差异的 RU 消耗。

    // This query is looking at read operations
    CDBCassandraRequests
    | where DatabaseName=="azure_cosmos" and CollectionName=="user"
    | project ResponseLength, TimeGenerated, RequestCharge, cassandraOperationName=split(split(PIICommandText,'"')[3], ' ')[0]
    | where cassandraOperationName =="SELECT"
    | summarize maxResponseLength=max(ResponseLength), maxRU=max(RequestCharge) by bin(TimeGenerated, 10m), tostring(cassandraOperationName)
    
    // This query is looking at write operations
    CDBCassandraRequests
    | where DatabaseName=="azure_cosmos" and CollectionName=="user"
    | project ResponseLength, TimeGenerated, RequestCharge, cassandraOperationName=split(split(PIICommandText,'"')[3], ' ')[0]
    | where cassandraOperationName in ("CREATE", "UPDATE", "INSERT", "DELETE", "DROP")
    | summarize maxResponseLength=max(ResponseLength), maxRU=max(RequestCharge) by bin(TimeGenerated, 10m), tostring(cassandraOperationName)
    
    // Write operations over a time period.
    CDBCassandraRequests
    | where DatabaseName=="azure_cosmos" and CollectionName=="user"
    | project ResponseLength, TimeGenerated, RequestCharge, cassandraOperationName=split(split(PIICommandText,'"')[3], ' ')[0]
    | where cassandraOperationName in ("CREATE", "UPDATE", "INSERT", "DELETE", "DROP")
    | summarize maxResponseLength=max(ResponseLength), maxRU=max(RequestCharge) by bin(TimeGenerated, 10m), tostring(cassandraOperationName)
    | render timechart;
    
    // Read operations over a time period.
    CDBCassandraRequests
    | where DatabaseName=="azure_cosmos" and CollectionName=="user"
    | project ResponseLength, TimeGenerated, RequestCharge, cassandraOperationName=split(split(PIICommandText,'"')[3], ' ')[0]
    | where cassandraOperationName =="SELECT"
    | summarize maxResponseLength=max(ResponseLength), maxRU=max(RequestCharge) by bin(TimeGenerated, 10m), tostring(cassandraOperationName)
    | render timechart;
    
  • 基于逻辑分区的读取和写入操作的 RU 消耗。

    CDBPartitionKeyRUConsumption
    | where DatabaseName=="azure_cosmos" and CollectionName=="user"
    | where OperationName in ("Delete", "Read", "Upsert")
    | summarize totalRU=max(RequestCharge) by OperationName, PartitionKeyRangeId
    
  • 按物理分区和逻辑分区划分的 RU 消耗。

    CDBPartitionKeyRUConsumption
    | where DatabaseName=="azure_cosmos" and CollectionName=="user"
    | summarize totalRequestCharge=sum(RequestCharge) by PartitionKey, PartitionKeyRangeId;
    
  • 热分区是否导致高 RU 消耗?

    CDBPartitionKeyStatistics
    | where DatabaseName=="azure_cosmos" and CollectionName=="user"
    | where  TimeGenerated > now(-8h)
    | summarize StorageUsed = sum(SizeKb) by PartitionKey
    | order by StorageUsed desc
    
  • 分区键如何影响 RU 消耗?

    let storageUtilizationPerPartitionKey = 
    CDBPartitionKeyStatistics
    | project AccountName=tolower(AccountName), PartitionKey, SizeKb;
    CDBCassandraRequests
    | project AccountName=tolower(AccountName),RequestCharge, ErrorCode, OperationName, ActivityId, DatabaseName, CollectionName, PIICommandText, RegionName
    | where DatabaseName=="azure_cosmos" and CollectionName=="user"
    | join kind=inner storageUtilizationPerPartitionKey  on $left.AccountName==$right.AccountName
    | where ErrorCode != -1 //successful
    | project AccountName, PartitionKey,ErrorCode,RequestCharge,SizeKb, OperationName, ActivityId, DatabaseName, CollectionName, PIICommandText, RegionName;
    

延迟

  • 在时间范围内显示的服务器端超时(状态代码 - 408)的数目。

    CDBCassandraRequests
    | where DatabaseName=="azure_cosmos" and CollectionName=="user"
    | where ErrorCode in (4608, 4352) //Corresponding code in Cassandra
    | summarize max(DurationMs) by bin(TimeGenerated, 10m), ErrorCode
    | render timechart;
    
  • 我们是否观察到指定时间范围内的服务器端延迟出现峰值?

    CDBCassandraRequests
    | where TimeGenerated > now(-6h)
    | DatabaseName=="azure_cosmos" and CollectionName=="user"
    | summarize max(DurationMs) by bin(TimeGenerated, 10m)
    | render timechart;
    
  • 正在受到限制的操作。

    CDBCassandraRequests
    | where DatabaseName=="azure_cosmos" and CollectionName=="user"
    | project RequestLength, ResponseLength,
    RequestCharge, DurationMs, TimeGenerated, OperationName,
    query=split(split(PIICommandText,'"')[3], ' ')[0]
    | summarize max(DurationMs) by bin(TimeGenerated, 10m), RequestCharge, tostring(query),
    RequestLength, OperationName
    | order by RequestLength, RequestCharge;
    

限制

  • 应用程序是否遇到任何限制?

    CDBCassandraRequests
    | where RetriedDueToRateLimiting != false and RateLimitingDelayMs > 0;
    
  • 哪些查询导致应用程序在指定的时间段(具体请查看 429)受到限制。

    CDBCassandraRequests
    | where DatabaseName=="azure_cosmos" and CollectionName=="user"
    | where ErrorCode==4097 // Corresponding error code in Cassandra
    | project DatabaseName , CollectionName , CassandraCommands=split(split(PIICommandText,'"')[3], ' ')[0] , OperationName, TimeGenerated;
    

后续步骤