Momentoはフルスケーラブルで簡単に使うことが出来るキャッシュサービスです。AWSのDynamoDBやS3のように事前の準備やサイジング、スケールへの心配なく、キャッシュストアを簡単にプロビジョニングするだけですぐに書き込みや読み込みが可能になります。いわゆるフルサーバーレスなキャッシュサービスですね。
少し前までは米国リージョンを中心に展開されていましたが、最近、東京リージョンでサービスがリリースされたとのことです。
AWSでサーバーレスな開発を普段してる方は感じているかもしれませんが、AWS Lambdaから使いやすいキャッシュストアが欲しくなるケースは結構あります。例えば以下のようなケースです。
- ハイトラフィックなシステムの場合に、Rate Limit対策として外部APIのレスポンス結果をキャッシュさせてLambda間で使い回す
- セッションデータなどをLambda間で共有する
この記事では実際にLambdaでMomentoを使ってこれらのユースケースに使えそうか見ていきましょう。
アカウントの発行
ローカルにCLIをインストールしてサインアップします。GitHub上にCLIのドキュメントがあるので本記事ではこれを参考にしています。まずはbrewでMomentoのCLIを以下のようにインストールしましょう。
brew tap momentohq/tap
brew install momento-cli
その後サインアップのコマンドを実行すると登録したメールアドレス宛にクレデンシャルが届きます。これでサインアップ自体は完了します。東京リージョンで使用する場合には以下のようにap-northeast-1を指定してください。
momento account signup --email <your email> --region ap-northeast-1
ローカル環境から試してみる
ローカル環境からCLI経由でキャッシュの読み書きを試してみましょう。最初にconfigureコマンドでCLIにクレデンシャル等のセットアップを行います。対話式でクレデンシャルやdefaultのTTLなどを設定していきます。
momento configure
その後、createコマンドでキャッシュストアをプロビジョニングすることで、直ぐに書き込みと読み込みのオペレーションが可能になります。
momento cache create --name example-cache
momento cache set --key key --value value --ttl 100 --name example-cache
momento cache get --key key --name example-cache
Lambda上で試してみる
では、Momentoを使って以下のような簡単なサンプルをAPI GatewayとLambda開発してみようと思います。
- 特定のキーでキャッシュがヒットしなければ、キャッシュをセットする
- 特定のキーでキャッシュがヒットすれば、その値をレスポンスする
2022/03/11現在Momentoは以下のSDKが公開されているようです。
- JavaScript
- Python
- Java
- .NET
- Go
- Rust(近日公開予定)
今回はJavaScript SDKのサンプルに沿ってMomentoを動かしてみました。ソースコードは以下のとおりです。TTLを60秒に設定して、最初にキャッシュの有無を確認。存在しなければ、setメソッドでキャッシュを登録して、存在すればその値を返すという実装になっています。
import type { ValidatedEventAPIGatewayProxyEvent } from '@libs/api-gateway';
import { formatJSONResponse } from '@libs/api-gateway';
import { middyfy } from '@libs/lambda';
import { SimpleCacheClient, CacheGetStatus } from "@momento/sdk";
import schema from './schema';
const hello: ValidatedEventAPIGatewayProxyEvent<typeof schema> = async (event) => {
// your authentication token for momento
const authToken = process.env.MOMENTO_AUTH_TOKEN;
// initializing momento
const DEFAULT_TTL = 60; // 60 seconds for default ttl
const momento = new SimpleCacheClient(authToken, DEFAULT_TTL);
const CACHE_NAME = "example-cache-store";
const res = await momento.get(CACHE_NAME, "key");
if (res.status === CacheGetStatus.Miss) {
await momento.set(CACHE_NAME, "key", "example-value");
return formatJSONResponse({
message: 'New cache data has been set.',
});
}
return formatJSONResponse({
message: 'The cache data was found.',
value: res.text(),
});
};
export const main = middyfy(hello);
動作確認してみると以下のように意図通り動きました。