sentinel监控redis的主节点和备份节点,并监控sentinel伙伴节点,
当redis主节点发生故障后,sentinel节点一起投票选举出redis主节点,
并进行redis主从节点切换,以达到高可用目的。
redis节点有多个,sentinel节点有多个,sentinel节点是最清楚
当前redis主节点和从节点的状态的,python redis客户端通过sentinel创建连接,
不管redis节点如何变化,都能得到主节点和从节点,从而不需要改动python代码,
灵活操作redis。
   

操作系统: CentOS Linux release 7.6.1810
    ip:       127.0.0.1
    服务端:  Redis server v=5.0.3
    客户端:  python 连接redis插件版本 redis-3.2.0

0、redis安装

a、下载redis-5.0.3.tar.gz
    b、tar xvzf redis-5.0.3.tar.gz
    c、cd redis-5.0.3/
    d、make PREFIX=/user/local/redis install

1、配置redis节点

a、端口1111 主节点配置文件 /etc/redis-conf/redis1111.conf 内容如下:
        bind 127.0.0.1
        port 1111
        daemonize no #通过supervisor管理,不用守护方式启动
        requirepass "m-SDFdfle90IUD&)+U" #当前节点密码
        logfile "/home/logs/redis/1111.log" #redis日志
        dbfilename "dump-1111.rdb" #redis存储的文件
        dir "/home/redis/db" #redis存储文件的目录
        
        replicaof 127.0.0.1 1111
        
        #配置主服务器的masterauth属性,
        #因为后续主节点由于下线会变成从节点,
        #所以这里也要配置,否则后续主节点恢复故障后,无法切换
        masterauth "m-SDFdfle90IUD&)+U"
        
        
    b、端口2222 从节点 配置文件 /etc/redis-conf/redis2222.conf 内容如下:
        bind 127.0.0.1
        port 2222
        daemonize no #通过supervisor管理,不用守护方式启动
        requirepass "m-SDFdfle90IUD&)+U" #当前节点密码
        logfile "/home/logs/redis/2222.log" #redis日志
        dbfilename "dump-2222.rdb" #redis存储的文件
        dir "/home/redis/db" #redis存储文件的目录
        
        replicaof 127.0.0.1 1111
        
        #配置主服务器的masterauth属性,
        masterauth "m-SDFdfle90IUD&)+U"
    
    
    c、端口3333 从节点 配置文件 /etc/redis-conf/redis3333.conf 内容如下:
        bind 127.0.0.1
        port 3333
        daemonize no #通过supervisor管理,不用守护方式启动
        requirepass "m-SDFdfle90IUD&)+U" #当前节点密码
        logfile "/home/logs/redis/3333.log" #redis日志
        dbfilename "dump-3333.rdb" #redis存储的文件
        dir "/home/redis/db" #redis存储文件的目录
        
        replicaof 127.0.0.1 1111

        #配置主服务器的masterauth属性,
        masterauth "m-SDFdfle90IUD&)+U"


    d、supervisor启动三个redis节点命令
        /usr/local/bin/redis-server /etc/redis-conf/redis1111.conf
        /usr/local/bin/redis-server /etc/redis-conf/redis2222.conf
        /usr/local/bin/redis-server /etc/redis-conf/redis3333.conf

        
2、sentinel节点配置
   

