My setup:
- 4 Windows servers
- A Redis Node and a Sentinel Process on each of theses servers
- The same webapplication deployed on each of these servers
- The webapplication connects to the redis servers via the StackExchange.Redis driver
Everything works great but I wonder if it is possible for read operations to always try to use the redis node that is locally available first. This would enhance performance quite a bit because there would be fewer hops for all read operations.
As far as I see one can prioritize slaves over masters für specific commands via the Command Flags property. But is there a way to prioritize specific endpoints?
PS:
Used DLL: StackExchange.Redis.StrongName@1.2.0.0
Redis Server Version: 3.2.100
EDIT:
Here is my connection code. The reason why I did not use the recommended Lazy getter is because I wanted to Connect/Reconnect on Failure of one of the nodes, which works very well with my solution.
internal class RedisConnector
{
private readonly ConfigurationOptions _currentConfiguration;
internal ConnectionMultiplexer Connection;
internal RedisCacheStore Store;
internal RedisConnector(ConfigurationOptions configuration)
{
_currentConfiguration = configuration;
Connect();
}
internal IDatabase Database
=> Connection.GetDatabase(RedisCacheConfiguration.Instance.Connection.DatabaseId);
internal IServer Server => Connection.GetServer(Database.IdentifyEndpoint());
private void Connect()
{
Connection = ConnectionMultiplexer.Connect(_currentConfiguration);
if (Connection == null || !Connection.IsConnected)
throw new CacheNotAvailableException();
Connection.ConnectionFailed += OnConnectionFailed;
Connection.ConnectionRestored += OnConnectionRestored;
Store = new RedisCacheStore(Database);
}
private void Reconnect()
{
if (Connection != null && !Connection.IsConnected)
Connection.Dispose();
Connect();
}
private void OnConnectionFailed(object sender, ConnectionFailedEventArgs args)
{
lock (_currentConfiguration)
{
if (_currentConfiguration.EndPoints.Contains(args.EndPoint))
{
_currentConfiguration.EndPoints.Remove(args.EndPoint);
Reconnect();
}
}
}
private void OnConnectionRestored(object sender, ConnectionFailedEventArgs args)
{
lock (_currentConfiguration)
{
if (!_currentConfiguration.EndPoints.Contains(args.EndPoint))
{
_currentConfiguration.EndPoints.Add(args.EndPoint);
Reconnect();
}
}
}
}