はじめに
この記事は、
Speed up your API on Cloud Run with Memorystore caching
という動画を視聴し『実際にやってみた』という記事になります。
この記事でできるようになる事
Cloud Memorystore を使って、API実行を高速化させる。
Cloud Memorystore について簡単に理解しておく
Cloud Memorystoreは、フルマネージドのインメモリデータストアで、
Googleが管理するスケーラブルで安全な高可用性インフラを提供する。
これを使用する事で、データはRAM上に保存され、
高速なアクセス頻度、レイテンシの低減、スケーラビリティを実現できる。
他にも複雑なタスクの自動化や、アプリの可用性への影響を
最小限に抑えながら、インスタンスを容易に拡張できる特徴がある。
また、データの耐障害性の確保や、テータの定期的な
自動バックアップによるデータの復元も容易である。
サポートしているプロダクトには、RedisやMemcachedがあり、
これらの特徴から、Cloud Memorystoreは、Webアプリケーションや
モバイルアプリ、ゲーム、分析ツールなどの多様な用途に適している。
Google Cloud API を有効化
GCPプロジェクトのコンソールへ接続。
Serverless VPC Access API
Cloud Build API
Artifact Registry API
Cloud Run Admin API
これらのAPIを有効化。
その他、APIの有効化は、必要に応じて、適宜行ってください。
sample code を git clone する。
cloud-run-redis を、git clone してください。
git clone https://github.com/GoogleCloudPlatform/serverless-expeditions.git
git cloneの実行が完了したら、cdコマンドを使って、対象のディレクトリ階層へ移動。
cd serverless-expeditions/cloud-run-redis
APIの実行速度が遅い事を確認する。
まずは、Cloud Memorystoreを使用しないで、
どれだけ速度に違いが出るのかを体感する為に、
既に完成形となっているコードを一部修正します。
なお、SERVCICE_NAME は任意のCloud Run Serviceの名前、
regionは最寄りのリージョンを選択して、入力してください。
deploy.sh
GOOGLE_PROJECT_ID=[プロジェクトIDを入力してください。]
SERVICE_NAME=rest-api
#REDIS_HOST=
#REDIS_PORT=
#VPC_CONNECTOR=
gcloud beta run deploy $SERVICE_NAME \
--source . \
--platform managed \
--region asia-northeast1 \
--allow-unauthenticated \
# --update-env-vars REDIS_HOST=$REDIS_HOST,REDIS_PORT=$REDIS_PORT
# --vpc-connector $VPC_CONNECTOR
--project=$GOOGLE_PROJECT_ID

※ deploy.sh を変更する際の注意事項
今回は、Google Cloud Shell上でvimコマンドを使って
直接修正を行なっていますが、下記のErrorがDeploy時に
コンソールへ出力される可能性があります。

このErrorが起こるのは、Windows環境での
改行文字 (\r\n) がUnixやLinux環境での
改行文字 (\n) として認識されていないことが原因との事。
これを解決するためには、以下のコマンドを実行してください。
sed -i 's/\r$//' deploy.sh
index.js
こちらのJSファイルは、一部コードの修正が
必要な箇所近くを抜粋しています。
/*
const redisClient = require('redis').createClient(
process.env.REDIS_PORT,
process.env.REDIS_HOST
);
*/
// Read one artist, by id.
app.get('/artist/:id', async (req, res) => {
try {
const id = req.params.id;
const artist = await getArtistFromDatabase(id);
if (artist) {
res.json(artist);
return;
}
else {
res.status(404).json({error: `Artist ${id} not found`});
}
}
catch(ex) {
res.status(500).json({error: ex.toString()});
}
})

deploy.sh と index.js それぞれコードの修正が終わったら、
Cloud Run Service を Deploy するために下記のコマンドを実行してください。
./deploy.sh
次に、Postmanを起動して、Deployされた
Cloud Run ServiceのURLを確認して、
以下のコマンドを修正して、GET Request を実行。
[Cloud Run Service URL]/artist/1

