web-dev-qa-db-ja.com

Azure Functionsを使用してDocumentDBドキュメントを更新するときの並列処理

ユーザーが不動産のリストをアップロードできるWebアプリを書いています。これにより、掲載している物件の写真をアップロードできるようになります。

私はマイクロサービスタイプのアプローチを使用しているため、メディアのすべてのアップロード、各プロパティで利用可能なメディアのクエリなどを処理するプロパティメディアサービスがあります。

ただし、7または8のサービスを呼び出さずにプロパティページをすばやく検索して表示する必要があるため、プロパティのAzure DocumentDBコレクションも維持しています。各ドキュメントには、プロパティの詳細の検索とバインドをサポートするために必要な特定のプロパティに関するすべてが含まれています。ページ。

ここまでは順調ですね。

新しい画像がアップロードされたときに、Azure Service Busトピックにイベントを発生させるだけのイベントソーシングパターンを選択しました。ドキュメントを読み込み、アップロードされた画像の詳細で更新し、保存するAzure関数のトリガーとなるこのトピックへのサブスクリプションがありました。

それは機能しました-しかし、ユーザーが10個の画像をアップロードすると、トピックに10個のイベントが発生するという並列性/並行性の問題があります。 Azure Functionsの性質上、メッセージを処理する10のプロセスを同時に起動する可能性があります。

Azure DocumentDbは部分的なドキュメントの更新をサポートしていないため、Azure関数は次の手順を実行します。

  • ドキュメントをロードします
  • imagesコレクションに子を追加します
  • ドキュメントを保存します

最近、複数の画像をアップロードすると、信頼できる更新が得られないことに気付きました。多分10のうち6つだけがDocumentDbに表示されます。関数のログは、10回の実行がすべて成功したことを示しているため、ここでは、私が並行して実行されており、1つの更新が別の更新を上書きした犠牲になっていると想定できます。

それを回避するために、メディアサービスがイベントを発生させないようにしていますが、DocumentDb自体を更新するだけです。しかし、これは私の心の責任ではないので、私はこれに本当に満足していません。今のところ問題は解決されていますが、イベントソーシングとAzure Functionsがドキュメントをより良いデザインとして更新するのが好きでした。

私にとってより良いオプションはありますか? 「マスタードキュメント」を1つ更新する代わりに、Azure FunctionのDocumentDbコレクションにドキュメントを追加できると考えましたが、それは、プロパティの詳細ページでさらに多くの作業を行い、それらをまとめることを意味します。

トリックを見逃しましたか?

6
bgs264

したがって、イベントソーシングについての私の理解は、オブジェクトの状態を従来の逆シリアル化するのではなく、保存されたイベントからオブジェクトを再作成することです。あなたは本当にそうではないようですが。

通常、イベントの順序が重要であるためです。これには、手動のトランザクションの形式が必要です。この場合、一連のイベントIDまたはバージョン番号を割り当て、作業中のイベントの処理中に別のイベントが発生したかどうかを確認できます。すなわち。

  • ドキュメントをロード
  • 古いバージョン番号/最後のイベントIDを読み取ります
  • イベントID付きの画像を追加
  • バージョン番号を更新する
  • バージョン番号が同じか、イベントが追加されていない場合、ドキュメントを上書きします
  • 開始後にバージョンが変更されている場合は、操作をやり直してください。

あなたがいつもステップをやり直しているので、衝突がたくさんある場合、これは明らかにうまくいきません。さらに、その最後のステップでは、DBでサポートされている何らかのトランザクションが必要です。

ただし、DocumentDbはトランザクションをサポートしています。

DocumentDBはACIDトランザクションをサポートしていますか?

はい、DocumentDBはJavaScriptストアドプロシージャとして表現されたクロスドキュメントトランザクションをサポートします

ドキュメントのバージョン番号を確認するだけの簡単な再利用可能なトランザクションを作成することをお勧めします。その後、それをすべてのイベントで使用できます。

1
Ewan