コンテンツにスキップ

7. スケーリングとパフォーマンス

Build.ioのようなプラットフォームで実行することの主な利点の一つは、スケーリングにサーバーのプロビジョニングが不要なことです。ダイノの数とサイズを調整することでスケールでき、プラットフォームが残りを処理します。ロードバランシング、コンテナの配置、トラフィックの分散はすべて自動的に行われます。

このセクションでは、アプリケーションのスケール方法と支払っているリソースを最大限に活用する方法を説明します。

7.1 水平スケーリング(インスタンスの追加)

Section titled “7.1 水平スケーリング(インスタンスの追加)”

水平スケーリングとは、同じタイプのダイノをより多く実行することです。追加される各ダイノはコードを実行する独立したコンテナであり、Buildのルーターがすべてのダイノに受信リクエストを分散します。

ダッシュボードから、アプリのResourcesタブに移動します。スライダーまたは入力フィールドを使用して各プロセスタイプ(web、workerなど)のダイノ数を調整します。

CLIから:

$ bld ps:scale web=3 -a my-app
Scaling dynos... done, now running web at 3

現在のフォーメーションを確認するには:

$ bld ps:list -a my-app

水平スケーリングが適切な場合

Section titled “水平スケーリングが適切な場合”

水平スケーリングは、ダイノが処理しきれないほどの同時リクエストを処理していてレスポンスタイムが増加している場合に適切な手段です。一般的なシグナルには、リクエストキュー時間の増加、負荷時のレイテンシの増加、タイムアウトエラーが含まれます。

アプリケーションがI/Oバウンド(データベースクエリ、外部API呼び出し、ファイル操作を待機している)場合、ダイノを追加することが有効です。各ダイノは他のダイノがI/Oでブロックされている間にリクエストを独立して処理できます。

個別のリクエストがCPUバウンドで遅い場合、水平スケーリングは効果が薄いです。その場合は、リクエストごとに行われる作業を最適化するか、垂直スケーリングを検討してください。

フォーメーションからプロセスを削除せずに一時的に停止したい場合、プロセスタイプをゼロダイノにスケールダウンできます。これはメンテナンス中や、設定を削除せずにバックグラウンドワーカーを一時停止したい場合に便利です。

$ bld ps:scale web=0 -a my-app

準備ができたらいつでもスケールアップできます。Config Var、アドオン、アプリの残りの部分はそのまま維持されます。

7.2 垂直スケーリング(インスタンスサイズ)

Section titled “7.2 垂直スケーリング(インスタンスサイズ)”

垂直スケーリングとは、より多くのメモリとCPUを持つ大きなダイノサイズに移行することです。インスタンスを増やすのではなく、各インスタンスにより多くのリソースを与えます。

Buildはアプリケーションのリソース要件に合わせた複数のダイノサイズを提供しています。小さいサイズは開発、ステージング、低トラフィックの本番アプリに適しています。大きいサイズはリソース集約型のワークロードにより多くのメモリとコンピュートを提供します。

ダイノサイズはアプリのResourcesタブから調整できます。

垂直スケーリングが適切な場合

Section titled “垂直スケーリングが適切な場合”

垂直スケーリングは、ダイノのメモリが不足している場合や、個別のリクエストが完了するためにより多くのCPU時間が必要な場合に適切なアプローチです。

メモリ不足 — ダイノがメモリ制限によって再起動されている場合は、より大きなダイノサイズが必要です。一般的な原因には、メモリリーク、大きなインメモリデータ構造、またはメモリを大量に使用するランタイムの実行などが含まれます。

CPUバウンドの作業 — 個別のリクエストが重い計算(画像処理、レポート生成、データ変換)を含むために遅い場合、より多くのCPU容量を持つ大きなダイノが役立ちます。これは通常、Webダイノとは独立してサイズを調整できるバックグラウンドワーカーダイノに作業をオフロードすることで対処する方が適切です。

水平スケーリングと垂直スケーリングの組み合わせ

Section titled “水平スケーリングと垂直スケーリングの組み合わせ”

ほとんどの本番アプリケーションは両方のアプローチの組み合わせが有効です。一般的なパターンは、中程度のサイズのWebダイノを複数実行し、バックグラウンド処理のために1〜2つの大きなワーカーダイノを実行することです。これにより、WebのレスポンスタイムをHighに維持しながら、重いバックグラウンドジョブに必要なリソースを確保できます。

7.3 パフォーマンスチューニング

Section titled “7.3 パフォーマンスチューニング”

スケーリングはパフォーマンスを改善するための手段の一つです。スケーリングの前(または並行して)、アプリケーション自体に低コストで改善できる部分が通常あります。このセクションでは最も一般的な改善ポイントを説明します。

ほとんどのパフォーマンス問題は少数の遅いエンドポイントから発生します。ロギングとモニタリングツールを使用して最も時間のかかるリクエストを特定し、最初にそれらに対処してください。

一般的な原因には、インデックスのないデータベースクエリ、N+1クエリパターン(単一クエリの代わりにループで関連レコードを取得する)、リクエストサイクル内で同期的に行われる遅い外部API呼び出しが含まれます。

重い作業にバックグラウンドジョブを使用する

Section titled “重い作業にバックグラウンドジョブを使用する”

ユーザーがレスポンスを受け取る前に完了する必要のない作業はバックグラウンドジョブで実行すべきです。メール配信、レポート生成、画像処理、Webhookの送信、サードパーティAPI呼び出しはすべて候補となります。

重い作業をバックグラウンドワーカーに移動することで、Webダイノのレスポンスを高速に維持し、長時間のリクエストがキャパシティを占有するのを防ぎます。バックグラウンドワーカーは独立してスケールでき、ジョブが失敗してもユーザーエクスペリエンスに影響なく再試行できます。

キャッシュは多くの場合、最大のパフォーマンス改善をもたらします。アプリケーションが同じデータを繰り返し計算または取得する場合、結果をキャッシュしてください。

アプリケーションレベルのキャッシュ — Redisを使用して(セクション5.2 データベースとアドオンを参照)、データベースクエリ結果、レンダリングされたページフラグメント、シリアライズされたAPIレスポンス、または高コストな計算をキャッシュします。短いTTL(30〜60秒)でも、トラフィックスパイク時のデータベース負荷を劇的に軽減できます。

HTTPキャッシュ — あまり頻繁に変更されないレスポンスに適切なCache-Controlヘッダーを設定します。静的アセットはキャッシュバストされたファイル名で積極的にキャッシュしてください。

Webサーバーの並行性チューニング

Section titled “Webサーバーの並行性チューニング”

ほとんどのWebフレームワークはデフォルトで保守的な並行性設定を使用しています。ダイノサイズとワークロードに合わせてこれらをチューニングすることで、ダイノを追加せずにスループットを大幅に増加させることができます。

Ruby(Puma) — ワーカー数とスレッド数を増やします。標準ダイノでの一般的な出発点は、5スレッドの2〜4ワーカーです。各ワーカーは独立したプロセスであるため、メモリ使用量を監視して適切なバランスを見つけてください。

Python(Gunicorn) — ワーカー数を増やします。一般的な計算式は(2 × CPUコア数) + 1です。アプリがI/Oバウンドの場合は非同期ワーカー(geventまたはuvicorn)を使用してください。

Node.js — Node.jsはデフォルトでシングルスレッドです。複数のワーカープロセスをフォークするためにclusterモジュールを使用するか、ダイノごとに1つのNodeプロセスを実行して水平スケールします。