StackExchange.Redis - 是否可以对端点进行优先级排序?
StackExchange.Redis - Is it possible to prioritize Endpoints?
我的设置:
- 4 Windows 个服务器
- 每个服务器上的 Redis 节点和哨兵进程
- 在每台服务器上部署相同的网络应用程序
- Web 应用程序通过 StackExchange.Redis 驱动程序连接到 Redis 服务器
一切正常,但我想知道读取操作是否有可能始终尝试首先使用本地可用的 redis 节点。这会大大提高性能,因为所有读取操作的跃点都会减少。
据我所知,可以通过命令标志 属性 将奴隶优先于主人 für 特定命令。 但是有没有办法确定特定端点的优先级?
PS:
使用的 DLL:StackExchange.Redis.StrongName@1.2.0.0
Redis 服务器版本:3.2.100
编辑:
这是我的连接代码。我没有使用推荐的 Lazy getter 的原因是因为我想 Connect/Reconnect 在一个节点失败时,这对我的解决方案非常有效。
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();
}
}
}
}
在这种情况下。
假设您有这种情况,3 个虚拟机,3 个应用程序和 3 个 redis 实例。
APP运行在VM1中最好的选择是在VM1中使用Redis。
APP运行在VM2中最好的选择是在VM2中使用Redis。
APP运行在VM3中最好的选择是在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;
}
}
如何使用此代码:
var db = LeakyConn.GetDatabase();
db.StringSet(key, i);
db.StringGet(key);
我的设置:
- 4 Windows 个服务器
- 每个服务器上的 Redis 节点和哨兵进程
- 在每台服务器上部署相同的网络应用程序
- Web 应用程序通过 StackExchange.Redis 驱动程序连接到 Redis 服务器
一切正常,但我想知道读取操作是否有可能始终尝试首先使用本地可用的 redis 节点。这会大大提高性能,因为所有读取操作的跃点都会减少。
据我所知,可以通过命令标志 属性 将奴隶优先于主人 für 特定命令。 但是有没有办法确定特定端点的优先级?
PS:
使用的 DLL:StackExchange.Redis.StrongName@1.2.0.0
Redis 服务器版本:3.2.100
编辑:
这是我的连接代码。我没有使用推荐的 Lazy getter 的原因是因为我想 Connect/Reconnect 在一个节点失败时,这对我的解决方案非常有效。
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();
}
}
}
}
在这种情况下。
假设您有这种情况,3 个虚拟机,3 个应用程序和 3 个 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;
}
}
如何使用此代码:
var db = LeakyConn.GetDatabase();
db.StringSet(key, i);
db.StringGet(key);