a、第一个sentinel节点配置文件 /etc/redis-conf/sentinel_1.conf
        port 9111
        daemonize no
        logfile "sentinel_1.log"
        dir "/home/logs/redis"
        sentinel monitor mymaster 127.0.0.1 1111 2
        #redis数据master节点设置了认证,则需要如下配置
        sentinel auth-pass mymaster m-SDFdfle90IUD&)+U
        sentinel down-after-milliseconds mymaster 5000
        sentinel parallel-syncs mymaster 1
        sentinel failover-timeout mymaster 180000
    
    b、第二个sentinel节点配置文件 /etc/redis-conf/sentinel_2.conf
        port 9222
        daemonize no
        logfile "sentinel_2.log"
        dir "/home/logs/redis"
        sentinel monitor mymaster 127.0.0.1 1111 2
        #redis数据master节点设置了认证,则需要如下配置
        sentinel auth-pass mymaster m-SDFdfle90IUD&)+U
        sentinel down-after-milliseconds mymaster 5000
        sentinel parallel-syncs mymaster 1
        sentinel failover-timeout mymaster 180000
    
    c、第三个sentinel节点配置文件 /etc/redis-conf/sentinel_3.conf
        port 9333
        daemonize no
        logfile "sentinel_3.log"
        dir "/home/logs/redis"
        sentinel monitor mymaster 127.0.0.1 1111 2
        #redis数据master节点设置了认证,则需要如下配置
        sentinel auth-pass mymaster m-SDFdfle90IUD&)+U
        sentinel down-after-milliseconds mymaster 5000
        sentinel parallel-syncs mymaster 1
        sentinel failover-timeout mymaster 180000

    
    d、通过supervisor启动3个sentinel节点的命令如下:
        /usr/local/bin/redis-sentinel /etc/redis-conf/sentinel_1.conf 
        /usr/local/bin/redis-sentinel /etc/redis-conf/sentinel_2.conf 
        /usr/local/bin/redis-sentinel /etc/redis-conf/sentinel_3.conf 
        
    
    f、检查3个节点的运行状态
        redis-cli -h 127.0.0.1 -p 9111 info sentinel
        # Sentinel
        sentinel_masters:1
        sentinel_tilt:0
        sentinel_running_scripts:0
        sentinel_scripts_queue_length:0
        sentinel_simulate_failure_flags:0
        master0:name=mymaster,status=ok,address=127.0.0.1:1111,slaves=2,sentinels=3

        
        redis-cli -h 127.0.0.1 -p 9222 info sentinel
        # Sentinel
        sentinel_masters:1
        sentinel_tilt:0
        sentinel_running_scripts:0
        sentinel_scripts_queue_length:0
        sentinel_simulate_failure_flags:0
        master0:name=mymaster,status=ok,address=127.0.0.1:1111,slaves=2,sentinels=3
        
        
        redis-cli -h 127.0.0.1 -p 9333 info sentinel
        # Sentinel
        sentinel_masters:1
        sentinel_tilt:0
        sentinel_running_scripts:0
        sentinel_scripts_queue_length:0
        sentinel_simulate_failure_flags:0
        master0:name=mymaster,status=ok,address=127.0.0.1:1111,slaves=2,sentinels=

3、python连接测试
   

from redis.sentinel import Sentinel
    sentinel = Sentinel([
            ('127.0.0.1', 9111),
            ('127.0.0.1', 9222),
            ('127.0.0.1', 9333),
            ],
            socket_timeout=0.5
        )
    master = sentinel.discover_master('mymaster') #得到redis master节点的信息
    ('127.0.0.1', 1111 )
    slave = sentinel.discover_slaves('mymaster') #得到redis 所有从节点的信息
    [ ('127.0.0.1', 2222),('127.0.0.1', 3333)]
    
    #得到主节点连接
    master = sentinel.master_for('mymaster', socket_timeout=0.5, password='m-SDFdfle90IUD&)+U')
    master.set("k","v")
    #得到从节点连接
    slave = sentinel.slave_for('mymaster', socket_timeout=0.5, password='m-SDFdfle90IUD&)+U')
    slave.get("k")

        >>> slave.set("k6","v6")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "build/bdist.linux-x86_64/egg/redis/client.py", line 1451, in set
      File "build/bdist.linux-x86_64/egg/redis/client.py", line 775, in execute_command
      File "build/bdist.linux-x86_64/egg/redis/client.py", line 789, in parse_response
      File "build/bdist.linux-x86_64/egg/redis/sentinel.py", line 56, in read_response
      File "build/bdist.linux-x86_64/egg/redis/connection.py", line 642, in read_response
    redis.exceptions.ReadOnlyError: You can't write against a read only replica.
    
    注意:
        当有从节点的时候,是不能执行更新操作的,如果只有主节点,没有从节点,sentinel.slave_for
    获取的节点是主节点,是可以执行更新操作的

4、关掉1111主节点
   

