web-dev-qa-db-ja.com

DynamoDBストリームはどのようにレコードをシャードに配信しますか?

私の目標は、DynamoDBストリームによって公開されたレコードが「正しい」順序で処理されるようにすることです。私のテーブルには顧客のイベントが含まれています。ハッシュキーはイベントID、範囲キーはタイムスタンプです。 「正しい」注文とは、同じ顧客IDのイベントが順番に処理されることを意味します。異なる顧客IDを並行して処理できます。

Lambda関数を介してストリームを消費しています。消費者はシャードごとに自動的に生成されます。したがって、ランタイムがストリームを分割することを決定した場合、消費は並行して発生し(これが正しくなると)、CustomerCreated(たとえば)の前にCustomerAddressChangedイベントを処理するリスクが発生します。

docs は、シャーディングに影響を与える方法がないことを意味します。しかし、彼らはそのようにはっきり言っていません。たとえば、範囲キーに顧客IDとタイムスタンプの組み合わせを使用する方法はありますか?

11
EagleBeak

シャーディングがテーブルキーによって決定されるという仮定は正しいようです。私の解決策は、ハッシュキーとして顧客IDを使用し、範囲キーとしてタイムスタンプ(またはイベントID)を使用することです。

このAWSブログ のコメント:

単一の主キーに対して行われた一連の変更の相対的な順序は、シャード内に保持されます。さらに、特定のキーは、特定の時点でアクティブな兄弟シャードのセットの多くても1つに存在します。その結果、コードは、アイテムへの変更を正確に追跡するために、シャード内のストリームレコードを単純に処理できます。

このスライド 確認します。 DynamoDBのドキュメントで明示的にそのように言ってほしい...

5
EagleBeak

AWSサポートから返事がありました。 @ EagleBeak シャードにマッピングされているパーティションに関する仮定を確認するようです。または、私が理解しているように、パーティションはシャードツリーにマップされています。

私の質問は、TTL期限切れによるREMOVEイベントに関するものでしたが、他のすべてのタイプのアクションにも適用されます。

  1. プライマリパーティションキーごとにシャードが作成されますか?同じパーティションにアイテムが多すぎる場合、シャードは子に分割されますか?

    DynamoDBテーブルのパーティションごとにシャードが作成されます。同じパーティション内のアイテムが多すぎるためにパーティション分割が必要な場合、シャードも子に分割されます。アプリケーションが複数のシャードのレコードを並行して処理できるように、シャードはその親テーブルでの高レベルの書き込みアクティビティに応答して分割される場合があります。 - https://aws.Amazon.com/blogs/database/dynamodb-streams-use-cases-and-design-patterns/

  2. 削除された100個のアイテムは、すべて同じパーティションキーを持つ場合、1つのシャードに配置されますか?

    100アイテムすべてが同じパーティションキー値(ただし、ソートキー値は異なる)であると想定すると、それらは同じパーティションに格納されます。したがって、それらは同じパーティションから削除され、同じシャードに配置されます。

  3. 「AWS Lambda関数に送信されるレコードは厳密にシリアル化されている」ので、TTLの場合、このシリアル化はどのように機能しますか?分割/ソートキー、TTL有効期限など)によって確立されたシャード内の順序ですか?

    DynamoDBストリームは、DynamoDBテーブル内の項目レベルの変更の時系列シーケンスをキャプチャします。この時間順のシーケンスは、シャードレベルごとに保持されます。つまり、シャード内の順序は、アイテムが作成、更新、または削除された順序に基づいて確立されます。 - https://docs.aws.Amazon.com/amazondynamodb/latest/developerguide/Streams.html

2
cortopy

Dynamodbストリームは、断片にグループ化されたストリームレコードで構成されます。シャードは、dynamodbテーブルへの多数の書き込みに応答して子シャードを生成できます。したがって、親シャードと、場合によっては複数の子シャードを持つことができます。 アプリケーションが正しい順序でレコードを処理するようにするには、親シャードを常に子シャードの前に処理する必要があります。これについては、 ドキュメント

残念ながら、AWS Lambda関数に送信されたDynamoDB Streamsレコードはシャードごとに厳密にシリアル化され、異なるシャード間でのレコードの順序は保証されません

AWS Lamda FAQから:

Q:AWS LambdaはAmazon KinesisストリームとAmazon DynamoDBストリームからのデータをどのように処理しますか?

AWS Lambda関数に送信されるAmazon KinesisおよびDynamoDB Streamsレコードは、シャードごとに厳密にシリアル化されます。つまり、同じシャードに2つのレコードを配置した場合、Lambdaは、2番目のレコードで呼び出される前に、最初のレコードでLambda関数が正常に呼び出されることを保証します。 1つのレコードの呼び出しがタイムアウトするか、制限されるか、その他のエラーが発生した場合、Lambdaは成功する(またはレコードが24時間の有効期限に達する)まで再試行してから次のレコードに移動します。異なるシャードにわたるレコードの順序は保証されておらず、各シャードの処理は並行して行われます。

DynamoDB Streams Kinesis Adapterを使用する場合、アプリケーションはDynamoDBのドキュメント here に従って、断片とストリームレコードを正しい順序で処理します。 DynamoDBストリームKinesisアダプターの詳細については、「 DynamoDBストリームKinesisアダプターを使用したスト​​リームレコードの処理 」を参照してください。

したがって、dynamodb lambdaトリガーを使用しても順序は保証されません。他のオプションには、DynamoDB Streams Kinesis Adapterまたは DynamoDB Streams低レベルAPI の使用が含まれます。

1
user818510