MichaCo / CacheManager

CacheManager is an open source caching abstraction layer for .NET written in C#. It supports various cache providers and implements many advanced features.
http://cachemanager.michaco.net
Apache License 2.0
2.34k stars 457 forks source link

[Question] High memory usage with Redis under high load normal? #258

Closed knepe closed 5 years ago

knepe commented 5 years ago

Hi Not sure if this is really an issue but I find it abit worrying so I want to ask if this is normal, hence this question :)

I have an API which uses Redis only. If I loadtest it with lets say 300 concurrent users hitting one method which only retrieves an object from the cache (pretty simple object), the memory goes up and down alot, 400mb > 700mb, down to 500mb and up to 1000mb in a matter of seconds. After awhile it seems to be more stable, but pretty high (over 2gb). Also the number of threads grows alot and never seem to be released (it follows the number of concurrent users, maybe thats normal, but dont see this behaviour with InMemory cache). I'm using expirationmode sliding so the cache never gets expired (because of the high load). So there's only Get happening. I tried adding InMemory cache and using Redis as backplane, and this seemed more "stable", but the CPU was high instead (~75% vs ~30% with only Redis). The number of threads were very low and memory very low aswell, also the request times were alot faster (but that is expected)

I register my CacheManager like this (StructureMap): var cacheManager = CacheFactory.FromConfiguration<object>(tenant.Configuration.CacheManagerConfiguration); config.ForSingletonOf<ICacheManager<object>>().Use(cacheManager);

Are there any issues with <object> there? The only reason why I have it like that is that I don't want to worry about what type the cache item is

MichaCo commented 5 years ago

Hi, If you have a high concurrent read count, using an in-memory cache on top of Redis is highly advisable. Obviously, doing tons of concurrent Gets to Redis does a lot of networking, eventually de-serialization etc... For memory and task/thread usage, is seems high, but also depends on how many requests per second you really do I guess, and also, how large the cached data is.

I cannot really give any other advice without more concrete examples than just use in-memory + Redis.