supervisorctl stop redis-server-m-1111
    
    查看日志tail -f /home/logs/redis/*.log:
    
    ==> /var/log/redis/sentinel_1111.log <==
    26890:X 31 Aug 2020 19:39:31.204 # +sdown master mymaster 127.0.0.1 1111
    
    ==> /var/log/redis/sentinel_2222.log <==
    26894:X 31 Aug 2020 19:39:31.219 # +sdown master mymaster 127.0.0.1 1111
    
    ==> /var/log/redis/sentinel_3333.log <==
    26897:X 31 Aug 2020 19:39:31.226 # +sdown master mymaster 127.0.0.1 1111
    
    ==> /var/log/redis/sentinel_2222.log <==
    26894:X 31 Aug 2020 19:39:31.290 # +odown master mymaster 127.0.0.1 1111 #quorum 2/2
    26894:X 31 Aug 2020 19:39:31.290 # +new-epoch 8
    26894:X 31 Aug 2020 19:39:31.290 # +try-failover master mymaster 127.0.0.1 1111
    26894:X 31 Aug 2020 19:39:31.294 # +vote-for-leader db29dc803706e24d4ba744fde7986b9855ae4cb5 8
    
    ==> /var/log/redis/sentinel_1111.log <==
    26890:X 31 Aug 2020 19:39:31.296 # +new-epoch 8
    
    ==> /var/log/redis/sentinel_3333.log <==
    26897:X 31 Aug 2020 19:39:31.296 # +new-epoch 8
    
    ==> /var/log/redis/sentinel_1111.log <==
    26890:X 31 Aug 2020 19:39:31.299 # +vote-for-leader db29dc803706e24d4ba744fde7986b9855ae4cb5 8
    
    ==> /var/log/redis/sentinel_3333.log <==
    26897:X 31 Aug 2020 19:39:31.299 # +vote-for-leader db29dc803706e24d4ba744fde7986b9855ae4cb5 8
    26897:X 31 Aug 2020 19:39:31.299 # +odown master mymaster 127.0.0.1 1111 #quorum 3/2
    
    ==> /var/log/redis/sentinel_2222.log <==
    26894:X 31 Aug 2020 19:39:31.299 # de0d06fdeb8f3ea146a519f1c7571584f3f422a5 voted for db29dc803706e24d4ba744fde7986b9855ae4cb5 8
    
    ==> /var/log/redis/sentinel_3333.log <==
    26897:X 31 Aug 2020 19:39:31.299 # Next failover delay: I will not start a failover before Mon Aug 31 19:45:31 2020
    
    ==> /var/log/redis/sentinel_2222.log <==
    26894:X 31 Aug 2020 19:39:31.299 # e16204d26a678a613b0c0e9d18a5f2f35efe523c voted for db29dc803706e24d4ba744fde7986b9855ae4cb5 8
    26894:X 31 Aug 2020 19:39:31.365 # +elected-leader master mymaster 127.0.0.1 1111
    26894:X 31 Aug 2020 19:39:31.365 # +failover-state-select-slave master mymaster 127.0.0.1 1111
    26894:X 31 Aug 2020 19:39:31.421 # +selected-slave slave 127.0.0.1:3333 127.0.0.1 3333 @ mymaster 127.0.0.1 1111
    26894:X 31 Aug 2020 19:39:31.421 * +failover-state-send-slaveof-noone slave 127.0.0.1:3333 127.0.0.1 3333 @ mymaster 127.0.0.1 1111
    26894:X 31 Aug 2020 19:39:31.497 * +failover-state-wait-promotion slave 127.0.0.1:3333 127.0.0.1 3333 @ mymaster 127.0.0.1 1111
    26894:X 31 Aug 2020 19:39:31.825 # +promoted-slave slave 127.0.0.1:3333 127.0.0.1 3333 @ mymaster 127.0.0.1 1111
    26894:X 31 Aug 2020 19:39:31.825 # +failover-state-reconf-slaves master mymaster 127.0.0.1 1111
    26894:X 31 Aug 2020 19:39:31.876 * +slave-reconf-sent slave 127.0.0.1:2222 127.0.0.1 2222 @ mymaster 127.0.0.1 1111
    
    ==> /var/log/redis/sentinel_3333.log <==
    26897:X 31 Aug 2020 19:39:31.877 # +config-update-from sentinel db29dc803706e24d4ba744fde7986b9855ae4cb5 127.0.0.1 9222 @ mymaster 127.0.0.1 1111
    26897:X 31 Aug 2020 19:39:31.877 # +switch-master mymaster 127.0.0.1 1111 127.0.0.1 3333
    26897:X 31 Aug 2020 19:39:31.877 * +slave slave 127.0.0.1:2222 127.0.0.1 2222 @ mymaster 127.0.0.1 3333
    26897:X 31 Aug 2020 19:39:31.877 * +slave slave 127.0.0.1:1111 127.0.0.1 1111 @ mymaster 127.0.0.1 3333
    
    ==> /var/log/redis/sentinel_1111.log <==
    26890:X 31 Aug 2020 19:39:31.878 # +config-update-from sentinel db29dc803706e24d4ba744fde7986b9855ae4cb5 127.0.0.1 9222 @ mymaster 127.0.0.1 1111
    26890:X 31 Aug 2020 19:39:31.878 # +switch-master mymaster 127.0.0.1 1111 127.0.0.1 3333
    26890:X 31 Aug 2020 19:39:31.878 * +slave slave 127.0.0.1:2222 127.0.0.1 2222 @ mymaster 127.0.0.1 3333
    26890:X 31 Aug 2020 19:39:31.878 * +slave slave 127.0.0.1:1111 127.0.0.1 1111 @ mymaster 127.0.0.1 3333
    
    ==> /var/log/redis/sentinel_2222.log <==
    26894:X 31 Aug 2020 19:39:32.438 # -odown master mymaster 127.0.0.1 1111
    26894:X 31 Aug 2020 19:39:32.863 * +slave-reconf-inprog slave 127.0.0.1:2222 127.0.0.1 2222 @ mymaster 127.0.0.1 1111
    26894:X 31 Aug 2020 19:39:32.863 * +slave-reconf-done slave 127.0.0.1:2222 127.0.0.1 2222 @ mymaster 127.0.0.1 1111
    26894:X 31 Aug 2020 19:39:32.953 # +failover-end master mymaster 127.0.0.1 1111
    26894:X 31 Aug 2020 19:39:32.953 # +switch-master mymaster 127.0.0.1 1111 127.0.0.1 3333
    26894:X 31 Aug 2020 19:39:32.953 * +slave slave 127.0.0.1:2222 127.0.0.1 2222 @ mymaster 127.0.0.1 3333
    26894:X 31 Aug 2020 19:39:32.954 * +slave slave 127.0.0.1:1111 127.0.0.1 1111 @ mymaster 127.0.0.1 3333
    
    ==> /var/log/redis/sentinel_3333.log <==
    26897:X 31 Aug 2020 19:40:01.890 # +sdown slave 127.0.0.1:1111 127.0.0.1 1111 @ mymaster 127.0.0.1 3333
    
    ==> /var/log/redis/sentinel_1111.log <==
    26890:X 31 Aug 2020 19:40:01.955 # +sdown slave 127.0.0.1:1111 127.0.0.1 1111 @ mymaster 127.0.0.1 3333
    
    ==> /var/log/redis/sentinel_2222.log <==
    26894:X 31 Aug 2020 19:40:03.039 # +sdown slave 127.0.0.1:1111 127.0.0.1 1111 @ mymaster 127.0.0.1 3333

    
5、python查看当前状态
    >>> sentinel.discover_master('mymaster')
    ('127.0.0.1', 3333)

    >>> sentinel.discover_slaves('mymaster')
    [('127.0.0.1', 2222)]
    发现主redis已经切换成3333节点了,1111故障节点也移除了,2222从节点也切换了主redis节点

6、继续关掉3333主节点
    supervisorctl stop redis-server-d-3333       

查看日志tail -f /home/logs/redis/*.log:
    ==> /var/log/redis/sentinel_1111.log <==
    26890:X 31 Aug 2020 19:47:21.842 # +sdown master mymaster 127.0.0.1 3333
    
    ==> /var/log/redis/sentinel_3333.log <==
    26897:X 31 Aug 2020 19:47:21.846 # +sdown master mymaster 127.0.0.1 3333
    
    ==> /var/log/redis/sentinel_2222.log <==
    26894:X 31 Aug 2020 19:47:21.860 # +sdown master mymaster 127.0.0.1 3333
    26894:X 31 Aug 2020 19:47:21.912 # +odown master mymaster 127.0.0.1 3333 #quorum 3/2
    26894:X 31 Aug 2020 19:47:21.912 # +new-epoch 9
    26894:X 31 Aug 2020 19:47:21.912 # +try-failover master mymaster 127.0.0.1 3333
    26894:X 31 Aug 2020 19:47:21.915 # +vote-for-leader db29dc803706e24d4ba744fde7986b9855ae4cb5 9
    
    ==> /var/log/redis/sentinel_3333.log <==
    26897:X 31 Aug 2020 19:47:21.918 # +new-epoch 9
    
    ==> /var/log/redis/sentinel_1111.log <==
    26890:X 31 Aug 2020 19:47:21.918 # +new-epoch 9
    
    ==> /var/log/redis/sentinel_3333.log <==
    26897:X 31 Aug 2020 19:47:21.921 # +vote-for-leader db29dc803706e24d4ba744fde7986b9855ae4cb5 9
    
    ==> /var/log/redis/sentinel_2222.log <==
    26894:X 31 Aug 2020 19:47:21.921 # e16204d26a678a613b0c0e9d18a5f2f35efe523c voted for db29dc803706e24d4ba744fde7986b9855ae4cb5 9
    
    ==> /var/log/redis/sentinel_1111.log <==
    26890:X 31 Aug 2020 19:47:21.921 # +vote-for-leader db29dc803706e24d4ba744fde7986b9855ae4cb5 9
    
    ==> /var/log/redis/sentinel_2222.log <==
    26894:X 31 Aug 2020 19:47:21.921 # de0d06fdeb8f3ea146a519f1c7571584f3f422a5 voted for db29dc803706e24d4ba744fde7986b9855ae4cb5 9
    
    ==> /var/log/redis/sentinel_3333.log <==
    26897:X 31 Aug 2020 19:47:21.946 # +odown master mymaster 127.0.0.1 3333 #quorum 2/2
    26897:X 31 Aug 2020 19:47:21.946 # Next failover delay: I will not start a failover before Mon Aug 31 19:53:21 2020
    
    ==> /var/log/redis/sentinel_2222.log <==
    26894:X 31 Aug 2020 19:47:21.977 # +elected-leader master mymaster 127.0.0.1 3333
    26894:X 31 Aug 2020 19:47:21.977 # +failover-state-select-slave master mymaster 127.0.0.1 3333
    26894:X 31 Aug 2020 19:47:22.068 # +selected-slave slave 127.0.0.1:2222 127.0.0.1 2222 @ mymaster 127.0.0.1 3333
    26894:X 31 Aug 2020 19:47:22.068 * +failover-state-send-slaveof-noone slave 127.0.0.1:2222 127.0.0.1 2222 @ mymaster 127.0.0.1 3333
    26894:X 31 Aug 2020 19:47:22.144 * +failover-state-wait-promotion slave 127.0.0.1:2222 127.0.0.1 2222 @ mymaster 127.0.0.1 3333
    26894:X 31 Aug 2020 19:47:22.391 # +promoted-slave slave 127.0.0.1:2222 127.0.0.1 2222 @ mymaster 127.0.0.1 3333
    26894:X 31 Aug 2020 19:47:22.391 # +failover-state-reconf-slaves master mymaster 127.0.0.1 3333
    26894:X 31 Aug 2020 19:47:22.487 # +failover-end master mymaster 127.0.0.1 3333
    26894:X 31 Aug 2020 19:47:22.487 # +switch-master mymaster 127.0.0.1 3333 127.0.0.1 2222
    26894:X 31 Aug 2020 19:47:22.487 * +slave slave 127.0.0.1:1111 127.0.0.1 1111 @ mymaster 127.0.0.1 2222
    26894:X 31 Aug 2020 19:47:22.487 * +slave slave 127.0.0.1:3333 127.0.0.1 3333 @ mymaster 127.0.0.1 2222
    
    ==> /var/log/redis/sentinel_3333.log <==
    26897:X 31 Aug 2020 19:47:22.490 # +config-update-from sentinel db29dc803706e24d4ba744fde7986b9855ae4cb5 127.0.0.1 9222 @ mymaster 127.0.0.1 3333
    26897:X 31 Aug 2020 19:47:22.490 # +switch-master mymaster 127.0.0.1 3333 127.0.0.1 2222
    26897:X 31 Aug 2020 19:47:22.490 * +slave slave 127.0.0.1:1111 127.0.0.1 1111 @ mymaster 127.0.0.1 2222
    26897:X 31 Aug 2020 19:47:22.490 * +slave slave 127.0.0.1:3333 127.0.0.1 3333 @ mymaster 127.0.0.1 2222
    
    ==> /var/log/redis/sentinel_1111.log <==
    26890:X 31 Aug 2020 19:47:22.490 # +config-update-from sentinel db29dc803706e24d4ba744fde7986b9855ae4cb5 127.0.0.1 9222 @ mymaster 127.0.0.1 3333
    26890:X 31 Aug 2020 19:47:22.490 # +switch-master mymaster 127.0.0.1 3333 127.0.0.1 2222
    26890:X 31 Aug 2020 19:47:22.490 * +slave slave 127.0.0.1:1111 127.0.0.1 1111 @ mymaster 127.0.0.1 2222
    26890:X 31 Aug 2020 19:47:22.490 * +slave slave 127.0.0.1:3333 127.0.0.1 3333 @ mymaster 127.0.0.1 2222
    
    ==> /var/log/redis/sentinel_3333.log <==
    
    ==> /var/log/redis/sentinel_1111.log <==
    
    ==> /var/log/redis/sentinel_3333.log <==
    26897:X 31 Aug 2020 19:47:52.496 # +sdown slave 127.0.0.1:3333 127.0.0.1 3333 @ mymaster 127.0.0.1 2222
    26897:X 31 Aug 2020 19:47:52.496 # +sdown slave 127.0.0.1:1111 127.0.0.1 1111 @ mymaster 127.0.0.1 2222
    
    ==> /var/log/redis/sentinel_1111.log <==
    26890:X 31 Aug 2020 19:47:52.526 # +sdown slave 127.0.0.1:3333 127.0.0.1 3333 @ mymaster 127.0.0.1 2222
    26890:X 31 Aug 2020 19:47:52.526 # +sdown slave 127.0.0.1:1111 127.0.0.1 1111 @ mymaster 127.0.0.1 2222
    
    ==> /var/log/redis/sentinel_2222.log <==
    26894:X 31 Aug 2020 19:47:52.575 # +sdown slave 127.0.0.1:1111 127.0.0.1 1111 @ mymaster 127.0.0.1 2222
    26894:X 31 Aug 2020 19:47:52.575 # +sdown slave 127.0.0.1:3333 127.0.0.1 3333 @ mymaster 127.0.0.1 2222

7、python查看当前状态
    >>> sentinel.discover_master('mymaster')
    ('127.0.0.1', 2222)
    >>> sentinel.discover_slaves('mymaster')
    []
    发现主节点切换为2222了,从节点已经没有了
    
    要注意一下,从节点为空的时候
    slave = sentinel.slave_for('mymaster', socket_timeout=0.5, password='m-SDFdfle90IUD&)+U')
    save对象操作的是主节点
    从节点不为空的时候,执行更新操作是不允许的,
    为空的时候由于是操作的是主节点,所以可以执行更新操作
    
    >>> slave.get("k4")
    >>> slave.set("k4","v4")
    True
    >>> slave.get("k4")
    'v4'

8、查看连接数

    lsof -i:1111|grep redis-ser|wc -l

    或者登入之后通过 info clients 查看