質問への回答。
アーキテクチャは、イベント駆動型の制御プレーンを介して短命なコンピュートと耐久性のある状態を分離するDurable Executionパターンに基づいています。コアには、すべての状態遷移がApache Kafka(前書きログ)に不変なイベントとして永続化される決定論的状態マシンとして実行されるワークフロー定義があります。これにより、障害発生時に決定論的な再生が可能になります。コンピュート層は、テナント固有のVPCおよびIAM境界内に整理されたAWS LambdaまたはAzure Functionsを活用し、隔離を確保しつつ、コールドスタートを軽減するためにプロビジョニング済みの同時実行暖かいプールを利用します。リージョン間での正確な一度のセマンティクスには、CockroachDBを使用し、ワークフローの状態を保存するためのデフォルトの逐次一貫性を持つシリアライズ可能な隔離を利用します。イベント相関は、RedisクラスターとRedisJSONインデックスによりホットイベントマッチングをメモリ内で処理し、Elasticsearchが過去の相関クエリ用のコールドストレージとして機能し、Cloudflare Workersがトラフィックスパイクを吸収するためのエッジサイドイベントバッファリングを提供します。
実生活からの状況
2023年のブラックフライデーにおいて、SwiftCart(グローバルなeコマースプラットフォーム)は、50Mの同時配信ワークフローを処理中に発生したレガシーStep Functions実装の壊滅的な障害に直面しました。us-east-1が地域的な障害を経験した際に、us-west-2へのフェイルオーバーにより12,000件の重複出荷が発生しました。なぜならワークフローの状態再一致がDynamoDBの最終的一貫性に依存していたためであり、TTLウィンドウは5分でした。同時に、キャリアのウェブフックイベントは30秒の相関遅延に直面し、顧客に対するリアルタイムの追跡約束が破られ、$2MのSLAペナルティが発生しました。
ソリューションA: EKS上のAirflowを使用したKubernetesベースのオーケストレーター
このアプローチは、Apache AirflowがAmazon EKS上で実行され、PostgreSQLがメタデータストアとして使用されることで完全な制御と成熟したツールを約束しました。メリットには広範なプラグインエコシステムと簡単なローカル開発環境が含まれていました。しかし、デメリットは致命的でした: ポッドスケジューリングのレイテンシは平均45秒で、アイドル状態のワークフローはほぼゼロのコンピューティングコストを負担するというスケール・トゥ・ゼロ要件に違反しました。さらに、リージョンに跨がるPostgreSQLの同期レプリケーションの維持は、タスク状態遷移ごとに200msを追加し、組み込みの正確に一度のセマンティクスの欠如は、複雑なアプリケーションレベルのロックを必要とし、地域的なフェイルオーバー中に頻繁にデッドロックを引き起こしました。
ソリューションB: KafkaとLambdaを使用した純粋なイベント駆動型の振る舞い
このサーバーレスネイティブアプローチは、Amazon MSK(Kafka)を真実の情報源として利用し、Lambda関数が中央のオーケストレーターなしでイベントに反応します。利点には真の使用従量課金制度とログベースの永続性を通じた自然な回復力が含まれていました。しかし、正確に一度のセマンティクスを実装するには、DynamoDB(冪等性のため)とKafkaに跨る分散トランザクションが必要で、各操作ごとに500ms以上のレイテンシを引き起こしました。さらに、長期間にわたるプロセス(7日間のワークフローの5日目)のワークフローステータスを再構築するには、S3アーカイブから数百万のイベントを再生する必要があり、回復時間が10分を超えてしまい、失敗が発生した際に「分散したスパゲッティ」をデバッグできなくなりました。
ソリューションC: シャーディングされた状態管理を持つ耐久性のある実行プラットフォーム
選択されたアーキテクチャは、耐久性のある状態(地理的にパーティション分けされたテーブルを持つCockroachDB)と短命なLambdaワーカーを分離したカスタムのTemporalにインスパイアされた制御プレーンを実装しました。Consistent Hashingがリージョンデータベースノード間でワークフローシャードを分散し、Redis Streamsがサブミリ秒のイベント相関バッファリングを提供しました。利点には、CockroachDBのシリアライズ可能なトランザクションを通じたネイティブの正確な一度の実現、デバッグ用の決定論的な再生、アイドル待機期間中に非アクティブなワークフローが安価なS3スナップショットのみに存在する真のスケール・トゥ・ゼロが含まれます。デメリットは、サービスディスカバリーのためにetcdクラスタを維持するための複雑な運用や、大規模なウェイクアップシナリオにおけるサンダリングハードを防ぐための洗練されたキャッシングが必要であることです。
結果
テナントごとのSQSキューと1秒の可視性タイムアウトを実装することにより、SwiftCartは、その後のPrime Dayイベント中に45分間のus-west-2の障害にもかかわらず、ワークフローの重複をゼロに抑えました。イベント相関のp95レイテンシは、Redisエッジキャッシュを通じて400msに短縮されました。インフラストラクチャコストは、常時稼働のEKSアプローチと比べて70%減少し、85%のワークフローがアイドル待機期間中にS3の圧縮状態スナップショットとしてのみ存在し、年間$1.4Mの節約を実現しました。
候補者が見逃すことが多いこと
ネットワークパーティションの間、両方のリージョンが同時にイベントを処理する場合、ワークフロー状態の分岐を防ぐにはどうしますか?
ほとんどの候補者は、DynamoDBまたはCassandraでlast-write-winsセマンティクスを提案しますが、ワークフローのオーケストレーションにはビジネス操作が非可換であるため機能しません(たとえば、「注文をキャンセルする」と「注文を出荷する」はタイムスタンプだけでは照合できません)。正しい実装は、ワークフロー状態メタデータ内に埋め込まれたVector ClocksまたはDotted Version Vectorsを使用します。ネットワークパーティションが修復されると、システムはバージョンベクター比較を通じて同時に発生したブランチを検知し、ドメイン固有のマージ関数を適用します。解決不可能な競合(たとえば同時キャンセルと出荷など)に対しては、アーキテクチャはsaga compensationパターンを適用し、後の操作が以前のアクションのロールバックを引き起こすようにします。CockroachDBのデフォルトのシリアライズ可能な隔離を利用することで、パーティション中の競合書き込みを拒否し、サイレントデータ破損を防ぎながら明示的なリトライループを強制できます。