App Engine は、アプリケーションのパフォーマンスとリソース使用率に関する使用状況レポートを生成します。以下に、リソースをより効率的に管理するための方法を示します。詳しくは料金のページをご覧ください。
使用状況レポートを表示する
アプリケーションのパフォーマンスを評価するときには、アプリケーションが実行されているインスタンス数や、アプリケーションによるリソースの消費状況を確認する必要があります。
以下のセクションで、リソースを管理する方法をいくつかご提案します。
動的インスタンス スケーリングの管理
レイテンシを短縮する
アプリケーションのレイテンシは、トラフィックの処理に必要なインスタンス数に影響します。レイテンシを短縮できれば、アプリケーションを提供するために使用するインスタンス数を減らすことができます。Cloud Trace は、レイテンシに関するデータを表示して、レイテンシを短縮するために見直すべき点を把握できる便利なツールです。
Cloud Trace を使用してレイテンシを表示した後、レイテンシを短縮するために次の方法をお試しください。
- アクセス頻度が高い共有データのキャッシュを大きくする − つまり、App Engine Memcache を使用することを意味します。また、アプリケーションのキャッシュ制御ヘッダーを設定すると、サーバーやブラウザによるデータのキャッシュ効率に大きな影響を与えることができます。数秒間キャッシュするだけでも、アプリケーションによるトラフィック処理の効率に影響を与えられます。
- App Engine Memcache をより効率的に使用する: 取得、設定、削除などの呼び出しを個々に行うのではなく、バッチで呼び出します。Memcache Async API の使用をご検討ください。
- リクエストにバインドされない機能にはタスクを使用する: ユーザー対応リクエストのスコープ外で処理できる作業をアプリケーションで実行する場合は、その作業をタスクに入れてください。その作業が完了してレスポンスが返されるのを待つのではなく、その作業をタスクキューに送信することで、ユーザー側のレイテンシが大幅に短縮されます。タスクキューを使用すると、実行速度をより細かく管理できるようになり、負荷を軽減できます。
- Datastore モードの Firestore(Datastore)をより効率的に使用する: 詳しくは下記をご覧ください。
- 複数の URL 取得呼び出しを並列化する:
- 複数の URL 取得呼び出しを個々のユーザー対応リクエスト内で個別に処理するのではなく、バッチにまとめ、非同期 URL 取得を使用して 1 つのオフライン タスクで同時処理します。
- 非同期 URL Fetch API を使用します。
- HTTP セッションの場合は、非同期書き込みを行う: Java では、
<async-session-persistence enabled="true"/>
をappengine-web.xml
に追加することで、Datastore に HTTP セッション データを非同期で書き込むようにアプリケーションを構成できます。セッション データは App Engine Memcache に常に同期的に書き込まれます。App Engine Memcache が使用できないときにセッション データを読み取ろうとしたリクエストは Datastore にフェイル オーバーします。ただし、Datastore にはまだ最新の更新が反映されていない場合があります。そのため、古いセッション データをアプリケーションが取得してしまうというリスクがわずかにありますが、ほとんどのアプリケーションではレイテンシが短縮されることの方が重要です。
自動スケーリングのパフォーマンス設定を変更する
appengine-web.xml
構成ファイルに含まれるいくつかの設定を使用して、アプリの特定のバージョンのパフォーマンスとリソース負荷のトレードオフを調整できます。使用可能な自動スケーリング設定のリストについては、スケーリング要素をご覧ください。App Engine の新しいスケジューラの設定の動画を見ると、これらの設定の効果を確認できます。
Java の同時リクエストを有効にする
この設定を有効にすると、アプリケーションのトラフィックの処理に必要なインスタンスの数が少なくなります。ただし、この機能が正常に動作するには、アプリケーションがスレッドセーフでなければなりません。appengine-web.xml
ファイルでスレッドセーフを有効にして、同時リクエストを利用する方法を確認してください。
タスクキュー設定を構成する
タスクキューのデフォルトの設定はパフォーマンスが高くなるように調整されています。これらのデフォルトの設定では、複数のタスクを同時にキューに入れると、高確率で新しいフロントエンド インスタンスが開始されます。インスタンス時間を節約するためにタスクキューを調整する方法の例を以下に紹介します。
- レイテンシがあまり重要でないタスクに X-AppEngine-FailFast ヘッダーを設定します。このヘッダーは、既存のインスタンスを使用できない場合はすぐにリクエストを止めるようにスケジューラに指示します。タスクキューは既存のインスタンスでリクエストを処理できるようになるまで、再試行とバックオフを実行します。ただし、X-AppEngine-FailFast が設定されたリクエストで既存のインスタンスがすべて使用されている場合は、そのヘッダーが設定されていないリクエストによって新しいインスタンスが開始されることがあるので注意してください。
- タスクキューの設定を構成します。
- 「rate」パラメータの値を小さくすると、タスクキューによるタスクの実行速度が低下します。
- 「max_concurrent_requests」パラメータの値を小さくすると、同時に実行されるタスクの数が少なくなります。
可能であれば静的コンテンツを提供する
Java での静的コンテンツの提供は、専用の App Engine インフラストラクチャによって処理されます。ここではインスタンス時間は消費されません。カスタム ヘッダーの設定が必要な場合は、Blobstore API を使用します。実際の blob レスポンスの提供では、インスタンス時間は消費されません。
アプリケーション ストレージの管理
App Engine は、Datastore のエンティティのサイズ、Datastore インデックスのサイズ、タスクキュー内のタスクのサイズ、Blobstore の保管データ量を基にストレージ コストを計算します。次を実行すると、必要以上にデータが保管されるのを防ぐことができます。
- アプリケーションで不要になったエンティティや blob を削除する。
- 不要なインデックスを削除してインデックス ストレージ コストを削減する(次の Datastore の使用量の管理に関するセクションをご覧ください)。
Datastore 使用量の管理
App Engine は、Datastore で実行されたオペレーションの数を記録しています。次の方法により、Datastore のリソース消費量の削減と、Datastore へのリクエストのレイテンシ短縮を実現できます。
- Google Cloud コンソール データビューアには、ローカル データストアのすべてのエンティティを作成するために要した書き込みオペレーションの数が表示されます。この情報を基に、各エンティティの書き込みコストを把握できます。このデータの解釈方法については、書き込みコストについてをご覧ください。
- 不要なインデックスを削除します。これにより、ストレージ コストとエンティティの書き込みコストが削減されます。インデックスの取得機能を使用して、アプリケーションでどのインデックスが定義されているか確認してください。現在アプリケーションに提供されているインデックスは、Google Cloud Console の [検索] ページで確認できます。
- データモデルの設計時に、カスタム インデックスを完全に除外するようにクエリを作成できます。App Engine によるインデックスの生成方法については、クエリとインデックスのドキュメントをご覧ください。
- 可能であれば、インデックスありのプロパティ(デフォルト)をインデックスなしのプロパティ(Java)に置き換えます。これにより、エンティティ挿入時のデータストア書き込みオペレーションの数を削減できます。後でそのインデックスなしのプロパティに対してクエリを実行する必要が生じた場合は、インデックスありのプロパティを使用できるようにコードを再修正するだけでなく、すべてのエンティティに対して map reduce を実行して再挿入する必要があるので注意してください。
- App Engine 1.5.2 および 1.5.3 リリースでは Datastore クエリ プランナーの機能が改善されたため、クエリに必要なインデックスの数が以前より少なくなっている可能性があります。パフォーマンス上の理由で一部のカスタム インデックスを引き続き使用することにした場合でも、それ以外のカスタム インデックスを削除してストレージ コストとエンティティの書き込みコストを削減できる可能性があります。
- データモデルを再構成して、クエリをキーによるフェッチに置き換えます。このほうが低コストで効率的です。
- 可能であれば、エンティティ クエリではなくキーのみのクエリを使用します。
- レイテンシを短縮するために、複数のエンティティの
get()
をバッチget()
に置き換えます。 - ページ分割にはオフセットではなくデータストア カーソルを使用します。
- 複数の Datastore RPC を Async Datastore API で並列化します。
注: 小規模な Datastore オペレーションには、データストア ID を割り当てるための呼び出しや、キーのみのクエリなどがあります。コストについては、料金ページをご覧ください。
帯域幅の管理
送信帯域幅を減らすには、レスポンスに適切な Cache-Control
ヘッダーを設定し、静的ファイルに妥当な有効期限を設定します。このようにパブリック Cache-Control
ヘッダーを使用すると、プロキシ サーバーとクライアントのブラウザで指定の期間にわたってレスポンスをキャッシュに保存できます。
受信帯域幅はユーザーがアプリに送信するデータ量となることから、制御は困難です。ただし、App Engine ファイアウォール ルールを使用して、IP アドレスとサブネットの範囲を許可または制限できます。