Amazon Data FirehoseのLambda変換で、失敗・破棄したレコードがどこへ行くのか確かめてみた

Amazon Data FirehoseのLambda変換で、失敗・破棄したレコードがどこへ行くのか確かめてみた

Amazon Data FirehoseのLambda変換で、失敗したレコードがS3のどこに、どんな形で残るのかを実際に検証してみました。正常なレコード・破棄・処理失敗・例外の4パターンを意図的に作り分けて、CloudFormationで構築した環境で試します。
2026.11.02

はじめに

おはようございます〜
クラウド事業統括本部/プロフェッショナルサービス事業本部/運用イノベーション部の三ツ口寛太です(╹◡╹)

今回は、Amazon Data FirehoseのLambda変換で、失敗・破棄したレコードがどこへ行くのかを、実際にレコードを送って確かめてみます🧑‍💻

Amazon Data Firehose(旧 Kinesis Data Firehose。2024年2月に名前が変わりました)には、S3などへ届ける前に、Lambdaでレコードを加工できる「データ変換」があります。

Lambdaは、レコードごとに Ok/Dropped/ProcessingFailed のどれかを返せます。ただ、返したレコードが実際にS3のどこに、どんな形で残るのかは、ドキュメントを読んだだけでは分かりにくいです。

最近、試験勉強をしていて、「使ってみたいな」と思っていたサービスでもあるので、実際に触って確かめてみることにしました!
わざと失敗するレコードを混ぜて送り、S3の中身を確認します💻

この記事で分かること

  • 正常なレコードが、S3にどんな形で届くか
  • Dropped と ProcessingFailed で、S3での扱いがどう違うか
  • 失敗したレコードのファイルに、何が書かれているか
  • Lambdaが例外で落ちたとき、同じバッチの正常なレコードがどうなるか。何回リトライされるか
  • 送ってから、S3に届くまでにかかった時間

こだわりポイント

  • 1つのLambdaで、レコードの中身に応じて 成功/破棄/変換失敗/例外 の4パターンを意図的に作り分ける
  • S3の出力先を transformed/(変換後)、errors/(失敗)、source/(変換前のバックアップ)に分けて、どのレコードがどこへ行ったかを見分けやすくする
  • CloudFormation1枚で構築。操作は AWS CloudShell だけで完結(CLIのインストールや認証設定は不要)
  • 送信時刻と配信時刻を毎回記録して、届くまでの時間も実測する

先に結論

  • 正常なレコードは、Lambdaで変換した形のまま、改行区切り(JSON Lines)で transformed/ に届いた
  • Dropped のレコードは、transformed/ にも errors/ にも出なかった。ただし、バックアップを有効にしていると source/ には残った
  • ProcessingFailed のレコードは、errors/processing-failed/ に届いた。ファイルには元のデータが Base64(rawData) で残り、errorCode は Lambda.ProcessingFailedStatus だった
  • Lambdaが例外で落ちると、同じバッチの正常なレコードも巻き込まれて errors/ に入った(errorCode は Lambda.FunctionError)。Lambdaは4回(初回+リトライ3回)呼ばれた
  • 送信からS3に届くまでは、約80秒〜約2分20秒。Lambdaのバッファ(60秒)とS3のバッファ(60秒)が効いていた

今回の構成

  • クライアント(CloudShellから aws firehose put-record-batch)→ Firehose(Direct PUT)→ Lambda(変換)→ S3
  • 変換後は transformed/、失敗は errors/、変換前のバックアップは source/ に出力
  • CloudWatch Logsに、Lambdaのログと、Firehoseの配信ログを出力

構築されるリソースと主な設定値

リソース 設定値 設定の意図
S3バケット パブリックアクセスブロック、SSE-S3 配信先。変換後・失敗・バックアップを、プレフィックスで分けて置く
Lambda(変換) Python 3.12、128MB、タイムアウト60秒、インラインコード レコードの中身で、戻り値のパターンを作り分ける
Firehose Direct PUT、S3宛先、バッファ 1MB/60秒、圧縮なし 圧縮しないほうがS3上でそのまま読める。60秒は既定値
Lambdaプロセッサ バッファ 1MB/60秒、NumberOfRetries は 3 Lambdaに渡すまでのバッファとリトライ回数を明示する
出力先プレフィックス 正常:transformed/、失敗:errors/!{firehose:error-output-type}/、バックアップ:source/ どのレコードがどこに行ったかを見分けやすくする
IAMロール(Firehose) S3書き込み、lambda:InvokeFunction、ログ出力 必要な権限に絞る
CloudWatch Logs Lambda用、Firehose配信用(保持7日) 呼び出し回数と例外の確認に使う

