私はAWSでイベントストアを設計していて、DynamoDBを選択しました。私のデザインはかなり良いようですが、解決できない問題に直面しています。
イベントは、ペア(StreamId、EventId)によって一意に識別されます。
イベントはDynamoDbに保持されます。各イベントは、必須フィールドがStreamId、EventId、EventName、Payload(より多くのフィールドを簡単に追加できます)であるテーブルの単一のレコードにマップします。 partitionKeyはStreamId、sortKeyはEventIdです。
楽観的ロックは、イベントをイベントストリームに書き込むときに使用されます。これを達成するために、私はDynamoDb条件付き書き込みを使用しています。同じ(StreamId、EventId)のイベントがすでに存在する場合は、集計を再計算し、ビジネス条件を再確認して、ビジネス条件に合格した場合は最後にもう一度書き込む必要があります。
各イベントストリームは、partitionKeyによって識別されます。すべてのイベントのストリームをクエリすると、partitionKey = $ {streamId}および0とMAX_INTの間のsortKeyのクエリと同じになります。各イベントストリームは、1つの集約のみを識別します。これは、前に説明した楽観的ロックを使用して、同じアグリゲートでの同時書き込みを処理するのに役立ちます。これにより、集計を再計算する際にも優れたパフォーマンスが得られます。
DynamoDBストリーム+ Lambdaの組み合わせを利用してイベントが公開されます。
ここから問題が始まります。各イベントストリームを1つの集計のみでマッピングすると(多数のイベントストリームが発生します)、どのイベントストリームからすべてのイベントを照会する必要があるかを簡単に知る方法はありません。
追加のレコードを使用することを考えていました。DynamoDBのどこかに、すべてのStreamIdを配列に格納します。その後、クエリを実行してイベントのクエリを開始できますが、再生中に新しいストリームが作成されると、ストリームが失われます。
何か不足していますか?それとも私のデザインは単に間違っていますか?
あなたが本当に達成したいのは、すべてのイベントを順番に再生する方法だと思います。このために必ず行うべきことは、イベントにタイムスタンプを追加することです。
これを実現する1つの方法は、いくつかのバッチサイズ(1000など)でラムダをDynamoDBストリームに接続し、1つのバッチ内でイベントを並べ替え、タイムスタンプをキーとしてバッチをS3バケットに保存することです。このようにして、バケットに対してListObjectsオペレーションを実行し、すべてのイベントを順番に取得できます。読み取りモデルが最新の状態になったら、通常のイベントストリームにフックします。
DynamoDBのイベントストアには非常によく似た設計を使用し、順次再生にはS3バケットを使用します。