redis主从结构最小高可用方案

redis是后端服务开发中常用中的缓存中间件,其以高性能、易用性而在互联网、金融等领域广泛使用。大流量业务可以使用redis多主多从集群模式,数据分片存储到不同节点上;小型服务可以使用redis的一主一从结构,然后再使用redis-sentinel进行高可用部署,基本就能满足要求。下面简单说下,如何用最小的资源部署高可用的redis主从结构。

一句话结论

最少需要三台独立的服务器,才能部署高可用的redis一主一从结构。

具体部署方式

  • 服务器A:部署redis主节点 + redis哨兵节点
  • 服务器B:部署redis从节点 + redis哨兵节点
  • 服务器C:部署redis哨兵节点

上面的部署架构,无论哪台宕机,都不会影响redis对外提供服务。

  • A宕机,B、C服务器上的哨兵节点检测到A宕机,三个哨兵服务共三票,B+C共两票,占了大多数,故将B上升为主节点,继续对外提供服务。这也是为何哨兵节点要部署奇数个的原因,防止出现一半对一半的脑裂问题,选不出主节点。
  • B宕机,本来就是备节点,不影响redis服务
  • C宕机,本来上面就没有redis服务,更不影响redis服务

当然如果已经挂掉1台了,就不再是高可用状态了,需尽快补充节点进去。

