GraphQL APIを手軽に爆速化するならStellateでEdgeキャッシュしよう
こんにちは!ユートニックの衛藤です!
前回の記事でバックエンド全体の概要を書きましたが、今回はその中で利用しているパフォーマンス改善のお話。
パフォーマンス改善といってもその手法は様々で、内容によってはかなりのリファクタ労力が必要になったり、新規開発に圧倒されてなかなか手がつけられなかったりすることも多いかと思います。
サーバー自体の性能を上げる
分散化
プログラムの遅いところを改善する
キャッシュする
など・・・
今回はこの中の「キャッシュする」にフォーカスを当てて改善策を紹介しようと思います。
ユートニックではAPIサーバーとしてGraphQLを採用しています。GraphQLのキャッシュ機構としてApolloのserver-side cachingがありますが、それよりも手軽に利用できる外部サービスでStellate(ステラート)というものがあります。
Stellateについて
Stellateは、クライアントと自前のGraphQLサーバーの間に配置するだけで高機能なEdgeキャッシュをしてくれるサービスで、ある程度のトラフィックまでは無料で利用できます。
2022/11時点では、エンドポイントに制限はなく好きなだけバックエンドにつなげることができます。
Stellateの仕組み
GraphQLレスポンスがのうち、Object Typeに対しユニークなキー(デフォルトは "id", "_id" または "key")があると、そのレスポンスがStellateでtag付けされ、結果がEdgeキャッシュされ、キャッシュがヒットした場合はStellateから直接返されるようになります。ヒットしない場合はGraphQLエンドポイントにリクエストが転送されます。
type Post {
id: ID!
name: String!
}
query {
post(id: "123") { // 次回以降、id: "123"を指定した場合はキャッシュが返されるようになる
id
name
}
}
キャッシュはtype単位、またはquery name単位で設定することができます。
Edgeキャッシュされるため、ヒットした場合は数十msレベルとかなり高速にレスポンスが返されるようになります。
Scopeとしてセッション、Authentication、publicがあり、利用用途に応じてScopeを設定することも可能です。
Stellateの特徴 -Auto Purge-
こちらのDocに説明がありますが、Stellateではmutationリクエストの場合にレスポンスを解析し、Objectに変更があった場合に自動でキャッシュを
purgeされるという特徴があります。
例えば、以下のようなレスポンスがキャッシュされていたとします。
type Post {
id: ID!
name: String!
}
query {
post(id: "123") {
id
name
}
}
そのときに、このようなMutationを実行しPostの内容が変わった場合に、Stellateで自動的に次回のリクエストからは更新されたPostが返されるようになります。
mutation {
// id: "123"のtagが自動でpurgeされる
updatePost(id: "123", name: "changed name") {
id
name
}
}
query {
post(id: "123") {
id
name // "changed name" が返されるようになる
}
}
ただし、レスポンス構造やシステムの設計によってはAuto Purgeの対象とならないケースもあるため、その場合はpurge用の専用Rest APIを実行することでキャッシュをpurgeする必要があるため注意が必要です。注意深く状態変化のテストを行ったほうが良いかと思います。
また、Auto Purgeには以下の通り3つのPolicyが設定できるため、利用ケースによって振る舞いを変えることが可能です。
Entity(デフォルト)
キャッシュされたkey(id: 123など)がレスポンスでマッチした場合にそのtagをpurgeする
List
レスポンスが配列の場合、keyがマッチするかに関わらず全体をpurgeする
DBのCRUDによりListの内容が代わる場合など、キャッシュkeyに関わらずpurgeが必要な場合等に利用
Type
keyがマッチするかに関わらず、Typeがレスポンスに含まれる場合にpurge
この中では一番厳しいAuto Purge
Stellate Config設定(ymlファイル)
Edgeキャッシュの設定はymlまたはjsonファイルを通じてstelalte cliでアップロードします。詳細は公式Docを参照してください。
このconfigファイルで、scope・キャッシュするObject・キャッシュ期間等を細かく設定することができます。
nodeの場合、cli用のpackageが公開されているため、以下のようにcliでconfigを更新することができます。サーバーのデプロイを自動化している場合は、デプロイ後に都度configをpushする処理を入れておけば、設定変更も自動で行われるようになります。
$ npx stellate push --env dev
Stellateのダッシュボード詳細
Stellateでは、利用状況の分析用ダッシュボードが提供されており、キャッシュヒットの全体概要、メトリクス(リクエスト数、レイテンシー、エラー数etc)、Config管理、Alert、Purging状況等を目視で確認することが可能です。
以上、GraphQLを手軽に高速化するための外部サービス Stellate の紹介でした。最後まで読んでいただきありがとうございます!
クライアントからは接続先のエンドポイントを変えるだけなので、サービスに登録して試してみてはいかがでしょうか。