Lambdaの動き(入力レコード → 戻り値)

入力(JSON) Lambdaの戻り値 備考
{"id":1,"user":"a","amount":1000} Ok amount_with_tax(税込金額)と processed_at を足し、末尾に改行を付ける
{"id":14,"action":"drop"} Dropped 意図的な破棄
{"id":15,"action":"fail"} ProcessingFailed 意図的な失敗
this is not json ProcessingFailed JSONとして読めない
{"id":22,"action":"raise"} (例外を投げる) バッチ全体が失敗する。リトライの確認用

テンプレート

テンプレート全文(firehose-lambda-transform.yamlの中身)
AWSTemplateFormatVersion: "2010-09-09"
Description: Amazon Data Firehose + Lambda data transformation lab (failed record behavior)

Parameters:
  ProjectName:
    Type: String
    Default: fh-lab
    AllowedPattern: "^[a-z0-9][a-z0-9-]{1,18}[a-z0-9]$"
    Description: Resource name prefix (lowercase letters, digits, hyphens, 3-20 chars)
  BackupMode:
    Type: String
    Default: Enabled
    AllowedValues:
      - Enabled
      - Disabled
    Description: Back up all source records to S3 (source/ prefix)
  LambdaRetries:
    Type: Number
    Default: 3
    MinValue: 0
    MaxValue: 300
    Description: Firehose retries when the Lambda invocation itself fails (NumberOfRetries)

Conditions:
  BackupEnabled: !Equals [!Ref BackupMode, Enabled]

