为什么我在使用 Kinesis Data Firehose 时遇到了数据传输故障?

上次更新时间:2020 年 6 月 16 日

我正在尝试将数据从 Amazon Kinesis Data Firehose 发送到我的 Amazon Elasticsearch Service (Amazon ES) 域。为什么我遇到了数据传输故障?

简短描述

Amazon Kinesis Data Firehose 和 Amazon ES 之间的数据传输失败可能是以下原因造成的:

  • 无效的传输目标
  • 无传入数据
  • 禁用了 Kinesis Data Firehose 日志
  • 缺少适当权限
  • AWS Lambda 函数调用问题
  • Amazon ES 域运行状况问题

解决方法

无效的传输目标

请确认您已指定了有效的 Kinesis Data Firehose 传输目标,并且您使用的是正确的 ARN。您可以通过查看 Amazon CloudWatch 中的 DeliveryToElasticsearch.Success 指标来检查传输是否成功。DeliveryToElasticsearch.Success 指标的值为零即可确认传输失败。有关 DeliveryToElasticsearch.Success 指标的更多信息,请参阅数据传输 CloudWatch 指标中的传输到 Amazon ES

无传入数据

监控 IncomingRecordsIncomingBytes 指标以确认 Kinesis Data Firehose 有传入数据。这些指标的值为零则意味着没有访问 Kinesis Data Firehose 的记录。有关 IncomingRecordsIncomingBytes 指标的更多信息,请参阅数据提取指标中的通过直接 PUT 提取数据

如果传输流使用 Amazon Kinesis 数据流作为源,则检查 Kinesis 数据流的 IncomingRecordsIncomingBytes 指标。这两个指标可指示是否存在传入数据。值为零可确认没有访问流式处理服务的记录。

如果有数据到达 Kinesis 数据流,则 DataReadFromKinesisStream.BytesDataReadFromKinesisStream.Records 指标可指示数据是否从 Kinesis 数据流传输到 Kinesis Data Firehose。有关数据指标的更多信息,请参阅通过 Kinesis 数据流提取数据。值为零可能表示传输到 Amazon ES 失败,而非 Kinesis 数据流与 Kinesis Data Firehose 之间的传输失败。

您还可以检查是否能够正确地调用 Kinesis Data Firehose 的 PutRecordPutRecordBatch API 调用。如果您未看到任何传入数据流指标,请检查执行 PUT 操作的创建器。有关故障排除创建器应用程序问题的更多信息,请参阅排查 Amazon Kinesis 数据流创建器的故障

禁用了 Kinesis Data Firehose 日志

请确保为 Kinesis Data Firehose 启用了日志记录。否则,错误日志会导致传输失败。然后,检查 CloudWatch Logs 中的 /aws/kinesisfirehose/delivery-stream-name 日志组名称。

在 Kinesis Data Firehose 角色中,需要以下权限:

"Action":[
               "logs:PutLogEvents"
              ]
"Resource":[
                "arn:aws:logs:region:account-id:log-group:log-group-name:log-stream:log-stream-name"
                   ]

验证您已授予 Kinesis Data Firehose 访问公有 Amazon ES 目标的权限。如果您使用数据转换功能,则您还必须授予访问 AWS Lambda 的权限。

缺少适当权限

根据 Kinesis Data Firehose 的配置,有几个必需权限。

要将记录传输到 Amazon Simple Storage Service (Amazon S3) 存储桶,需要以下权限:

{      
            "Effect": "Allow",      
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:PutObject"
            ],      
            "Resource": [        
                "arn:aws:s3:::bucket-name",
                "arn:aws:s3:::bucket-name/*"            
            ]    
        }

注意:要使用此策略,必须存在 Amazon S3 存储桶资源。

如果您的 Kinesis Data Firehose 进行了静态加密,则需要以下权限:

