要点: サーバーを増やしても、一つのリクエスト自体が重いという問題は解決しません。
この記事の用語: Backpressure:処理能力を超える前に受付を減らす仕組み。オートスケール:需要に応じて実行数を増減すること。
現場の課題
メール送信、帳票生成、ファイル処理を応答前に行えば、利用者は長く待たされます。さらにサーバーを増やすほどDB接続も増え、下流のボトルネックを悪化させます。
オートスケールは閾値を超えた後に反応し、重いリクエストを軽くはしません。同期経路を短くし、遅延可能な仕事を分け、下流に上限を置くことが先です。
設計と実装
- リクエスト時間を測り、利用者が完了を待つ必要のない処理を同期経路から外します。
- キュー ジョブは複数回実行されても結果が一つになるよう設計します。
- CPUだけでなく、最古ジョブの待ち時間と下流サービスの上限でワーカーを増減します。
実装例
arrivalRate = jobsAdded / windowSeconds
serviceRate = jobsCompleted / windowSeconds
backlogTime = queueDepth / max(serviceRate, 1)
desiredWorkers = ceil(arrivalRate / jobsPerWorker)
desiredWorkers = clamp(desiredWorkers, minWorkers, maxWorkers)
if backlogTime > objectiveSeconds:
desiredWorkers = min(desiredWorkers + burstStep, maxWorkers)本番導入の進め方
メールや帳票などの副作用を一つずつOutboxとキューへ移します。同期結果と比較した後、最古ジョブの待ち時間とDBの安全上限に基づいてワーカーを増やします。
まとめ
オートスケールは、仕事の単位、非同期境界、需要を表す指標が明確になって初めて効果を発揮します。
