Redis
 sql >> Base de données >  >> NoSQL >> Redis

Pool StackExchange.Redis ConnectionMultiplexer pour les méthodes synchrones

Je pense que vous vous trompez ici. ConnectionMultiplexer n'est pas "bloqué". Création d'un ConnectionMultiplexer vous donne un objet de type usine avec lequel vous pouvez créer IDatabase les instances. Vous utilisez ensuite ces instances pour effectuer des requêtes Redis normales. Vous pouvez également effectuer des requêtes Redis avec le multiplexeur de connexion lui-même, mais ce sont des requêtes de serveur et il est peu probable qu'elles soient effectuées souvent.
Donc, pour faire court, il peut être extrêmement utile d'avoir un pool de multiplexeurs de connexion, quelle que soit la synchronisation /async/usage mixte.

Pour aller plus loin, voici une implémentation de pool très simple, qui peut certainement être encore améliorée :

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;
    }
}