StackExchange.Redis - 是否可以优先考虑端点?

phi*_*hil 5 c# redis stackexchange.redis

我的设置:

\n\n
    \n
  • 4台Windows服务器
  • \n
  • 每台服务器上都有一个 Redis 节点和一个 Sentinel 进程
  • \n
  • 在每台服务器上部署相同的 Web 应用程序
  • \n
  • Web应用程序通过StackExchange.Redis驱动程序连接到redis服务器
  • \n
\n\n

一切都很好,但我想知道读取操作是否可以始终首先尝试使用本地可用的 Redis 节点。这将大大提高性能,因为所有读取操作的跃点都会减少。

\n\n

据我所知,可以通过命令标志属性将从站优先于主站 f\xc3\xbcr 特定命令。但有没有办法确定特定端点的优先级呢?

\n\n

附:

\n\n

使用的DLL:StackExchange.Redis.StrongName@1.2.0.0

\n\n

Redis服务器版本:3.2.100

\n\n

编辑:

\n\n

这是我的连接代码。我没有使用推荐的 Lazy getter 的原因是因为我想在其中一个节点发生故障时进行连接/重新连接,这非常适合我的解决方案。

\n\n
internal class RedisConnector\n{\n    private readonly ConfigurationOptions _currentConfiguration;\n    internal ConnectionMultiplexer Connection;\n\n    internal RedisCacheStore Store;\n\n    internal RedisConnector(ConfigurationOptions configuration)\n    {\n        _currentConfiguration = configuration;\n        Connect();\n    }\n\n    internal IDatabase Database\n        => Connection.GetDatabase(RedisCacheConfiguration.Instance.Connection.DatabaseId);\n\n    internal IServer Server => Connection.GetServer(Database.IdentifyEndpoint());\n\n    private void Connect()\n    {\n        Connection = ConnectionMultiplexer.Connect(_currentConfiguration);\n        if (Connection == null || !Connection.IsConnected)\n            throw new CacheNotAvailableException();\n        Connection.ConnectionFailed += OnConnectionFailed;\n        Connection.ConnectionRestored += OnConnectionRestored;\n        Store = new RedisCacheStore(Database);\n    }\n\n    private void Reconnect()\n    {\n        if (Connection != null && !Connection.IsConnected)\n            Connection.Dispose();\n        Connect();\n    }\n\n    private void OnConnectionFailed(object sender, ConnectionFailedEventArgs args)\n    {\n        lock (_currentConfiguration)\n        {\n            if (_currentConfiguration.EndPoints.Contains(args.EndPoint))\n            {\n                _currentConfiguration.EndPoints.Remove(args.EndPoint);\n                Reconnect();\n            }\n        }\n    }\n\n    private void OnConnectionRestored(object sender, ConnectionFailedEventArgs args)\n    {\n        lock (_currentConfiguration)\n        {\n            if (!_currentConfiguration.EndPoints.Contains(args.EndPoint))\n            {\n                _currentConfiguration.EndPoints.Add(args.EndPoint);\n                Reconnect();\n            }\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

jeo*_*vre 1

在这种情况下。

假设您有这样的案例,3VM,有 3 个应用程序和 3 个 Redis 实例。
在此输入图像描述 对于在 VM1 中运行 APP 的最佳选择是在 VM1 中使用 Redis。在VM2中运行APP的最佳选择是在VM2中使用Redis。在VM3中运行APP的最佳选择是在VM3中使用Redis。

您可以像这样实现一些规则:

private static Lazy<ConfigurationOptions> configOptions
    = new Lazy<ConfigurationOptions>(() => 
    {
        var configOptions = new ConfigurationOptions();
        configOptions.EndPoints.Add("x.x.x.1:6379");          
        configOptions.EndPoints.Add("x.x.x.2:6379");
        configOptions.EndPoints.Add("x.x.x.3:6379");

        configOptions.ClientName = "LeakyRedisConnection";
        configOptions.ConnectTimeout = 100000;
        configOptions.SyncTimeout = 100000;
        return configOptions;
    });



private static string getIP()
{
    var host = Dns.GetHostEntry(Dns.GetHostName());
    foreach (var ip in host.AddressList)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork)
        {
            return ip.ToString();
        }
    }
    throw new Exception("ip not found!");
}


private static Lazy<ConfigurationOptions> getOptionsForIp(string myip)
        {
            var configOptions = new ConfigurationOptions();
            configOptions.EndPoints.Add(myip);
            configOptions.ClientName = "LeakyRedisConnectionDirectVM";
            configOptions.ConnectTimeout = 100000;
            configOptions.SyncTimeout = 100000;
            return configOptions;
        });


private static ConnectionMultiplexer conn;

private static ConnectionMultiplexer LeakyConn
{
    get
    {
        if (conn == null || !conn.IsConnected){               
            string myIP = getIP();

            conn = ConnectionMultiplexer.Connect(getOptionsForIp(myIP).Value);
            if(conn == null || !conn.IsConnected){
                conn = ConnectionMultiplexer.Connect(configOptions.Value);
            }

        }
        return conn;
    }
}
Run Code Online (Sandbox Code Playgroud)

如何使用此代码:

 var db = LeakyConn.GetDatabase();
 db.StringSet(key, i);
 db.StringGet(key);
Run Code Online (Sandbox Code Playgroud)