StackExchange.Redis - 如何在运行时更改配置?

3
基本上,我有一个"不要这样做"的Sentinel方案。因为在这种情况下Sentinel是不安全的,所以我实施了以下措施。
var main   = "192.168.XXX.YY:6379,abortConnect=false";
var backup = "192.168.XXX.YY:6379,abortConnect=false";

IConnectionMultiplexer redis = ConnectionMultiplexer.Connect(main);

redis.ConnectionFailed += (src, args) =>
{
    if ((src as ConnectionMultiplexer).Configuration != backup) {
        using (var writer = new StringWriter()) {
            writer.Write(backup);

            (src as ConnectionMultiplexer).Configure(writer);
            /**
              * Just for checking. It does not save
              **/
            (src as ConnectionMultiplexer).GetDatabase().StringSet("aaa", "bbb");
        }
    }
};

当我的主要连接断开时,我通过调用 (src as ConnectionMultiplexer).Configure(writer) 来更改配置,以便 ConnectionMultiplexer 可以使用新配置。然而,ConnectionMultiplexer 仍然继续使用旧的配置。
问题:在 ConnectionFailed 事件中如何更改 ConnectionMultiplexer.configuration?
2个回答

2
我查看了这个库的源代码,似乎没有所需的功能。虽然有一个名为Reconfigure的内部方法,但它试图从配置中连接到其他服务器。
如果你的应用程序不是非常大,我建议你进行重构。在ConnectionMultiplexer上创建一个包装器,将其传递给需要使用连接的对象。我们包装了GetConnection方法,该方法返回单个对象上的所有链接。所有需要连接的人都会调用此方法,无需存储连接。在包装器内部,订阅OnFailed事件处理程序以创建到备份的新连接。

0

不确定这是否可接受,不完全是切换配置,而更像是重建多路复用器

private static Lazy<IConnectionMultiplexer> _redisMux = new Lazy<ConnectionMultiplexer>(CreateMultiplexer);
public static IConnectionMultiplexer Multiplexer { get { return _redisMux.Value; } }

private const string Main   = "192.168.XXX.YY:6379,abortConnect=false";
private const string Backup = "192.168.XXX.YY:6379,abortConnect=false";

private static string ActiveConfig = Main;

private static ConnectionMultiplexer CreateMultiplexer()
{
    var mux = ConnectionMultiplexer.Connect(ActiveConfig));
    mux.ConnectionFailed += OnConnectionFailed;

    return mux;
}

[MethodImpl(MethodImplOptions.Synchronized)]
private static void OnConnectionFailed(object sender, ConnectionFailedEventArgs e)
{
    ActiveConfig = Backup;

    try { Multiplexer.Dispose(); } catch { }
    _redisMux = new Lazy<ConnectionMultiplexer>(CreateMultiplexer);
}

最明显的答案,但我需要保留同一实例,因为它分布在整个应用程序中。也许一个事件可以通知所有的订阅者,但我的应用程序的某些部分不能改变它们的原始行为,包括ConnectionMultiplexer的引用。无论如何,谢谢。 - Arthur Ronald
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Ismail Hawayel
如果我设置两个连接,我最终会遇到多个主节点的问题。在这种情况下,StackExchange.redis使用TieBreaker的概念来解决“主”主节点。我不确定这样的功能是否能够安全解决我的问题。我将在周一进行检查。 - Arthur Ronald
@IsmailHawayel 有进展吗?我只是希望能够更改 Redis 凭据/连接信息,而无需手动重新启动每个使用 Redis 的已部署应用程序。我希望只需更改保存连接信息的一个配置位置,所有站点将自动更新,无需进行部署。 - Terry
@IsmailHawayel 实际上,我找到了一个解决方案,通过替换IDistributedCache单例并使用Polly回退策略。 - Terry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接