Akamai Diversity

Akamai Japan ブログ

キャッシングによるAPIパフォーマンスの向上

アカマイはAPI Gatewayという新製品を発売しましたが、この記事ではAPIをキャッシュする意義についてお伝えしたいと思います。

※ この記事は2018.5.31に執筆されたDeveloper Blogの記事を翻訳した内容を元に作成しています。
 
多くの開発者がAPIキャッシングについてどのように動作するのか、それがもたらす利点をより深く理解したいと考えています。APIのキャッシングの採用は、各APIのキャッシングルールを定義し管理するツールがないために制限されていました。(従来は、レスポンスをキャッシュする要件がAPIごとに異なるため、複数のAPIにキャッシングルールを設定することは現実的ではありませんでした)  
このブログ記事はさまざまな実装シナリオのレビューを通じて、APIレスポンスのキャッシュの利点を理解するのに役立ちます。

下記のテスト方法でテストした場合、キャッシュ使用時にテスト用のAPIが21%速く配信されることがわかりました。
さらにこのブログでは、Akamai API GatewayがAPI開発者がそれぞれのAPIに独自のキャッシュポリシーを提供する方法について注目していきます。Akamai API GatewayはAPIキャッシングを利用するプロセスを大幅に簡素化し、同じ時間内でもより多くのデータを提供することができます。
 
考慮すべき主要なキャッシュのシナリオ: 
※考慮すべき主要なキャッシュのシナリオが7つですが、この記事では前半の4つテストしました、後半の3つについては次回記事にてテストします。
 
  • ローカルでアプリケーションレベルのキャッシュを使用しない
  • ローカルでアプリケーションレベルのキャッシュを使用する
  • アプリケーションレベルのキャッシュを持たないIaaS(Digital Ocean)を使用する
  • アプリケーションレベルのキャッシュを備えたIaaS(Digital Ocean)を使用する
  • アカマイを利用し(キャッシュは使用しない)、アプリケーションレベルのキャッシュを使用しない
  • アカマイを利用し(キャッシュは使用しない)、アプリケーションレベルのキャッシュを使用する
  • アカマイを利用し(キャッシュは使用しする)、アプリケーションレベルのキャッシュも使用する
サンプルAPIに対するリクエストを生成するために、Siegeを使用します。Siegeはアプリケーションが耐えることができる負荷を判断するためのオープンソースツールです。DDoS攻撃を行うような悪意のある用途でも使用される可能性がありますが、そういったユースケースを除けば、単一または複数のAPI URLの負荷テストをするために優れたツールです。
Siegeの実行結果は以下のスクリーンキャプチャのようになります。:指定したURLへのリクエスト実行結果です:
 
api_part1_image1_1.png
 
テストのために使用するAPIは、単純なNodeJS APIとMongeDBを組み合わせたものであり、実行結果はリクエストに対応したデータを返します。mongoose、bodyParserなどを使用した基本的なExpressベースのAPIです
 
api_part1_image2.png
 
いくつかのデータを含む、長さ227行で6.59 KBのJSONレスポンスを返す簡単なGETリクエストをテストします
 
api_part1_image3.png
以下は、GETコマンドを実行して返されるヘッダーです。サーバーとの接続を維持しており、ペイロードのサイズを減らすためにGZIPを有効にしていることに注目してください
 
api_part1_image4.png
最初のテストでは、5人の同時ユーザーがローカルホストからExpressを実行しているサーバーに対してSiegeを5分間実行します。ベースラインを設定するために、ネットワーク関連の遅延を計測から外します。以下のSiegeコマンドラインを起動すると、5分間GETリクエスト実行する5人の同時ユーザーがシュミレートされます。
 
$ siege -c 5 -time = 5m -content-type "application / json" GET http:// localhost:3000 / cats
 
api_part1_image5_1.jpg
最初のSiege実行結果には、ヒット数(トランザクション)、テストの実行時間、転送されたデータの量、トランザクション率、成功したトランザクションと失敗したトランザクションの数などのデータが含まれます。
この結果をベースラインとして使用します。
次にアプリケーションレベルのキャッシュを追加しましょう。apicache NPMパッケージを使用して、アプリに単純なメモリ内レスポンスキャッシュを追加します。パッケージ( "npm install apicache")を追加した後、いくつかの行を設定ファイルに追加して有効にします:
 
api_part1_image6.png
ルート・パスに対する"get_all_cats"にキャシュをオンにします。元のルート・パスはコメントアウトされていることに注意してください。このルート・パスのコピーでは、5分間レスポンスをキャッシュするためのディレクティブ付きのapicacheが使用されています。:
 
api_part1_image7.png
 
この記事の後半ではさまざまなテストを実行するために、この2つのルートの間でキャッシングを有効または無効を切り替えます。テストを混乱させる可能性のあるメモリがクリアするためにNodeJSサーバーを一度再起動します。サーバーに対してリクエストを行うと、レスポンスキャッシュは新しい追加されたcache-controlヘッダーの存在によって有効になっていることがわかります。このヘッダーの最大有効期間の値は300秒(5分)に設定しています。:
 
api_part1_image8.png
 
また、apicacheモジュールのデバッグを有効にして、動作していることを確認することもできます。
 
api_part1_image9.png
 

最初のリクエストでは、クライアントにデータを返すのに31msかかりましたが、その後のリクエストはそれほど長くはかかりませんでした。最初のリクエストは完全なリクエストですが、それ以降のすべてのリクエストはメモリキャッシュから処理され、0.5ms以内にクライアントに返されます。これがキャッシュの主な利点です。

