Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

Pool do StackExchange.Redis ConnectionMultiplexer para métodos síncronos


Acho que você está se confundindo aqui. ConnectionMultiplexer não "bloqueia". Criando um ConnectionMultiplexer lhe dá um objeto tipo fábrica com o qual você pode criar IDatabase instâncias. Em seguida, você usa essas instâncias para realizar consultas Redis normais. Você também pode fazer consultas Redis com o próprio multiplexador de conexão, mas essas são consultas de servidor e dificilmente serão feitas com frequência.
Então, para resumir, pode ajudar tremendamente ter um conjunto de multiplexadores de conexão, independentemente da sincronização /async/uso misto.

Para expandir ainda mais, aqui está uma implementação de pool muito simples, que certamente pode ser aprimorada ainda mais:
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;
    }
}