Redis主从互备及切换

目录

    一,条件:

    二,哨兵:

    三,redis 配置:

    四,sentinel 配置:

    五,代码例子:


主从互备:

    一,条件:

2台设备,(注意主从角色只是暂时的)

        主角色:master 192.168.58.14

        从角色:slave 192.168.58.4

    二,哨兵:

3个 sentinel 哨兵实例,master 两个,slave 一个 ()

最佳实践和考虑因素:

  1. 最小数量

    • Sentinel 的最小推荐数量是 3。这是因为 Sentinel 使用 Raft 一致性算法来决定何时执行故障转移,而 Raft 需要大多数节点的同意来进行决策。至少需要三个 Sentinel 实例可以在一个实例失效时仍然保持决策能力。
  2. 奇数规则

    • 最好配置奇数个 Sentinel 实例。这样可以更容易地达到“多数派”决策,从而避免在网络分区情况下的脑裂问题(即两个子网络各自认为自己是有效的主节点)。例如,有 3 个 Sentinel 实例时,即使一个实例无法通信,剩余两个仍然可以形成多数派进行决策。
  3. 网络分布

    • 如果可能,将 Sentinel 实例分布在不同的物理服务器或至少在不同的虚拟机上。这样可以防止单点故障影响多个 Sentinel 实例,比如一台物理服务器的故障导致多个 Sentinel 实例同时失效。
  4. 与 Redis 服务器的关系

    • Sentinel 实例可以与 Redis 服务器共存于同一硬件上,但在生产环境中,最好将它们分开部署以避免资源争用和提高故障隔离性。

        Redis Sentinel 集群依赖于所谓的“多数派”(quorum)来做出决策,特别是对故障转移操作。Quorum 是一个配置参数(一般为奇数),代表执行故障转移前必须同意该操作的最小 Sentinel 数量。通常,这个值至少是 Sentinel 总数的一半加一,以确保决策的有效性和防止脑裂。

  • 如果有三个 Sentinel,你可能设置了一个 quorum 值为 2。
  • 如果两个 Sentinel 异常退出,剩下的一个 Sentinel 将无法达到 quorum。因此,即使它独自认为主节点已经下线,也无法自主进行故障转移操作。

    三,redis 配置:

        主:

            bind 0.0.0.0

            protected-mode no

            requirepass yourMasterPassword

            masterauth yourMasterPassword

            找到并注释掉slaveof这一行(如果存在)

        从:

            bind 0.0.0.0

            protected-mode no

            requirepass YourMasterPassword

            masterauth yourMasterPassword

            slaveof master_ip master_port

           

    四,sentinel 配置:

        主:

            【/etc/redis-sentinel1.conf 配置】

            port 26379

            daemonize no

            sentinel monitor ml_redismaster 192.168.58.14 6379 2

            sentinel auth-pass ml_redismaster bird

            sentinel down-after-milliseconds ml_redismaster 30000

            sentinel parallel-syncs ml_redismaster 1

            sentinel failover-timeout ml_redismaster 180000

            sentinel deny-scripts-reconfig yes

            logfile /var/log/redis/sentinel1.log

            pidfile /var/run/redis-sentinel1.pid

            dir /tmp

            【/etc/redis-sentinel2.conf 配置】

            port 26380

            daemonize no

            sentinel monitor ml_redismaster 192.168.58.14 6379 2

            sentinel auth-pass ml_redismaster bird

            sentinel down-after-milliseconds ml_redismaster 30000

            sentinel parallel-syncs ml_redismaster 1

            sentinel failover-timeout ml_redismaster 180000

            sentinel deny-scripts-reconfig yes

            logfile /var/log/redis/sentinel2.log

            pidfile /var/run/redis-sentinel2.pid

            dir /tmp

        从:

            【/etc/redis-sentinel.conf 配置】

            port 26379

            daemonize no

            sentinel monitor ml_redismaster 192.168.58.14 6379 2  

            sentinel auth-pass ml_redismaster bird

            sentinel down-after-milliseconds ml_redismaster 30000

            sentinel parallel-syncs ml_redismaster 1

            sentinel failover-timeout ml_redismaster 180000

            sentinel deny-scripts-reconfig yes

            logfile /var/log/redis/sentinel.log

            pidfile /var/run/redis-sentinel.pid

            dir /tmp

       

        关键配置说明:

        sentinel monitor xxx quorum(法定数),即至少需要2个 Sentinel 同意主服务器不可用时才会触发故障转移)

    验证:

        redis-cli -p 26379 sentinel master ml_redismaster

        redis-cli -p 26379 sentinel slaves ml_redismaster

        redis-cli -h 192.168.58.4 -p 6379 -a bird info replication  查看该节点角色

    五,代码例子:

        import time

        import random

        from redis.sentinel import Sentinel

        from redis.exceptions import ConnectionError

        # 配置Sentinel

        sentinel = Sentinel([

            ('192.168.58.14', 26379),

            ('192.168.58.14', 26380),

            ('192.168.58.4', 26379)

        ], socket_timeout=0.1, password='bird')

        def get_master_slave(sentinel, master_name):

            """ 获取主从服务器的连接 """

            try:

                master = sentinel.master_for(master_name, socket_timeout=0.1, password='bird')

                slave = sentinel.slave_for(master_name, socket_timeout=0.1, password='bird')

                return master, slave

            except ConnectionError:

                print("连接主服务器失败,正在尝试重新连接...")

                return None, None

        master_name = 'ml_redismaster'

        master, slave = get_master_slave(sentinel, master_name)

        try:

            while True:

                if not master:

                    # 如果主服务器连接失败,则尝试重新获取

                    master, slave = get_master_slave(sentinel, master_name)

                    if not master:

                        print("故障转移可能正在进行,等待后重试...")

                        time.sleep(1)

                        continue

                # 生成随机键值对

                key = f"key{random.randint(1, 10000)}"

                value = f"value{random.randint(1, 10000)}"

                try:

                    # 写入操作

                    master.set(key, value)

                    # 读取操作

                    retrieved_value = slave.get(key)

                    print(f"Set {key} to {value}, retrieved {retrieved_value}")

                except ConnectionError as e:

                    print(f"操作失败: {e}")

                    master, slave = None, None  # 重置连接

                # 休眠一秒,模拟实际操作间隔

                time.sleep(0.5)

        except KeyboardInterrupt:

            print("测试被用户中断。")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值