Momento Cacheを使ってデータベースを高速化する
データベースと一緒にキャッシュを使用することで、アプリケーションのパフォーマンスと可用性を大幅に向上させることができます。頻繁にアクセスされるデータをキャッシュに保存することで、データベースへの負荷を軽減し、応答時間の短縮、可用性の向上、コストの削減につながります。
キャッシュをデータベースと組み合わせて使う方法は複数ある。主なパターンは read-aside
と write-through
キャッシュの 2 つです。このガイドでは、これらのパターンと Momento Cache を使った実装方法を説明します。
どのようなキャッシュパターンでも、キャッシュアイテムのTTL(Time to Live)を調整することが重要です。TTLは、データがキャッシュから削除されるまでの保存期間を決定します。適切なTTLを設定することで、キャッシュ内のデータを最新の状態に保つことができます。短すぎるTTLを選ぶと頻繁なキャッシュ・ミスを引き起こす可能性があり、長すぎるTTLを選ぶと古いデータが提供される可能性があります。適切なTTLを決定することは、アプリケーション、キャッシュされるデータ、そしてそのデータがどのように使用されるかに依存します。
リード・アサイド・キャッシング
リード・アサイド・キャッシングとは、アプリケーションがまずキャッシュに必要なデータがあるかどうかをチェックするパターンです。キャッシュにデータが見つからない場合、アプリケーションはデータベースからデータをフェッチし、将来の使用のためにキャッシュに保存します。このパターンは、同じデータが頻繁にアクセスされる、読み込みの多いアプリケーションに便利です。
リード・アサイド・キャッシングの利点
- Faster reads: キャッシュのヒット率が高いと仮定すると、ほとんどのリクエストはデータベースをヒットする必要がなく、結果として読み込みが速くなります。
- Higher availability: リード・アサイド・キャッシングはデータベースへの負荷を軽減し、アプリケーションの可用性を向上させることができます。
Momentoによるリード・アサイド・キャッシング
Momento を使うと、アプリケーションにリードアサイドキャッシュを簡単に実装できます。キャッシュからデータを取得するには get
API を、キャッシュにデータを保存するには set
API を使用します。
- JavaScript
- Python
- Go
const cachedValue = (await cacheClient.get('test-cache', 'test-key')).value();
if (cachedValue !== undefined) {
console.log(`Cache hit for key 'test-key': ${cachedValue}`);
return cachedValue;
} else {
console.log("Key 'test-key' was not found in cache 'test-cache', checking in database...");
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const actualValue = database.get('test-key')!;
await cacheClient.set('test-cache', 'test-key', actualValue);
return actualValue;
}
get_response = await cache_client.get("test-cache", "test-key")
match get_response:
case CacheGet.Hit() as hit:
print(f"Retrieved value for key 'test-key': {hit.value_string}")
return
print(f"cache miss, fetching from database")
actual_value = database.get("test-key")
await cache_client.set("test-cache", "test-key", actual_value)
return
key := uuid.NewString()
resp, err := client.Get(ctx, &momento.GetRequest{
CacheName: cacheName,
Key: momento.String(key),
})
if err != nil {
panic(err)
}
switch r := resp.(type) {
// cache hit
case *responses.GetHit:
return r.ValueString()
}
// lookup value in database
val := database[key]
client.Set(ctx, &momento.SetRequest{
CacheName: cacheName,
Key: momento.String(key),
Value: momento.String(val),
})
return val
リード・アサイド・キャッシングの欠点
- Cache misses: もしデータがキャッシュに適切にセットされていなければ、キャッシュミスが多発し、余計なapiコールが発生することになり、アプリケーションが遅くなる可能性があります。
- Stale data: データベースのデータが頻繁に更新される場合、キャッシュに古いデータが含まれる可能性があります。これは、キャッシュ項目に適切なTTLを設定することで軽減できます。