

# 对 Amazon DynamoDB 中的内部服务器错误进行故障排除
<a name="TroubleshootingInternalServerErrors"></a>

在 DynamoDB 中，内部服务器错误（500 错误）表示服务无法处理请求。发生这些错误的原因可能多种多样，例如实例集中的临时网络问题、基础设施问题、存储节点相关问题等。

在 DynamoDB 表的生命周期中，您可能会遇到一些内部服务器错误。由于服务的分布式特性，这是意料之中的，通常不应引起关注。DynamoDB 可以自动实时修复和解决服务中的任何暂时问题，无需您进行任何干预。但是，如果您观察到对表的请求中出现大量内部服务器错误（如 [SystemErrors](metrics-dimensions.md#SystemErrors) 指标所示），则应进一步调查。

**Topics**
+ [调查内部服务器错误](#ServerErrors-investigating)
+ [尽可能地减少内部服务器错误的影响](#ServerErrors-minimizing-impact)
+ [提高操作感知](#ServerErrors-improving-operational-awareness)

## 调查内部服务器错误
<a name="ServerErrors-investigating"></a>

如果您在 DynamoDB 表中遇到内部服务器错误，请考虑以下选项：

1. **查看 AWS Health Dashboard。**

   要确定问题，第一步是查看 [AWS Service Health Dashboard](https://health.aws.amazon.com/health/status) 和您的 AWS Account Health Dashboard。这些控制面板提供了有关任何服务范围的问题、受影响的表、持续存在的问题以及问题解决后的根本原因的宝贵信息。

   通过查看这些控制面板中的详细信息，您可以更好地了解您正在使用的 AWS 服务的当前状态以及影响您账户的任何潜在问题。这些信息可能有助于您确定解决问题的后续步骤，并尽可能地减少对运营的任何干扰。

1. **联系 支持。**

   如果您在请求中观察到长时间、持续的错误，则可能表明服务存在问题。一般而言，如果您在过去 15 分钟内看到总体故障率为 1% 或更高，那么现在是将问题上报给 AWS Support 团队的适当时机。要了解更多信息，请参阅 [DynamoDB 服务水平协议](https://aws.amazon.com/dynamodb/sla/)。

   向 AWS Support 团队开立案例时，请提供以下详细信息以协助加快故障排除过程：
   + 受影响的 DDB；表或二级索引
   + 观察到错误的时段
   + DynamoDB 请求 ID，例如 `4KBNVRGD25RG1KEO9UT4V3FQDJVV4KQNSO5AEMVJF66Q9ASUAAJG`，可以在应用程序日志中找到。

   在支持案例中包含这些详细信息将有助于 AWS 团队了解问题并更快地解决问题。如果您没有请求 ID，仍应使用其它可用的详细信息记录案例。

## 尽可能地减少内部服务器错误的影响
<a name="ServerErrors-minimizing-impact"></a>

如果在使用 DynamoDB 时发生内部服务器错误，并要尽可能地减少这些错误对应用程序的影响，请考虑以下最佳实践：
+ 使用回退和重试 - DynamoDB 的默认 SDK 行为旨在为大多数应用程序在回退和重试策略方面找到适当的平衡。但是，您可以根据应用程序对停机的容忍度和性能要求来调整这些设置。了解有关回退和重试的更多信息，以了解如何微调这些重试设置。
+ 使用最终一致性读取 – 如果应用程序不需要强一致性读取，请考虑使用最终一致性读取。这些读取的成本较低，而且由于内部服务器错误导致出现暂时问题的可能性也较小，因为可以从任何可用的存储节点进行读取。有关更多信息，请参阅 [DynamoDB 读取一致性](HowItWorks.ReadConsistency.md)。

## 提高操作感知
<a name="ServerErrors-improving-operational-awareness"></a>

在当今的数字环境中，保持应用程序的高可用性和可靠性至关重要。其中一个关键方面是主动监控 DynamoDB 表和全局二级索引（GSI）中的内部服务器错误（ISE）。通过创建 CloudWatch 警报来监控这些错误，您可以获得更好的操作感知，并在潜在问题影响最终用户之前收到警报。这种方法与 AWS Well-Architected Framework 的卓越运营支柱保持一致，可确保 DynamoDB 工作负载在性能、安全性和可靠性方面得到优化。

**创建 CloudWatch 告警**

您应该在 DynamoDB 表上设置 CloudWatch 警报，以便在持续出现大量内部服务器错误时接收通知，而不是手动观察指标。这与 Well-Architected Framework 的卓越运营支柱息息相关，适用于 AWS 上的任何工作负载。请参阅[使用 DynamoDB Well-Architected Lens 优化您的 DynamoDB 工作负载](bp-wal.md)，详细了解如何精心构建 DynamoDB 表。

这些警报使用自定义指标数学来计算出 5 分钟时段内的失败请求百分比。建议的最佳实践是配置警报，以便在连续 3 个数据点突破 1% 阈值时进入 `ALARM` 状态，这意味着 15 分钟期间内共有 1% 的请求失败。

以下示例是一个 CloudFormation 模板，有助于您对表和表上的 GSI 创建 CloudWatch 警报。

```
AWSTemplateFormatVersion: "2010-09-09"
Description: Sample template for monitoring DynamoDB
Parameters:  
 DynamoDBProvisionedTableName: 
    Description: Name of DynamoDB Provisioned Table to create
    Type: String
    MinLength: 3
    MaxLength: 255
    ConstraintDescription : https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Limits.html#limits-naming-rules
  DynamoDBSNSEmail:
    Description : Email Address subscribed to newly created SNS Topic
    Type: String
    AllowedPattern: "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$"
    MinLength: 1
    MaxLength: 255

Resources:
  DynamoDBMonitoringSNSTopic:
    Type: AWS::SNS::Topic
    Properties: 
      DisplayName: DynamoDB Monitoring SNS Topic
      Subscription: 
        - Endpoint: !Ref DynamoDBSNSEmail
          Protocol: email
      TopicName: dynamodb-monitoring
      
  DynamoDBTableSystemErrorAlarm:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      AlarmName: 'DynamoDBTableSystemErrorAlarm'
      AlarmDescription: 'Alarm when system errors exceed 1% of total number of requests for 15 minutes'
      AlarmActions:
        - !Ref DynamoDBMonitoringSNSTopic
      Metrics:
        - Id: 'e1'
          Expression: 'm1/(m1+m2+m3)'
          Label: SystemErrorsOverTotalRequests
        - Id: 'm1'
          MetricStat:
            Metric:
              Namespace: 'AWS/DynamoDB'
              MetricName: 'SystemErrors'
              Dimensions:
                - Name: 'TableName'
                  Value: !Ref DynamoDBProvisionedTableName
            Period: 300
            Stat: 'SampleCount'
            Unit: 'Count'
          ReturnData: False
        - Id: 'm2'
          MetricStat:
            Metric:
              Namespace: 'AWS/DynamoDB'
              MetricName: 'ConsumedReadCapacityUnits'
              Dimensions:
                - Name: 'TableName'
                  Value: !Ref DynamoDBProvisionedTableName
            Period: 300
            Stat: 'SampleCount'
            Unit: 'Count'
          ReturnData: False
        - Id: 'm3'
          MetricStat:
            Metric:
              Namespace: 'AWS/DynamoDB'
              MetricName: 'ConsumedWriteCapacityUnits'
              Dimensions:
                - Name: 'TableName'
                  Value: !Ref DynamoDBProvisionedTableName
            Period: 300
            Stat: 'SampleCount'
            Unit: 'Count'
          ReturnData: False
      EvaluationPeriods: 3
      Threshold: 1.0
      ComparisonOperator: 'GreaterThanThreshold'
  DynamoDBGSISystemErrorAlarm:
    Type: 'AWS::CloudWatch::Alarm'
    Properties:
      AlarmName: 'DynamoDBGSISystemErrorAlarm'
      AlarmDescription: 'Alarm when GSI system errors exceed 2% of total number of requests for 15 minutes'
      AlarmActions:
        - !Ref DynamoDBMonitoringSNSTopic
      Metrics:
        - Id: 'e1'
          Expression: 'm1/(m1+m2+m3)'
          Label: GSISystemErrorsOverTotalRequests
        - Id: 'm1'
          MetricStat:
            Metric:
              Namespace: 'AWS/DynamoDB'
              MetricName: 'SystemErrors'
              Dimensions:
                - Name: 'TableName'
                  Value: !Ref DynamoDBProvisionedTableName
                - Name: 'GlobalSecondaryIndexName'
                  Value: !Join [ '-', [!Ref DynamoDBProvisionedTableName, 'gsi1'] ]
            Period: 300 
            Stat: 'SampleCount'
            Unit: 'Count'
          ReturnData: False
        - Id: 'm2'
          MetricStat:
            Metric:
              Namespace: 'AWS/DynamoDB'
              MetricName: 'ConsumedReadCapacityUnits'
              Dimensions:
                - Name: 'TableName'
                  Value: !Ref DynamoDBProvisionedTableName
                - Name: 'GlobalSecondaryIndexName'
                  Value: !Join [ '-', [!Ref DynamoDBProvisionedTableName, 'gsi1'] ]
            Period: 300 
            Stat: 'SampleCount'
            Unit: 'Count'
          ReturnData: False
        - Id: 'm3'
          MetricStat:
            Metric:
              Namespace: 'AWS/DynamoDB'
              MetricName: 'ConsumedWriteCapacityUnits'
              Dimensions:
                - Name: 'TableName'
                  Value: !Ref DynamoDBProvisionedTableName
                - Name: 'GlobalSecondaryIndexName'
                  Value: !Join [ '-', [!Ref DynamoDBProvisionedTableName, 'gsi1'] ]
            Period: 300 
            Stat: 'SampleCount'
            Unit: 'Count'
          ReturnData: False
      EvaluationPeriods: 3
      Threshold: 1.0
      ComparisonOperator: 'GreaterThanThreshold'
```