详细步骤

  1. 安装redis-server

    apt update && apt install redis-server
  2. 部署redis主从
    默认配置文件路径/etc/redis/

    • 启动redis主
      配置文件:redis-server1.conf

          port 6379
          bind 0.0.0.0
          dir "/data/redis"
          appendonly yes

      可以配置systemd服务,或者直接使用命令启动:

          nohup redis-server  redis-server1.conf > redis-server1.log 2>&1 &
    • 启动redis从
      配置文件: redis-server2.conf

          port 6380
          bind 0.0.0.0
          dir "/data/redis"
          appendonly yes
          replicaof XX.XX.XX.XX(redis主的地址) 6379

      启动:

          nohup redis-server  redis-server2.conf > redis-server2.log 2>&1 &

      redis主从启动之后,主从之间会自动开启同步。

  3. 部署哨兵节点
    配置文件:sentinel1.conf

        port 26379
        dir "/tmp"
        sentinel deny-scripts-reconfig yes
        sentinel monitor mymaster XX.XX.XX.XX(redis主的ip) 6379 2
        sentinel down-after-milliseconds mymaster 5000

    上面配置了,默认的redis主节点ip和端口和检测超时的时间,启动命令如下:

        nohup redis-server  sentinel1.conf --sentinel > sentinel1.log 2>&1 &   

    再按照上面方式启动另外两个sentinel节点。启动日志如下:

    244533:X 28 Nov 2025 15:32:26.644 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    244533:X 28 Nov 2025 15:32:26.644 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=244533, just started
    244533:X 28 Nov 2025 15:32:26.644 # Configuration loaded
    244533:X 28 Nov 2025 15:32:26.644 * Increased maximum number of open files to 10032 (it was originally set to 1024).
    244533:X 28 Nov 2025 15:32:26.644 * Running mode=sentinel, port=26379.
    244533:X 28 Nov 2025 15:32:26.678 # Sentinel ID is 0c255a19ca146bdfc29a50f56e89b3ba143ade44
    244533:X 28 Nov 2025 15:32:26.679 # +monitor master mymaster XX.XX.XX.XX 6379 quorum 2
    244533:X 28 Nov 2025 15:32:26.679 * +slave slave XX.XX.XX.XX:6380 XX.XX.XX.XX 6380 @ mymaster XX.XX.XX.XX 6379
  4. 模拟宕机
    可以kill掉redis主进程,看看是否会主从切换,如下日志,可以看到6380端口的redis主宕掉,然后两个哨兵节点进行选举得到2票,之后把6379端口的redis升级为主节点。

    244552:X 28 Nov 2025 15:47:53.579 # +sdown master mymaster XX.XX.XX.XX 6380
    244552:X 28 Nov 2025 15:47:53.579 # +sdown sentinel 0c255a19ca146bdfc29a50f56e89b3ba143ade44 XX.XX.XX.XX 26379 @ mymaster XX.XX.XX.XX 6380
    244552:X 28 Nov 2025 15:47:53.646 # +odown master mymaster XX.XX.XX.XX 6380 #quorum 2/2
    244552:X 28 Nov 2025 15:47:53.646 # +new-epoch 2
    244552:X 28 Nov 2025 15:47:53.646 # +try-failover master mymaster XX.XX.XX.XX 6380
    244552:X 28 Nov 2025 15:47:53.670 # +vote-for-leader cc50f37eb9de672f18319b6c49f295ea5cf66963 2
    244552:X 28 Nov 2025 15:47:53.703 # 6902261baed2421f1e4b0542d0d3ad5e4cc7a396 voted for cc50f37eb9de672f18319b6c49f295ea5cf66963 2
    244552:X 28 Nov 2025 15:47:53.732 # +elected-leader master mymaster XX.XX.XX.XX 6380
    244552:X 28 Nov 2025 15:47:53.732 # +failover-state-select-slave master mymaster XX.XX.XX.XX 6380
    244552:X 28 Nov 2025 15:47:53.784 # +selected-slave slave XX.XX.XX.XX:6379 XX.XX.XX.XX 6379 @ mymaster XX.XX.XX.XX 6380
    244552:X 28 Nov 2025 15:47:53.785 * +failover-state-send-slaveof-noone slave XX.XX.XX.XX:6379 XX.XX.XX.XX 6379 @ mymaster XX.XX.XX.XX 6380
    244552:X 28 Nov 2025 15:47:53.851 * +failover-state-wait-promotion slave XX.XX.XX.XX:6379 XX.XX.XX.XX 6379 @ mymaster XX.XX.XX.XX 6380
    244552:X 28 Nov 2025 15:47:54.753 # +promoted-slave slave XX.XX.XX.XX:6379 XX.XX.XX.XX 6379 @ mymaster XX.XX.XX.XX 6380
    244552:X 28 Nov 2025 15:47:54.753 # +failover-state-reconf-slaves master mymaster XX.XX.XX.XX 6380
    244552:X 28 Nov 2025 15:47:54.801 # +failover-end master mymaster XX.XX.XX.XX 6380
    244552:X 28 Nov 2025 15:47:54.801 # +switch-master mymaster XX.XX.XX.XX 6380 XX.XX.XX.XX 6379
    244552:X 28 Nov 2025 15:47:54.801 * +slave slave XX.XX.XX.XX:6380 XX.XX.XX.XX 6380 @ mymaster XX.XX.XX.XX 6379  
  5. 模拟客户端读写
    java、python等语言都有成熟的支持redis-sentinel的组件,无需在业务代码做操作。如下python示例,需要pip install redis
    下面代码,会依次尝试连接指定的sentinel地址,如果超时就尝试下一个;连接sentinel之后,再获取到真正的redis主从示例,进行读写操作;即使redis发生主从切换,redis-py会感知到变化,然后进行切换;当然在流量较大的时候,可能会短时间报错。

        from redis.sentinel import Sentinel
    
        sentinel = Sentinel (
            [
                ("XX.XX.XX.XX", 26379),
                ("XX.XX.XX.XX", 26380),
                ("XX.XX.XX.XX", 26381)
            ],
            socket_timeout=1
        )
    
        master = sentinel.master_for('mymaster')
        slave = sentinel.slave_for('mymaster')
        master.set("age", 15)
        print(slave.get('name'))
        print(slave.get('age'))
版权声明

本站文章、图片、视频等(除转载外),均采用知识共享署名 4.0 国际许可协议(CC BY-NC-SA 4.0),转载请注明出处、非商业性使用、并且以相同协议共享。

© 空空博客,本文链接:https://www.yeetrack.com/?p=1729