Resources:
  # ---------- 配信先S3 ----------
  DestBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${ProjectName}-${AWS::AccountId}-${AWS::Region}
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256

  # ---------- 変換用Lambda ----------
  TransformLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/lambda/${ProjectName}-transform
      RetentionInDays: 7

  TransformRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: write-logs
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: !GetAtt TransformLogGroup.Arn

  TransformFunction:
    Type: AWS::Lambda::Function
    DependsOn: TransformLogGroup
    Properties:
      FunctionName: !Sub ${ProjectName}-transform
      Runtime: python3.12
      Handler: index.handler
      Role: !GetAtt TransformRole.Arn
      Timeout: 60
      MemorySize: 128
      Code:
        ZipFile: |
          import base64
          import json
          from datetime import datetime, timezone

          TAX_RATE = 1.10

          def result(record_id, status, data):
              return {"recordId": record_id, "result": status, "data": data}

          def handler(event, context):
              out = []
              counts = {"Ok": 0, "Dropped": 0, "ProcessingFailed": 0}
              for r in event["records"]:
                  rid = r["recordId"]
                  raw = base64.b64decode(r["data"])

                  # JSONとして読めないレコードは変換失敗にする
                  try:
                      body = json.loads(raw)
                  except ValueError:
                      body = None
                  if not isinstance(body, dict):
                      out.append(result(rid, "ProcessingFailed", r["data"]))
                      counts["ProcessingFailed"] += 1
                      continue

                  action = body.get("action")

                  # Lambda自体が例外で落ちるケース(バッチ全体が失敗する)
                  if action == "raise":
                      raise RuntimeError("intentional failure for lab")

                  if action == "drop":
                      out.append(result(rid, "Dropped", r["data"]))
                      counts["Dropped"] += 1
                      continue

                  if action == "fail":
                      out.append(result(rid, "ProcessingFailed", r["data"]))
                      counts["ProcessingFailed"] += 1
                      continue

                  # 正常系:税込金額と処理時刻を足す。末尾に改行を付けてJSON Linesにする
                  body["amount_with_tax"] = round(body.get("amount", 0) * TAX_RATE)
                  body["processed_at"] = datetime.now(timezone.utc).isoformat()
                  encoded = base64.b64encode(
                      (json.dumps(body, ensure_ascii=False) + "\n").encode("utf-8")
                  ).decode("utf-8")
                  out.append(result(rid, "Ok", encoded))
                  counts["Ok"] += 1

              print(json.dumps({"received": len(event["records"]), **counts}))
              return {"records": out}

  # ---------- Firehose ----------
  FirehoseLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/kinesisfirehose/${ProjectName}
      RetentionInDays: 7

  FirehoseLogStream:
    Type: AWS::Logs::LogStream
    Properties:
      LogGroupName: !Ref FirehoseLogGroup
      LogStreamName: DestinationDelivery

  FirehoseRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: firehose.amazonaws.com
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                sts:ExternalId: !Ref AWS::AccountId
      Policies:
        - PolicyName: deliver-to-s3-and-invoke-lambda
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:AbortMultipartUpload
                  - s3:GetBucketLocation
                  - s3:GetObject
                  - s3:ListBucket
                  - s3:ListBucketMultipartUploads
                  - s3:PutObject
                Resource:
                  - !GetAtt DestBucket.Arn
                  - !Sub ${DestBucket.Arn}/*
              - Effect: Allow
                Action:
                  - lambda:InvokeFunction
                  - lambda:GetFunctionConfiguration
                Resource: !GetAtt TransformFunction.Arn
              - Effect: Allow
                Action: logs:PutLogEvents
                Resource: !GetAtt FirehoseLogGroup.Arn

  DeliveryStream:
    Type: AWS::KinesisFirehose::DeliveryStream
    Properties:
      DeliveryStreamName: !Sub ${ProjectName}-stream
      DeliveryStreamType: DirectPut
      ExtendedS3DestinationConfiguration:
        BucketARN: !GetAtt DestBucket.Arn
        RoleARN: !GetAtt FirehoseRole.Arn
        Prefix: transformed/!{timestamp:yyyy/MM/dd/HH}/
        ErrorOutputPrefix: errors/!{firehose:error-output-type}/!{timestamp:yyyy/MM/dd/HH}/
        BufferingHints:
          IntervalInSeconds: 60
          SizeInMBs: 1
        CompressionFormat: UNCOMPRESSED
        CloudWatchLoggingOptions:
          Enabled: true
          LogGroupName: !Ref FirehoseLogGroup
          LogStreamName: !Ref FirehoseLogStream
        ProcessingConfiguration:
          Enabled: true
          Processors:
            - Type: Lambda
              Parameters:
                - ParameterName: LambdaArn
                  ParameterValue: !GetAtt TransformFunction.Arn
                - ParameterName: NumberOfRetries
                  ParameterValue: !Ref LambdaRetries
                - ParameterName: BufferSizeInMBs
                  ParameterValue: "1"
                - ParameterName: BufferIntervalInSeconds
                  ParameterValue: "60"
        S3BackupMode: !Ref BackupMode
        S3BackupConfiguration: !If
          - BackupEnabled
          - BucketARN: !GetAtt DestBucket.Arn
            RoleARN: !GetAtt FirehoseRole.Arn
            Prefix: source/!{timestamp:yyyy/MM/dd/HH}/
            ErrorOutputPrefix: backup-errors/!{firehose:error-output-type}/!{timestamp:yyyy/MM/dd/HH}/
            BufferingHints:
              IntervalInSeconds: 60
              SizeInMBs: 1
            CompressionFormat: UNCOMPRESSED
          - !Ref AWS::NoValue

Outputs:
  DeliveryStreamName:
    Value: !Ref DeliveryStream
  BucketName:
    Value: !Ref DestBucket
  FunctionName:
    Value: !Ref TransformFunction
  FirehoseLogGroupName:
    Value: !Ref FirehoseLogGroup

重要な部分の解説

1. Lambdaの戻り値は、recordId・result・data の3つ

def result(record_id, status, data):
    return {"recordId": record_id, "result": status, "data": data}

result は Ok/Dropped/ProcessingFailed の3種類です。recordId は、入力と同じ値を返す必要があります。正常なレコードの末尾に改行(\n)を付けているのは、Firehoseがレコードをそのままつなげて書くためです(付けないと、S3上で1行にくっついてしまいます)。

2. 失敗の出力先は ErrorOutputPrefix で決まる

ErrorOutputPrefix: errors/!{firehose:error-output-type}/!{timestamp:yyyy/MM/dd/HH}/

!{firehose:error-output-type} の部分に、失敗の種類(今回は processing-failed)が入ります。ErrorOutputPrefix に式を書くときは、これを1つ以上含める必要があります。また、バックアップ(S3BackupConfiguration)を指定すると、ErrorOutputPrefix の既定値は用意されないので、自分で書きます。

3. リトライとバッファは、Lambdaプロセッサのパラメータで指定する

- ParameterName: NumberOfRetries
  ParameterValue: !Ref LambdaRetries
- ParameterName: BufferSizeInMBs
  ParameterValue: "1"
- ParameterName: BufferIntervalInSeconds
  ParameterValue: "60"

NumberOfRetries は、Lambdaの呼び出し自体が失敗したときのリトライ回数です(既定は3)。

やってみた

1. デプロイ

CloudFormationのコンソールからテンプレートをアップロードして、スタックを作成します。
デプロイ完了するまでは夕飯何にするか考えましょう。🍚

無事に完了しました!

念の為Firehoseの設定値を確認します。

想定通り作成できています!

2. CloudShellの準備

コンソールの右上で東京リージョンを確認し、CloudShell(>_)を開きます。次の「共通設定」を貼り付けます(BUCKET はスタックの出力タブの値)。

STREAM=fh-lab-stream
BUCKET=fh-lab-<アカウントID>-ap-northeast-1
aws configure set cli_binary_format raw-in-base64-out

# S3の中身を、ファイルごとに全部表示する小さなコマンド
show() {
  for k in $(aws s3 ls s3://$BUCKET/$1 --recursive | awk '{print $4}'); do
    echo "--- $k"
    aws s3 cp s3://$BUCKET/$k -
    echo
  done
}

3. 検証1:正常なレコードだけ送る

3件の正常なレコードを送ります。

cat > records1.json <<'EOF'
[
  {"Data": "{\"id\":1,\"user\":\"a\",\"amount\":1000}"},
  {"Data": "{\"id\":2,\"user\":\"b\",\"amount\":2500}"},
  {"Data": "{\"id\":3,\"user\":\"c\",\"amount\":300}"}
]
EOF
date
aws firehose put-record-batch --delivery-stream-name $STREAM --records file://records1.json

FailedPutCount が 0(3件とも受け付けられた)ことを確認して、1〜2分待ちます。

transformed/ の中身です。

{"id": 1, "user": "a", "amount": 1000, "amount_with_tax": 1100, "processed_at": "2026-11-02T08:06:15.658179+00:00"}
{"id": 2, "user": "b", "amount": 2500, "amount_with_tax": 2750, "processed_at": "2026-11-02T08:06:15.658275+00:00"}
{"id": 3, "user": "c", "amount": 300, "amount_with_tax": 330, "processed_at": "2026-11-02T08:06:15.658297+00:00"}

1行ごとに改行された、JSON Linesの形になっています。税込金額も、計算どおり(1000→1100)です。

一方、source/(変換前のバックアップ)は、改行なしで1行につながっていました。

{"id":1,"user":"a","amount":1000}{"id":2,"user":"b","amount":2500}{"id":3,"user":"c","amount":300}

errors/ には何も出ていません。

届くまでの時間です(UTC)。

時刻 できごと 送信からの経過
08:05:09 送信 —
08:06:15 Lambdaが処理 約66秒
08:06:16 source/ に配信 約67秒
08:06:29 transformed/ に配信 約80秒

4. 検証2:成功・破棄・変換失敗・不正なJSONを混ぜる

6件を1バッチで送ります。

cat > records2.json <<'EOF'
[
  {"Data": "{\"id\":11,\"user\":\"a\",\"amount\":1000}"},
  {"Data": "{\"id\":12,\"user\":\"b\",\"amount\":2000}"},
  {"Data": "{\"id\":13,\"user\":\"c\",\"amount\":3000}"},
  {"Data": "{\"id\":14,\"action\":\"drop\"}"},
  {"Data": "{\"id\":15,\"action\":\"fail\"}"},
  {"Data": "this is not json"}
]
EOF
date
aws firehose put-record-batch --delivery-stream-name $STREAM --records file://records2.json

transformed/ には、正常な3件(id 11〜13)だけが届きました。drop と fail、不正なJSONは出ていません。

errors/processing-failed/ には、2件が入っていました。

{"rawData":"eyJpZCI6MTUsImFjdGlvbiI6ImZhaWwifQ==","errorCode":"Lambda.ProcessingFailedStatus","errorMessage":"ProcessingFailed status set for record","attemptsMade":1,"arrivalTimestamp":1793606974810,"attemptEndingTimestamp":1793607035036,"lambdaARN":"arn:aws:lambda:ap-northeast-1:<アカウントID>:function:fh-lab-transform"}
{"rawData":"dGhpcyBpcyBub3QganNvbg==","errorCode":"Lambda.ProcessingFailedStatus","errorMessage":"ProcessingFailed status set for record","attemptsMade":1,"arrivalTimestamp":1793606974810,"attemptEndingTimestamp":1793607035036,"lambdaARN":"arn:aws:lambda:ap-northeast-1:<アカウントID>:function:fh-lab-transform"}
項目 内容
rawData 元のデータをBase64にしたもの。デコードすると、{"id":15,"action":"fail"} と this is not json(送ったもの)になる
errorCode Lambda.ProcessingFailedStatus
errorMessage ProcessingFailed status set for record
attemptsMade 1
arrivalTimestamp/attemptEndingTimestamp Firehoseへの到着時刻と、処理を終えた時刻(ミリ秒)。差は約60秒で、Lambdaのバッファ時間と合う

fail を返したレコードも、不正なJSONも、errorCode は同じ値でした。失敗の原因までは、このファイルからは区別できません。

そして気になっていた、Dropped(id 14)の行き先です。transformed/ にも errors/ にも出ませんでしたが、source/ には残っていました。バックアップを有効にしていると、Dropped を含めた全6件のソースが保存されます。

{"id":11,"user":"a","amount":1000}{"id":12,"user":"b","amount":2000}{"id":13,"user":"c","amount":3000}{"id":14,"action":"drop"}{"id":15,"action":"fail"}this is not json

Lambdaのログにも、件数が出ていました。

{"received": 3, "Ok": 3, "Dropped": 0, "ProcessingFailed": 0}
{"received": 6, "Ok": 3, "Dropped": 1, "ProcessingFailed": 2}

届くまでの時間です(UTC)。

時刻 できごと 送信からの経過
08:09:32 送信 —
08:10:35 Lambdaが処理 約63秒
08:10:40 source/ に配信 約68秒
08:10:48 errors/ に配信 約76秒
08:11:38 transformed/ に配信 約126秒

検証1は約80秒で届いたのに、今回は約126秒かかりました。

下のS3の画像は、ファイルの更新日時が**日本時間(JST、UTC+9)**で表示されています(上の表のUTCに9時間を足した時刻です。たとえば 08:10:48 UTC は 17:10:48 JST)。

5. 検証3:Lambdaが例外で落ちる

id 22 だけ例外を出すレコードを、正常な2件と同じバッチで送ります。

cat > records3.json <<'EOF'
[
  {"Data": "{\"id\":21,\"user\":\"a\",\"amount\":1000}"},
  {"Data": "{\"id\":22,\"action\":\"raise\"}"},
  {"Data": "{\"id\":23,\"user\":\"c\",\"amount\":3000}"}
]
EOF
date
aws firehose put-record-batch --delivery-stream-name $STREAM --records file://records3.json

結果は、3件すべてが errors/processing-failed/ に入りました。例外を出したのは id 22 だけなのに、正常な id 21 と 23 も巻き込まれて、transformed/ には出ませんでした。

{"rawData":"eyJpZCI6MjEsInVzZXIiOiJhIiwiYW1vdW50IjoxMDAwfQ==","errorCode":"Lambda.FunctionError","errorMessage":"The Lambda function was successfully invoked but it returned an error result.","attemptsMade":4,"arrivalTimestamp":1793607247630,"attemptEndingTimestamp":1793607322696,"lambdaARN":"arn:aws:lambda:ap-northeast-1:<アカウントID>:function:fh-lab-transform"}
  • errorCode は、ProcessingFailed のときと違う Lambda.FunctionError
  • attemptsMade は 4(初回+リトライ3回)
  • errorMessage にLambdaの例外の内容は入っていない(内容はLambdaのログで見る)

Lambdaの呼び出し回数は、CloudWatch Logsの START RequestId を数えて確認しました。

08:15:07  初回
08:15:09  リトライ1(約2秒後)
08:15:14  リトライ2(約5秒後)
08:15:22  リトライ3(約8秒後)

呼び出しの間隔は、だんだん長くなっていました。最後の呼び出し(08:15:22)は、失敗ファイルの attemptEndingTimestamp(08:15:22.696)と一致しています。

例外の内容は、ログにこのように出ていました。

[ERROR] RuntimeError: intentional failure for lab
Traceback (most recent call last):
  File "/var/task/index.py", line 33, in handler
    raise RuntimeError("intentional failure for lab")

届くまでの時間です(UTC)。

時刻 できごと 送信からの経過
08:14:05 送信 —
08:15:07 Lambda 初回呼び出し 約62秒
08:15:22 最終試行が終了 約77秒
08:16:24 errors/ に配信 約139秒

6. 後片付け

CloudShellでバケットを空にしてから、スタックを削除しました。

aws s3 rm s3://$BUCKET/ --recursive

結果のまとめ

検証 送ったもの transformed/ errors/ source/ 配信までの時間
1 正常3 3行 なし 3件(連結) 約80秒
2 正常3、drop 1、fail 1、不正JSON 1 正常3行のみ 2件(Lambda.ProcessingFailedStatus) 6件(drop含む) 約126秒
3 正常2、例外1(同一バッチ) なし 3件すべて(Lambda.FunctionError、4回試行) 3件 約139秒

注意点

  • 各検証は1回ずつの実測です。届くまでの時間は、バッファの設定や、そのときの状況で変わります(検証1と2で、約80秒と約126秒の差が出ました)。
  • バックアップ(S3BackupMode)を無効にした場合の挙動は、今回は検証していません(有効のときの結果から、Dropped のデータが残るのはバックアップのおかげだと考えられます)。
  • 今回は1つのバッチに失敗を混ぜました。バッチの分け方や大きさで、巻き込まれる範囲は変わります。
  • errors/ と source/ には、元のデータがそのまま残ります(rawData はBase64なので、デコードすれば読めます)。個人情報などを流す場合は、これらの置き場所の権限や保存期間に注意が必要です。
  • 検証用の構成です。本番では、失敗したレコードを再処理する仕組みや、アラームなども考えてください。

まとめ

  • Lambda変換で返した結果ごとに、S3での行き先を実測しました。
  • Ok は transformed/ へ、ProcessingFailed は errors/processing-failed/ へ、Dropped はどこにも配信されません。ただし、バックアップを有効にしていると、Dropped を含む全ソースが source/ に残りました。
  • 失敗ファイルには、元のデータが Base64(rawData) で残るので、あとから中身を確認して再処理する材料になります。
  • Lambdaが例外で落ちると、同じバッチの正常なレコードも巻き込まれて、すべて errors/ に入りました。Lambdaは、初回+リトライ3回の4回呼ばれました。
  • なので、Lambdaの処理は、個々のレコードで try/except して、失敗を ProcessingFailed として返す形にしておくのが良さそうです。そうすれば、1件の不具合で、同じバッチの正常なレコードまで失われる事態を避けられます。
  • 配信には、Lambdaのバッファ(60秒)とS3のバッファ(60秒)が効いて、約80秒〜約2分20秒かかりました。リアルタイム性が必要なときは、バッファの設定を見直す必要があります。

この記事が、FirehoseのLambda変換で、失敗レコードの扱いを設計するときの参考になれば幸いです!

最後に

本日の写真はこちら!(ででん)

こちらは、ミニチュアアートを手がけられている田中達也さんの、ミニチュア展(横浜)に行った時の写真です!
これは緑のスプーンを木に見立てて、森の中を散策する狩人の作品ですかね。
発想力が豊かで、驚かされるような作品にたくさん出会えました。機会があれば是非足を運んでみてください!

最後まで見てくださりありがとうございました〜

参考

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事