¿Tiene sentido implementar un grupo ConnectionMultiplexer si lo usamos para métodos síncronos?
Entonces, por grupo me refiero a crear varias instancias de StackExchange.Redis ConnectionMultiplexer, almacenar esos objetos y cuando quiero comunicarme con el servidor Redis, tomo el menos usado del grupo. Esto es para evitar tiempos de espera debido al gran tamaño de la cola según la sugerencia n.º 10 de este artículo: https://azure.microsoft.com/en-us/blog/investigating-timeout-exceptions-in-stackexchange-redis-for- azure-redis-cache/
Tengo dudas porque no estoy seguro de cómo puede ocurrir una cola si connectionMultiplexer bloquea un hilo hasta que regresa una llamada.
Me parece que tener un grupo no tiene sentido con llamadas de método de sincronización, pero los artículos de mejores prácticas de Redis sugieren crear este tipo de grupo independientemente del tipo de método (sincronización/async)
Creo que te estás confundiendo aquí. ConnectionMultiplexer no se "bloquea". La creación de un ConnectionMultiplexer le brinda un objeto similar a una fábrica con el que puede crear instancias IDatabase . A continuación, utiliza estas instancias para realizar consultas normales de Redis. También puede realizar consultas de Redis con el propio multiplexor de conexión, 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 conjunto de multiplexores de conexión, independientemente del uso sincronizado/asincrónico/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; } }