キャッシュは、空間を利用して時間を短縮する手法であり、応答時間を効率的に短縮することができます。asp.net coreではローカルメモリキャッシュと分散キャッシュが導入されています。
まず、ローカルメモリキャッシュについて見てみましょう:
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Internal;
var builder = WebApplication.CreateBuilder(args);
// メモリキャッシュサービスを注入し、キャッシュ容量を40に設定
builder.Services.AddMemoryCache(opt =>{
opt.SizeLimit = 40;
});
var app = builder.Build();
// キャッシュを検索
app.MapGet("/get/{id}", (IMemoryCache memoryCache, string id) =>{
var result = memoryCache.TryGetValue(id, out string timeStr);
if (result)
{
return $"取得成功:{timeStr}";
}
return "取得失敗";
});
// キャッシュを構成し、サイズを10とする
app.MapGet("/set/{id}", (IMemoryCache memoryCache, string id) =>{
var time = memoryCache.Set<string>(id, $"{id}、 {DateTime.Now}", new MemoryCacheEntryOptions
{
Size = 10
});
return $"設定された時間: {time}";
});
app.Run();
SizeLimit=40は総キャッシュ容量であり、Size=10はこのキャッシュが占有する容量です。毎回10の場合、最大で4つ生成できます。ここで問題があり、バグかもしれませんが、5番目を追加すると、5番目は成功せず、最初の1つが削除されます(最も長くアクセスされていないものが削除される)。この時、有効なキャッシュは3つのみで、再び5番目を追加すると、それが有効になります。
キャッシュの設定時には、SlidingExpirationとAbsoluteExpirationRelativeToNowを設定でき、以下のように使用します:
var time = memoryCache.Set<string>(id, $"{id}、 {DateTime.Now}", new MemoryCacheEntryOptions{
// 3秒間アクセスがなければ期限切れ
SlidingExpiration = TimeSpan.FromSeconds(3),
// 3秒以内に継続的にアクセスがあれば、30秒で期限切れ
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(30),
});
複数のレプリカをデプロイする場合、メモリキャッシュは適していません。現在の主流は、redisのようなNoSQLデータベースを使用してデータを高速にキャッシュすることです。ここではredisを例に、ローカルのdockerでredisをインストールし、次のコマンドで起動します:docker run --name some-redis -d -p 6379:6379 redis
。appsettings.jsonの設定は以下の通りです:
"ConnectionStrings": {
"MyRedisConStr": "127.0.0.1:6379"
}
具体的な実装コードは非常にシンプルです:
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Internal;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddStackExchangeRedisCache(options =>{
options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr");
options.InstanceName = "DistributedRedis_";
});
var app = builder.Build();
app.MapGet("/disget/{id}", async (IDistributedCache distributedCache, string id) => {
var result = await distributedCache.GetStringAsync(id);
return $"取得成功:{result}";
});
app.MapGet("/disset/{id}", async (IDistributedCache distributedCache, string id) =>{
var time = $"{id}、 {DateTime.Now}";
await distributedCache.SetStringAsync(id, time, new DistributedCacheEntryOptions
{
SlidingExpiration = TimeSpan.FromSeconds(5),
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(30)
});
return $"設定された時間: {time}";
});
app.Run();
キャッシュの使用法は非常にシンプルですが、何がキャッシュに適しており、どのくらいの時間キャッシュするべきか、キャッシュが失効した場合にシステムにどのような負担がかかるかなどの問題を考慮する必要があります。
(Translated by GPT)