🐥

.NET の DistributedMemoryCache のデフォルトのサイズ制限

に公開

本番ではあまり想定されていないと思われるインメモリのキャッシュの MemoryDistributedCache クラスですが、デフォルトでは 200 MB までのサイズ制限があります。この制限はキャッシュ全体ではなく、キャッシュの 1 つのアイテムのサイズに対して適用されます。

軽く探した感じ、ドキュメント上で明記されている箇所は見つかりませんでしたが、ソースコード上で以下のように定義されています。

https://github.com/dotnet/runtime/blob/aec77dd2f0bb9f57acf94c86077e8fb39583637e/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryDistributedCacheOptions.cs

この時厄介なのが、200 MB を超えるアイテムをキャッシュにセットしたときに例外ではなくサイレントにデータがセットされないという点です。キャッシュなので、キャッシュにデータがなくても処理が正常に動作するように実装されるべきなので、ちゃんと実装していれば問題になることは少ないと思います。

問題になるケース

キャッシュが無いと動かない処理を実装している

上で書いたようにキャッシュはあくまでキャッシュなのでキャッシュが無くても動くように実装するのが一般的ですが、そうはいっても世の中にはキャッシュが無いと動かない実装もあると思います。

HTTP セッションの保存先をメモリにしていて大量データをセットしている

お作法的にどうなの?と思うこともありますが、ASP.NET Core でインメモリにセッションんを保存するようにしていると 1 つのセッションに入っているデータをまとめて 1 つのキャッシュのアイテムとして保存します。そのためセッションが大きくなって 200 MB を超えるとセッションのデータがいきなり消えます。

解決方法

サイズ制限を変更する

MemoryDistributedCacheOptionSizeLimit プロパティを設定することでサイズ制限を変更できます。以下のように Program.csAddDistributedMemoryCache を呼び出す際に SizeLimit を設定することで、サイズ制限を変更できます。

Program.cs
builder.Services.AddDistributedMemoryCache(options =>
{
    // この例では無制限に設定していますが、ちゃんとした値を設定するほうがベター
    options.SizeLimit = null;
});

そんなでかいキャッシュを作らないようにする

そもそもキャッシュが 200 MB を超えるというのがおかしいので、設計を見直すのが個人的にはいいと思います。

まとめ

ということで、あまりハマらないと思いますがハマるとなんで!?ってなる.NET の DistributedMemoryCache のデフォルトのサイズ制限についてでした。

Microsoft (有志)

Discussion