Creo que te estás confundiendo aquí. ConnectionMultiplexer
no se "bloquea". Creando un ConnectionMultiplexer
te da un objeto similar a una fábrica con el que puedes crear IDatabase
instancias. A continuación, utiliza estas instancias para realizar consultas normales de Redis. También puede realizar consultas de Redis con el multiplexor de conexión en sí, pero esas son consultas de servidor y es poco probable que se realicen con frecuencia.
Entonces, para resumir, puede ser de gran ayuda tener un grupo de multiplexores de conexión, independientemente de la sincronización. /async/uso mixto.
Para ampliar aún más, aquí hay una implementación de grupo muy simple, que sin duda se puede mejorar aún más:
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;
}
}