Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

274
Views
StackExchange.Redis ConnectionMultiplexer pool for synchronous methods

Does implementing a ConnectionMultiplexer pool make sense if we use it for synchronous methods?

So by pool I mean creating multiple instances of StackExchange.Redis ConnectionMultiplexer, storing those objects and when I want to communicate with Redis server I take the least used one from the pool. This is to prevent timeouts due to large queue size as per No. 10 suggestion in this article: https://azure.microsoft.com/en-us/blog/investigating-timeout-exceptions-in-stackexchange-redis-for-azure-redis-cache/

I'm having doubts because I'm not sure how can a queue even happen if connectionMultiplexer blocks a thread until a call returns.

It seems to me that having a pool is pointless with sync method calls, but Redis best practice articles suggest creating this kind of pool regardless of method type (sync/async)

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

I think you're getting confused here. ConnectionMultiplexer does not "get blocked". Creating a ConnectionMultiplexer gives you a factory-like object with which you can create IDatabase instances. You then use these instances to perform normal Redis queries. You can also do Redis queries with the connection multiplexer itself, but those are server queries and unlikely to be done often.
So, to make things short, it can help tremendously to have a pool of connection multiplexers, regardless of sync/async/mixed usage.


To expand further, here's a very simple pool implementation, which can certainly be enhanced further:

public interface IConnectionMultiplexerPool
{
    Task<IDatabase> GetDatabaseAsync();
}

public class ConnectionMultiplexerPool : IConnectionMultiplexerPool
{
    private readonly ConnectionMultiplexer[] _pool;
    private readonly ConfigurationOptions _redisConfigurationOptions;

    public ConnectionMultiplexerPool(int poolSize, string connectionString) : this(poolSize, ConfigurationOptions.Parse(connectionString))
    {
    }

    public ConnectionMultiplexerPool(int poolSize, ConfigurationOptions redisConfigurationOptions)
    {
        _pool = new ConnectionMultiplexer[poolSize];
        _redisConfigurationOptions = redisConfigurationOptions;
    }

    public async Task<IDatabase> GetDatabaseAsync()
    {
        var leastPendingTasks = long.MaxValue;
        IDatabase leastPendingDatabase = null;

        for (int i = 0; i < _pool.Length; i++)
        {
            var connection = _pool[i];

            if (connection == null)
            {
                _pool[i] = await ConnectionMultiplexer.ConnectAsync(_redisConfigurationOptions);

                return _pool[i].GetDatabase();
            }

            var pending = connection.GetCounters().TotalOutstanding;

            if (pending < leastPendingTasks)
            {
                leastPendingTasks = pending;
                leastPendingDatabase = connection.GetDatabase();
            }
        }

        return leastPendingDatabase;
    }
}
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!