Redis Sentinel:如何在主节点切换时刷新主客户端对象?

4

我已经设置了一个 Redis 副本,其中有一个主节点和两个从节点,并使用 Redis Sentinel 监控每个节点。我正在使用 redis-py 库与主节点和从节点通信。以下是我用于连接主节点和从节点的代码:

from redis.sentinel import Sentinel

sentinel = Sentinel([("localhost", 5000)])  # connect to one of the sentinels
master = sentinel.master_for("mymaster")  # get master object
slave = sentinel.slave_for("mymaster")  # get slave object

现在,我将使用主服务器进行写入操作,从服务器进行读取操作。但问题在于,当发生故障转移时,需要刷新master对象以指向新的主服务器。为此,正如这个答案文档中所述,我应该订阅+switch-master频道以接收新主服务器的地址。
但问题是,我应该使用哪个对象来订阅该频道?我尝试使用以下代码中的master对象:
ps = master.pubsub()
ps.subscribe("+switch-master")

当主服务器宕机时,我尝试以下方式获取信息:

ps.get_message()

但是,由于主服务器宕机,该方法没有返回预期的消息。
sentinel对象不支持pubsub功能。
>>> sentinel.pubsub()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Sentinel' object has no attribute 'pubsub'

作为一种替代方法,在链接的答案中建议使用client-reconfig-script。 但是我应该如何使用外部脚本修改我的应用程序中的对象?
我在这里缺少什么? 我对Redis不熟悉,所以任何参考资料都将不胜感激。

嘿 @Kaushal28,你解决了这个问题吗?我也卡在这里,试图更新redis主对象但没有成功。 - rhoitjadhav
1个回答

0

我不太确定,但也许这样做可以有所帮助

class RedisWithReloadTest(Redis):

    def __init__(self, *args, **kwargs):
        super(RedisWithReloadTest, self).__init__(*args, **kwargs)
        self.sentinel_master_name = None

    def execute_command(self, *args, **kwargs):
        reload = kwargs.pop("reload", False)
        try:
            super().execute_command(*args, **kwargs)
        except ReadOnlyError:
            if reload:
                raise
            master = self.connection_pool.sentinel_manager.master_for(
                self.sentinel_master_name, redis_class=self.__class__
            )
            master.sentinel_master_name = self.sentinel_master_name
            kwargs.update(reload=reload)
            master.execute_command(*args, **kwargs)
            self.__dict__.update(master.__dict__)

    @classmethod
    def from_sentinel(cls, list_of_hosts_and_ports: List[tuple],    master: str):
        sentinel = Sentinel(list_of_hosts_and_ports)
        master = sentinel.master_for(master, redis_class=cls)
        master.app = app
        master.sentinel_master_name = master
        return master

在代码注释或其他方式下添加一些解释,以便他人能够理解它。 - Bunny
您可以通过添加额外的支持信息来改进您的答案。请[编辑]以添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是否正确。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Bunny

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