Redis
 sql >> Datenbank >  >> NoSQL >> Redis

StackExchange.Redis ConnectionMultiplexer-Pool für synchrone Methoden

Ich glaube du verwechselst dich hier. ConnectionMultiplexer wird nicht "geblockt". Erstellen eines ConnectionMultiplexer gibt Ihnen ein Factory-ähnliches Objekt, mit dem Sie IDatabase erstellen können Instanzen. Anschließend verwenden Sie diese Instanzen, um normale Redis-Abfragen durchzuführen. Sie können Redis-Abfragen auch mit dem Verbindungsmultiplexer selbst durchführen, aber das sind Serverabfragen und werden wahrscheinlich nicht oft durchgeführt.
Um es kurz zu machen, es kann enorm hilfreich sein, einen Pool von Verbindungsmultiplexern zu haben, unabhängig von der Synchronisierung /async/mixed use.

Zur weiteren Erweiterung hier eine sehr einfache Pool-Implementierung, die sicherlich weiter verbessert werden kann:

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