{
           "Effect": "Allow",
           "Action": [
               "kms:Decrypt",
               "kms:GenerateDataKey"
           ],
           "Resource": [
               "arn:aws:kms:region:account-id:key/key-id"           
           ],
           "Condition": {
               "StringEquals": {
                   "kms:ViaService": "s3.region.amazonaws.com"
               },
               "StringLike": {
                   "kms:EncryptionContext:aws:s3:arn": "arn:aws:s3:::bucket-name/prefix*"
               }
           }
        }

要授予 Amazon ES 访问权限,您可以像本示例中那样更新策略:

 {
           "Effect": "Allow",
           "Action": [
               "es:DescribeElasticsearchDomain",
               "es:DescribeElasticsearchDomains",
               "es:DescribeElasticsearchDomainConfig",
               "es:ESHttpPost",
               "es:ESHttpPut"
           ],
          "Resource": [
              "arn:aws:es:region:account-id:domain/domain-name",
              "arn:aws:es:region:account-id:domain/domain-name/*"
          ]
       },
       {
          "Effect": "Allow",
          "Action": [
              "es:ESHttpGet"
          ],
          "Resource": [
              "arn:aws:es:region:account-id:domain/domain-name/_all/_settings",
              "arn:aws:es:region:account-id:domain/domain-name/_cluster/stats",
              "arn:aws:es:region:account-id:domain/domain-name/index-name*/_mapping/type-name",
              "arn:aws:es:region:account-id:domain/domain-name/_nodes",
              "arn:aws:es:region:account-id:domain/domain-name/_nodes/stats",
              "arn:aws:es:region:account-id:domain/domain-name/_nodes/*/stats",
              "arn:aws:es:region:account-id:domain/domain-name/_stats",
              "arn:aws:es:region:account-id:domain/domain-name/index-name*/_stats"
          ]
       }

如果您使用 Kinesis 数据流作为源,则像本示例中那样更新您的权限:

{
          "Effect": "Allow",
          "Action": [
              "kinesis:DescribeStream",
              "kinesis:GetShardIterator",
              "kinesis:GetRecords",
              "kinesis:ListShards"
          ],
          "Resource": "arn:aws:kinesis:region:account-id:stream/stream-name"
       }

要配置 Kinesis Data Firehose 以进行数据转换,您可以像下面那样更新策略:

{
          "Effect": "Allow", 
          "Action": [
              "lambda:InvokeFunction", 
              "lambda:GetFunctionConfiguration" 
          ],
          "Resource": [
              "arn:aws:lambda:region:account-id:function:function-name:function-version"
          ]
       }

AWS Lambda 函数调用问题

检查 Kinesis Data Firehose ExecuteProcessing.Success and Errors 指标是否为 true,它表示 Kinesis Data Firehose 已调用您的函数。如果 Kinesis Data Firehose 尚未尝试调用您的 Lambda 函数,则检查调用时间以查看它是否超过了超时参数。您的 Lambda 函数可能需要更高的超时值或需要更多内存才能完成。有关调用指标的更多信息,请参阅使用调用指标

要确定 Kinesis Data Firehose 未调用 Lambda 函数的原因,检查 /aws/lambda/lamdba-function-name 的 Amazon CloudWatch Logs 组。如果数据转换失败,则失败的记录会传输到 S3 存储桶中的 processing-failed 文件夹作为备份。S3 存储桶中的记录还包含针对已失败调用的错误消息。有关解决 Lambda 调用失败的更多信息,请参阅数据转换失败处理

Amazon ES 域运行状况问题

检查以下指标以确认 Amazon ES 处于良好运行状况:

  • CPU 利用率:如果此指标始终不高,则数据节点可能无法响应任何请求或传入数据。您可能需要扩展您的集群。
  • JVM 内存压力:如果 JVM 内存压力始终高于 80%,则集群可能正在触发内存断路器异常。这些异常可能会阻止编制数据索引。
  • ClusterWriteBlockException:这是当域处于高 JVM 内存压力时或需要更多存储空间时发生的索引编制阻止。如果一个数据节点没有空间,则无法为任何新数据编制索引。有关排查 Amazon ES 问题的更多信息,请参阅 Amazon Elasticsearch Service 故障排除

这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助?