時間が、3s以上かかっていれば、速度が遅い状態となります。
これを何度か繰り返して行なって、
すべてのRequestが3sかかる事を確認してください。

APIの実行速度を速くする。
APIの実行速度が3s以上かかっている事を確認できたら、
次にAPIの実行速度を上げる為に必要な、
Cloud MemorystoreのDeployを行います。
なお、Cloud Memorystoreは、VPC内に
できる為、外部からのアクセスを受け付けません。
そこで、Cloud Runから仮想プライベートクラウドへ
接続できるように、『サーバレスVPCアクセス」を設定します。
Cloud Memorystoreを設定。
- GCPコンソールからMemorystoreを開いて、
Redisタブを選択した状態で、『インスタンスを作成』を実行。
- インスタンス名をつけて、最寄りリージョン、
ネットワークを選択、残りフィールドはデフォルトのまま『作成』を実行。
ネットワークはdefaultを選択。


サーバレスVPCアクセスを設定
- GCPコンソールからVPCネットワークを開いて、
サーバレスVPCアクセスタブを選択した状態で、『コネクタを作成』を実行。
- 任意のコネクタ名をつけて、最寄りリージョン、ネットワークは
defaultを選択。
- サブネットは『
カスタムIP範囲』を選択して、
推奨値『10.8.0.0』を入力して、『作成』を実行する。
REDIS_HOST, REDIS_PORT には、Deployされた
Memorystoreのプライマリエンドポイントを入力してください。

VPC_CONNECTOR は、Deployされた
サーバレスVPCアクセスの名前を入力してください。

コードは上記の内容を適用させたものになります。
GOOGLE_PROJECT_IDやREDIS_HOSTは、
それぞれ環境ごとに異なる為、そのまま利用しないでください。
deploy.sh
GOOGLE_PROJECT_ID=[プロジェクトIDを入力してください。]
SERVICE_NAME=rest-api
REDIS_HOST=10.44.88.21
REDIS_PORT=6379
VPC_CONNECTOR=my-vpc-connecter
gcloud beta run deploy $SERVICE_NAME \
--source . \
--platform managed \
--region asia-northeast1 \
--allow-unauthenticated \
--update-env-vars REDIS_HOST=$REDIS_HOST,REDIS_PORT=$REDIS_PORT \
--vpc-connector $VPC_CONNECTOR \
--project=$GOOGLE_PROJECT_ID

index.js
こちらのJSファイルは、一部コードの修正が
必要な箇所近くを抜粋しています。
const redisClient = require('redis').createClient(
process.env.REDIS_PORT,
process.env.REDIS_HOST
);
// Read one artist, by id.
app.get('/artist/:id', async (req, res) => {
try {
const id = req.params.id;
const artist = await getArtistFromCache(id);
if (artist) {
res.json(artist);
return;
}
else {
res.status(404).json({error: `Artist ${id} not found`});
}
}
catch(ex) {
res.status(500).json({error: ex.toString()});
}
})
deploy.shとindex.jsの修正が完了したら、
続けて以下のコマンドを実行して、
Cloud Run Serviceの再Deployを行なってください。
./deploy.sh
再DeployされたCloud Run ServiceをPostmanを使って実行。
最初のRequestは、3s以上かかりますが、
2回目以降は速くなっていることを確認できればOK。

Memorystoreを利用して、キャッシュからRequestされた結果が返されている状態。

終わりに
今回の記事は、動画を視聴しまして、
実際に『手を動かしてみた』という内容でまとめました。
Cloud Memorystoreを利用することで、
一度、Requestされたデータをキャッシュに残すことが、
可能となり、処理の高速化を確認できました。
APIの実行にかかる時間が遅いと
感じていれば、Cloud Memorystoreを
検討するのも良いかもしれません。
Cloud Memorystoreがどのようなものか、
試してみたい人は、参考にしていただけると幸いです。
あとで『じっくり読みたい』、『繰り返し読みたい』と
思ってくれましたら、『ストック』へ登録、
この記事が読まれている方にとって、
参考になる記事となりましたら、『いいね』を
付けていただけますと、励みになりますので、
よろしくお願いします。

