Search code examples
c#rediscachemanager

How to set the Redis Server pool size with the CacheManager?


[C#] How to set the Redis Server pool size with the CacheManager ?

I got an error with high concurrency: No connection is available to service this operation: HMGET , How to set the connection pool size?

No connection is available to service this operation: HMGET U

 at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor`1 processor, ServerEndPoint server)
   at StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProcessor`1 processor, ServerEndPoint server)
   at StackExchange.Redis.RedisDatabase.HashGet(RedisKey key, RedisValue[] hashFields, CommandFlags flags)
   at CacheManager.Redis.RedisCacheHandle`1.<>c__DisplayClass25_0.<GetCacheItemInternal>b__0()
   at CacheManager.Redis.RetryHelper.Retry[T](Func`1 retryme, Int32 timeOut, Int32 retries)
   at CacheManager.Redis.RedisCacheHandle`1.Retry[T](Func`1 retryme)
   at CacheManager.Redis.RedisCacheHandle`1.GetCacheItemInternal(String key, String region)
   at CacheManager.Redis.RedisCacheHandle`1.GetCacheItemInternal(String key)
   at CacheManager.Core.Internal.BaseCache`1.GetCacheItem(String key)
   at CacheManager.Core.BaseCacheManager`1.GetCacheItemInternal(String key, String region)
   at CacheManager.Core.BaseCacheManager`1.GetCacheItemInternal(String key)
   at CacheManager.Core.Internal.BaseCache`1.GetCacheItem(String key)
   at CacheManager.Core.Internal.BaseCache`1.Get(String key)
   at CacheManager.Core.Internal.BaseCache`1.Get[TOut](String key)

=======================

      var cache = CacheFactory.Build("RuntimeCache", settings =>
        {
            settings.WithSystemRuntimeCacheHandle("RuntimeCache")
            .WithExpiration(ExpirationMode.Sliding, TimeSpan.FromMinutes(10))
            .And
            .WithRedisConfiguration("RedisCache", config =>
            {
                config.WithAllowAdmin()
                .WithDatabase(1)
                .WithPassword(password)
                .WithEndpoint(host, port);
            })
            .WithMaxRetries(100)
            .WithRetryTimeout(50)
            .WithRedisBackPlate("RedisCache")   
            .WithRedisCacheHandle("RedisCache", true)
            .WithExpiration(ExpirationMode.Sliding, TimeSpan.FromMinutes(30));
        });

Solution

  • The Stackexchange.Redis doesn't use connection pooling, instead, it uses multiplexing.

    You can change the time the library waits for sync calls (defaults to 1000ms) via configuration => syncTimeout. (To use that with CacheManager, use the connection string based configuration or create your Multiplexer yourself). This might improve your experience.

    Anyways, timeouts and such connection errors are most of the time unrelated to the client and are caused by the single threaded nature of the Redis server, especially if you hit memory limits on the server and Redis tries to remove keys , or if Redis tries to backup to disk...

    I cannot give you a more clear answer as those issues are highly dependent on what you are trying to do and the Redis server you are using...

    You'll find many other q/a about that error, e.g. see StackExchange.Redis timeout and "No connection is available to service this operation"