Dyno formation のスケーリング
最終更新日 2024年01月23日(火)
Table of Contents
Heroku アプリは、複数の dyno (Eco または Basic dyno を除く) で同時に実行されるようにスケーリングできます。アプリの Dyno formation は、Heroku Dashboard または CLI から、手動でスケールアップまたはスケールダウンできます。
Performance 層の dyno および Private Space で実行中の dyno に対して、Heroku Autoscaling を設定することもできます。しきい値のオートスケールにより、現在のリクエストレイテンシーに基づいて、Web dyno がアプリに自動で追加または削除されます。
dyno は秒単位に分割されるため、別のスケーリング設定を試しても、実際に使用した秒数分のみ請求されます。アプリの dyno および Worker の数の設定はユーザーの責任となるため、正しく行ってください。
手動スケーリング
dyno の数のスケーリング
Heroku dyno は、Eco、Basic、Professional の各層に分類されます。プロセスタイプごとに複数の dyno を実行するようにスケーリングできるのは、Professional 層の dyno (Standard および Performance dyno) だけです。dyno の数をスケーリングするには、アプリが Professional 層の dyno で実行されていることを事前に確認してください。
- Heroku Dashboard で、スケーリングするアプリをアプリの一覧から選択します。
Resources
(リソース) タブに移動します。- dyno の一覧の上にある
Change Dyno Type
(dyno タイプの変更) をクリックします。 Professional (Standard/Performance)
dyno タイプを選択します。Save
(保存) をクリックします。
ダッシュボードからのスケーリング
特定のプロセスタイプについて dyno の数をスケーリングする方法
- スケーリングするアプリをアプリの一覧から選択します。
Resources
(リソース) タブに移動します。- アプリの dyno 一覧で、スケーリングするプロセスタイプの横にある
Edit
(編集) ボタン (鉛筆マーク) をクリックします。 - スライダーをスケーリングする dyno の数までドラッグします。
Confirm
(確認) をクリックします。
ダッシュボードからのスケーリング
Dyno formation は、Heroku CLI で ps:scale
コマンドを使用してスケーリングします。
$ heroku ps:scale web=2
Scaling dynos... done, now running web at 2:Standard-1X
上記のコマンドにより、アプリの web
プロセスタイプが 2 つの dyno にスケーリングされます。
以下のように、1 つのコマンドで複数のプロセスタイプをスケーリングすることもできます。
$ heroku ps:scale web=2 worker=1
Scaling dynos... done, now running web at 2:Standard-1X, worker at 1:Standard-1X
dyno の数量を (上記の例のように) 絶対数で指定することも、以下のように現在の dyno の数から数量を増減させることもできます。
$ heroku ps:scale web+2
Scaling dynos... done, now running web at 4:Standard-1X.
特定のプロセスタイプの実行を完全に停止する場合は、 0
にスケーリングします。
$ heroku ps:scale worker=0
Scaling dynos... done, now running web at 0:Standard-1X.
dyno タイプの変更
ダッシュボードからの dyno タイプの変更
Eco、Basic、Professional の各層の dyno タイプの間で変更するには:
- Heroku Dashboard で、スケーリングするアプリをアプリの一覧から選択します。
Resources
(リソース) タブに移動します。- dyno の一覧の上にある
Change Dyno Type
(dyno タイプの変更) をクリックします。 - 目的の層を選択します。
Save
(保存) をクリックします。
特定のプロセスタイプに使用される Professional 層の dyno の間で dyno タイプを変更するには:
- Heroku Dashboard で、スケーリングするアプリをアプリの一覧から選択します。
Resources
(リソース) タブに移動します。- 変更するプロセスタイプの横にある八角形のアイコンをクリックします。
- ドロップダウンメニューから新しい dyno タイプ (Standard dyno または Performance dyno) を選択します。
Confirm
(確認) をクリックします。
CLI からの dyno タイプの変更
プロセスタイプを standard-1x
dyno から standard-2x
dynoに移動し、メモリと CPU 割り当てを増やす方法
$ heroku ps:scale web=2:standard-2x
Scaling dynos... done, now running web at 2:Standard-2X.
dyno タイプを変更する場合も、dyno の数量 (上記の例の 2
など) を指定する必要があります。
standard-1x
dyno に戻す場合も、同様に機能します。
$ heroku ps:scale web=2:standard-1x
Scaling dynos... done, now running web at 2:Standard-1X
dyno タイプとその特性の詳細については、dyno タイプに関するドキュメントを参照してください。
オートスケール
現在、オートスケールは Performance 層の dyno および Private Space で実行中の dyno でのみ利用できます。Heroku のオートスケールでは、応答時間のばらつきを大幅に抑えるために、アプリケーションに依存する応答時間を使用します。オートスケールがユーザーのニーズを満たさない場合や、アプリに対して想定どおりに機能していない場合は、Elements Marketplace にあるサードパーティ製のアドオンを検討してください。たとえば、全体的な応答時間の代わりにキューイング時間に基づいてスケール調整するアドオンを検討できます。
オートスケールを使用すると、アプリの 1 つ以上のパフォーマンス特性に基づいて、Web dyno の数量を自動的にスケールアップおよびスケールダウンできます。
設定
Heroku の Web オートスケールを HireFire などのサードパーティー製の Worker オートスケール機能と同時に使用すると、まれに競合状態が発生することが確認されています。この競合状態により、Heroku のオートスケールが予期せず無効になります。このシナリオを回避するため、これら 2 つのオートスケールツールは同時に使用しないでください。
オートスケールは、アプリの Heroku Dashboard の Resources
(リソース) タブで設定されます。
Web dyno の詳細の横にある Enable Autoscaling
(オートスケールの有効化) ボタンをクリックします。オートスケールの設定オプションが表示されます。
スライダーまたはテキストボックスを使用して、アプリの可能なオートスケール範囲を指定します。指定した範囲に関連付けられているコスト範囲は、スライダーの下に直接表示されます。dyno の数が、指定した範囲を超える数量にスケーリングされることはありません。dyno 数の下限を 1
より少なくすることはできません。
次に、アプリの Desired p95 Response Time (望ましい p95 応答時間) を設定します。オートスケールエンジンは、この値を使用して、dyno の数をスケーリングする方法を決定します (下記参照)。推奨 p95 応答時間が提示されます。
Web dyno の数が上限に到達したらアプリの共同作業者 (Heroku Teams を使用している場合はチームメンバー) の全員に通知されるようにする場合は、Email Notifications
(メール通知) を有効にします。1 日に送信される通知メールは最大 1 通です。
好みに応じてオートスケールを設定したら、Confirm
(確認) をクリックします。新しいオートスケール dyno 範囲の設定にプロセスタイプの現在の dyno の数が含まれていない場合、現在の dyno の数が範囲に従って即座に調整されます。
オートスケールロジック
Dyno Manager は、アプリの 「Desired p95 Response Time」 (望ましい p95 応答時間) を使用して、アプリのスケーリングを行うタイミングを決定します。オートスケールアルゴリズムによって、過去の時間からのデータが使用され、現在のリクエストスループットでの受信リクエストの 95% についての望ましい応答時間を実現するために必要な Web dyno の最低数が計算されます。
オートスケールアルゴリズムでは、計算に WebSocket トラフィックは含まれません。
オートスケールイベントが発生するたびに、1 つの Web dyno がアプリに追加されるか、アプリから削除されます。オートスケールイベントは、必ず 1 分以上の間隔を空けて発生します。
オートスケールアルゴリズムでは、スケールダウンはスケールアップよりも消極的に行われます。これにより、リクエストの一時的な停滞から大幅なスケールダウンが行われることによって、需要がその後急増した場合にレイテンシーが高くなるのを回避することができます。
アプリで 3 分間リクエストのスループットがない場合、スループットが再開されるまで、Web dyno が -1 分のインターバルにスケールダウンされています。
リクエストの速度低下は、Web リソースではなくダウンストリームのボトルネックが原因となる場合があります。このような場合、Web dyno の数をスケールアップしても、レイテンシーへの影響が最小限になる可能性があります (マイナスの影響が生じる可能性すらあります)。これらのシナリオに対応するため、失敗したリクエストの割合が 20% 以上になると、オートスケールは無効になります。しきい値アラートを使用して、失敗したリクエストに関する指標を監視できます。
オートスケールイベントの監視
Heroku Dashboard から
オートスケールイベントは、「Events」 (イベント) グラフに手動のスケーリングイベントとともに表示されます。現在、イベント詳細では、オートスケールイベントは「Dyno Autoscaling」によって開始されているものとして識別されます。さらに、オートスケールの有効化、無効化、変更も表示されます。一連のオートスケールイベントが間隔をはさんで実行される場合、スケーリングの方向が変わったステップのみが表示されます。たとえば、「Scaled up to 2 of Performance-M」 (2 つの Performance-M へのスケールアップ) の下の 「Events」 (イベント) グラフには、最大の 3 つの Performance-M dynos への中間ステップがありますが、これは表示されません。
Webhook の使用
アプリの Dyno formation が変更されるたびに送信される Webhook 通知に登録することができます。Dyno formation に関連する Webhook 通知は api:formation
タイプです。
Webhook 通知への登録の詳細については、「アプリの Webhook」を参照してください。
オートスケールの無効化
アプリの Resources
(リソース) タブで Disable Autoscaling
(オートスケールの無効化) ボタンをクリックして、オートスケールを無効化します。その後、確定した Web dyno の数を指定して Confirm
(確認) をクリックします。
CLI から手動でスケーリングするか、API から ps:scale
に対する呼び出しを行い、(たとえばサードパーティー製オートスケールツールを使用して) 手動でスケーリングすると、オートスケールが無効になるように指示します。
既知の問題と制限事項
いかなるオートスケール機能にもあるように、オートスケールが役に立たない可能性がある特定のアプリケーションヘルスシナリオがあります。Postgres 接続プール、Worker の数、またはアドオンプランを調整して、Web dyno formation に変更を適応させる必要がある場合もあります。20% 以上のリクエストスループットエラー率に基づくスロットルのオートスケールのメカニズムは、ダウンストリームコンポーネントでボトルネックが発生したシナリオ向けに設計されています。詳細については、「並列性の理解」を参照してください。
負荷テストで本番稼働をシミュレーションし、オートスケールと同時にしきい値アラートを使用してアプリのエンドユーザーエクスペリエンスを監視することを強くお勧めします。Heroku Support の通知要件については、「負荷テストのガイドライン」を参照してください。
スケーリングの制限
dyno タイプによって、スケーリングできる限度が異なります。スケーリングの制限の詳細については、「dyno タイプ」を参照してください。
Dyno formation
「Dyno formation」という用語は、特定の時間におけるアプリの dyno のレイアウトを指しています。シンプルなアプリのデフォルトの Dyno formation は 1 つの Web dyno ですが、より要求の多いアプリケーションは Web、Worker、Clock など、さまざまなプロセスタイプで構成されます。上記の例では、Dyno formation は初めに 2 つの Web dyno に変更され、次に 2 つの Web dyno と 1 つの Worker dyno に変更されました。
スケールコマンドは、コマンド内で指定されたプロセスタイプにのみ影響します。たとえば、アプリにすでに 2 つの Web dyno の Dyno formation があり、heroku ps:scale worker=2
を実行した場合、dyno の数は 4 つ (Web 2 つ、Worker 2つ) になります。
dyno の一覧表示
現在の Dyno formation は、heroku ps
コマンドを使用して確認できます。
$ heroku ps
=== web (Eco): `bundle exec unicorn -p $PORT -c ./config/unicorn.rb`
web.1: up for 8h
web.2: up for 3m
=== worker (Eco): `bundle exec stalk worker.rb`
worker.1: up for 1m
Unix の Watch ユーティリティは、ps
コマンドと組み合わせて使用すると非常に便利です。dyno の追加または削除、デプロイ、またはアプリの起動を行いながら、1 つのターミナルで watch heroku ps
を実行します。
内観
Dyno formation への変更はすべてログ記録されます。
$ heroku logs | grep Scale
2011-05-30T22:19:43+00:00 heroku[api]: Scale to web=2, worker=1 by adam@example.com
ログ記録されたメッセージには、スケーリングのコマンドで指定された dyno のみではなく、Dyno formation もあります。
並列性の理解
Clock/Scheduler プロセスタイプなどのシングルトンプロセスタイプや、Twitter の Streaming API を使用するプロセスタイプは、1 つの dyno を超えるスケーリングを行ってはなりません。これらのプロセスタイプには追加の並列性によるメリットはなく、むしろ各試行で同時に同じ処理が行われることによって、システムに重複したレコードやイベントが作成されます。
プロセスタイプのスケールアップにより、プロセスタイプが対応する処理の実行の並列性が強化されます。たとえば、dyno を追加すると、より多くの並列 HTTP リクエストを処理できるため、より大量のトラフィックを処理できます。Worker dyno を追加すると、より多くのジョブを同時に処理できるため、ジョブの合計ボリュームが大きくなります。
ただし、重要なこととして、プロセスタイプに dyno を追加してもアプリのパフォーマンスがすぐには向上しないシナリオも存在します。
バッキングサービスのボトルネック
アプリのパフォーマンスが、バッキングサービス (最も一般的にはデータベース) によって生じたボトルネックによって制限される場合があります。現在、データベースがパフォーマンスのボトルネックとなっている場合は、dyno を追加してもさらに状況が悪化するだけです。代わりに、以下のいずれかまたはすべてを試してください。
- データベースクエリを最適化する
- より大きなデータベースにアップグレードする
- キャッシングを実装してデータベースの負荷を減らす
- 共有設定に切り替えるか、スケーリングでフォロワーを使用して読み込む
実行時間の長いジョブ
dyno の並列性では、30 秒かかるデータベースクエリがあるレポートや、20,000 人の購読者にニュースレターを送信するジョブなど、大きな単一 HTTP リクエストには対応しません。並列性では、処理を分割しやすい水平方向へのスケーリングが行われます。
処理速度の遅いレポートは、レポートの計算がバックグラウンドで行われるようにして、あとで表示するために結果が memcache に格納されます。
長いジョブの場合は、処理を分割します。(それぞれ 1 つのニュースレターを送信する) 20,000 個のジョブを順番にキューに配置する単一ジョブを作成します。1 つの Worker ですべてのジョブを順番に処理するか、スケールアップして複数の Worker でこれらのジョブをよりすばやく処理します。Worker を増やせば増やすほど、バッチ全体が早く完了します。
リクエストキューイングの効率に関する並列性の効果については、「リクエストタイムアウト」の記事でより詳細に説明しています。