StackExchange.Redis - Is it possible to prioritize Endpoints?

Viewed 2799

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();
            }
        }
    }
}
1 Answers
Related