先程のキャッシュしない場合と比べ、アプリケーションベースのキャッシュを行った場合に
どのような違いがあるか確認するために、前回と同じSiegeコマンドを再実行します。 

$ siege -c 5 -time = 5m -content-type "application / json" GET http:// localhost:3000 / cats
 
api_part1_image10_1.jpg
 
アプリケーションベースのキャッシングは大きな違いをもたらしました。同じ5分間の経過時間で、キャッシュをオンにした場合ヒット数を60%増やしました。より多くのデータを転送し、449件/秒のトランザクションを処理できました。これは、もとの179件/秒から60%の増加です。APIにキャッシングを追加するだけで、驚くべき結果を得られます。ここから、ネットワークを考慮にいれていきます。この記事では、NYCのデータセンターに1GBのRAM、1つのvCPU、および25GBのSSDを搭載したDigital Ocean Dropletサーバーを作成しました。これは、Digital Oceanが提供するハードウェアの最小レベルの仮想マシンです。これにより、ハードウェアに制約のある環境でキャッシングがAPIにもたらす影響を確認することができます。NodeJSのAPIをDropletサーバー上のNginxに配置し、ポート80からNodeJSのポート3000へのプロキシするようにしました。また、MongoDBのローカルインスタンスが実行され、APIのバックエンドとして機能します。その他のソフトウェアはサーバー上で実行されていません。
 
サーバーが返却したレスポンスヘッダーを確認するためにサーバーにリクエストしましょう。ローカルホスト上で実行していないことをNginxバナーが存在することで確認できます。
 
api_part1_image11.png
 
ここでは、同じコマンドラインのSiegeコマンドをDigital Oceanサーバー(IPアドレス)に対して再実行します。
 
$ siege -c 5 -time = 5m -content-type "application / json" GET http://206.81.0.14/cats
 
以下は、APIレスポンスキャッシングをしていないDigital Ocean VPSに対するSiegeの実行結果です
 
api_part1_image12_1.jpg
このテストがローカルでの実行からIaaSプロバイダに対して実行へ変更されている点に注意してください。
  • ヒット件数と取引件数がそれぞれ35%に減少
  • 最初に失敗したトランザクションがあることがわかります。
35%は非常に大きな減少ですが、マルチテナントクラウドプロバイダー上でコードを実行した場合では想定されるケースです。Digital Oceanでapicacheを有効にした場合どのような結果になるかを見てみましょう。以前に説明したときと同様にAPIでレスポンスキャッシングを有効にします。キャッシングを有効にするために、APIに1回のリクエストを行い、Digital Oceanでレスポンスキャッシュが有効になっていることを確認します:
 
api_part1_image13.png
ここでも、キャッシュ制御ヘッダーの値が5分(つまり300秒)であることがわかります。アプリケーションキャッシュを有効にしてDigital Oceanサーバーに対して同じSiegeコマンドを再実行しましょう。
 
$ siege -c 5 -time = 5m -content-type "application / json" GET http://206.81.0.14/cats
 
api_part1_image14_1.jpg
 
今回はキャッシュを有効にすることにより4,932件のトランザクションを完了し、21%高速(63 件 / 秒 vs. 80 件 / 秒)にトランザクションを処理できるようになりました。サーバーは毎回レスポンスを再生成する必要がないため、同じ時間内に多くのデータを配信しました。これは可能な限りAPIレスポンスのキャッシングを有効にすることの価値を明確にしています。
 
APIのレスポンスをキャッシュすべき以下の7つの理由があります。
  1. ほとんどのAPI操作は読み取り操作です。
  2. データが変更されない場合、なぜそれを生成し続ける必要があるかを考慮してください。
  3. クラウドプロバイダーは、IOPSとインスタンスサイズで請求します。
    キャッシュすることでどれだけのコンピュータリソースを減らすことができるかを考慮してください。
  4. ネットワークトラフィックを減らすことができます。
  5. データベースのクエリ/計算コストを削減できます。
  6. オリジンの停止が発生した場合でも、キャッシュされた応答を提供することができます。
  7. 速度制限への依存を減らすことができます。
次にでる疑問は、「何をキャッシュすべきか?」ですが、こちらに一般的なガイドラインがあります。
  • HTTP GET経由でアクセス可能なリソース
  • 静的データ
  • 変更がないレスポンス
  • 頻繁に、または予測可能な間隔で変化するレスポンス
  • 多くのクライアントによって使用されるレスポンス(頻繁に要求されるデータ)
キャッシュの可用性はAPIごとに大きく異なるため、キャッシング戦略を個々のAPIベースで実装することが重要です。1つの方法だけではすべてに適合することができません。Akamai API Gatewayが有効に利用できます。APIゲートウェイの特徴は各API開発者が独立してキャッシュルールを個別に定義できるようにすることです。APIゲートウェイでは、ドメインレベルのキャッシュルールに依存しないため、各API開発者はコンテンツの配信を最適化することができます。
 
これは、APIキャッシングとAkamai API Gatewayに関する2つの記事のうちの最初のものです。上記の情報を基に2番目の記事では、Akamai API Gatewayを使用したアプリケーションキャッシング結果を改善する方法について説明します。 
 
また、APIゲートウェイホームページで多くの役立つ情報を確認してみてください。 
 

Leave a comment