■ 1. 非同期処理の定義と採用基準
- 非同期処理の定義: Webサービスにおける非同期処理は、AWS SQSやGoogle Cloud Pub/Subなどのメッセージキューを利用し、バックエンドサーバーがキューにメッセージを入れ、ワーカーがそれを非同期に処理する仕組みを指す。
- 構造: クライアント → バックエンドサーバー → AWS SQS/Pub/Sub → ワーカー
- 採用基準: 非同期処理は基本的に面倒であるため、同期処理では要件を満たせない時にのみ採用すべきである。
- 同期処理で要件を満たせないケース:
- 大規模な時間のかかる処理: 巨大なCSVファイルのダウンロードやアップロード・DB登録処理など、利用者を長時間待たせたり、DBに高負荷をかけたりする場合。
- 高RPS(Request Per Second)環境での外部API呼び出し: レイテンシの高い外部APIを複数回叩くエンドポイントに大量のリクエストが集中し、バックエンドサーバーのリソース(コネクションプールなど)が枯渇したり、スケール効率が悪化したりする場合。
■ 2. 非同期処理で考慮すべき面倒なポイント(設計フェーズ)
- (1) メッセージキュー/タスクキューに対する理解:
- 課題: AWS SQSやGoogle Cloud Pub/Subなど、利用する仕組みの仕様、機能、オプション、制限を正確に理解しておく必要がある。
- 運用上の考慮点: メッセージが溜まった際のワーカー数の手動スケールの必要性、それに必要なアラートやメトリクスの取得・設定を設計に含めるべきである。
- (2) ワーカー処理が失敗したときのリカバリ方法:
- 課題: ワーカーの処理は100%成功しないため、失敗時のリカバリ方法を設計する必要がある。
- 手動リカバリ: 失敗頻度が低い場合は、エンジニアが手動でメッセージを再キューイングする方法が考えられるが、手順の複雑化や手順書の最新性維持が困難になる可能性がある。
- 自動リカバリ: 失敗した処理をDBに記録し、定期実行バッチでリトライする方法が考えられるが、実装の手間やバッチ自体の失敗対応、処理タスク数の設計など、考慮点が多くなる。
- (3) ボトルネックの確認と対策:
- 課題: 非同期処理を採用しても、最終的に処理はどこかで実行されるため、ボトルネックや負荷は残る。特にRDBがボトルネックになる可能性が高い。
- 具体的なボトルネック: DBへの複雑なクエリや大量クエリによるDB負荷、メッセージ集中によるワーカー数クオータ上限到達、アラート発火などが考えられる。
- 対策例:
- 同時に実行できるワーカー数を制限する。
- ワーカー処理用に専用のDBインスタンス(分析用DBなど)を用意する。
- メッセージキューにキューイングできるメッセージ数を制限する。
- ワーカー処理にsleepを入れ、クエリ実行間隔を長くする。
- 補足: ハイトラフィックな非同期処理では、RDBよりもNoSQLやNewSQLといったスケールするDBとの相性が良い。
■ 3. 結論
- システムのスケーラビリティ: 非同期処理は面倒ではあるが、システムのスケール性能やサービス間の疎結合化を実現する上で非常に魅力的である。
- 将来の展望: ある程度の規模のシステムでは非同期処理の利用が避けられないため、エンジニアや組織は、システムのスケールに合わせて非同期処理を適切に扱えるようになるための変化への投資が必要となる。
- 重要性: 非同期処理は実装自体は簡単だが、設計フェーズで上記の面倒なポイント(仕様理解、リカバリ、ボトルネック)を考慮しなければ、リリース後の運用で大きな問題が発生する可能性が高い。