redis主从哨兵sentineljedis(代码片段)

有且仅有 有且仅有     2022-12-07     555

关键词:

上篇说到了Redis安装、运行。今天来看一看Redis的主从复制、Sentinel;


一、主从复制

1. 配置

Master上修改redis.conf

// 不想用密码,所以把保护模式设置为no
protected-mode no
// 其实master上不需要配置什么,这里只是取消了保护模式

Slave1Slave2上修改redis.conf

// 同样关闭保护模式
protected-mode no
// 设置本机是谁的slave
slaveof master的ip 6379
// 当配置了slaveof后,下面这条控制本机只能读
slave-read-only yes

2. Jedis操作

    // 简单设置3个连接池
    private static final JedisPool masterPool;
    private static final JedisPool slavePool1;
    private static final JedisPool slavePool2;
    static 
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最多可以有10个连接
        jedisPoolConfig.setMaxTotal(10);
        jedisPoolConfig.setMaxIdle(5);
        jedisPoolConfig.setMinIdle(5);
        masterPool = new JedisPool(jedisPoolConfig, "111.111.111.111");
        slavePool1 = new JedisPool(jedisPoolConfig, "111.111.111.112");
        slavePool2 = new JedisPool(jedisPoolConfig, "111.111.111.113");
    

    public static void main(String[] args) throws Exception 
        // 简单使用,通过try-with-resource
        try (Jedis jedis = masterPool.getResource()) 
            jedis.get("key1");
         catch (Exception e) 
            e.printStackTrace();
        
    

3. 主从的意义

  1. Redis需要读写分离吗?
    可能大家会思考过这样一个问题,在MySQL中常用的读写分离,在Redis这种内存DB中是否还会需要?

    反对者的观点是:Redis是内存存储,读写都非常快,如果将读且分离到MasterSlaves上不仅可能造成主从不同步的麻烦,甚至不见得会提升整个DB的处理能力和速度。

    赞成者的观点是:Redis提供的MasterSlave复制功能;官网中的介绍

    Replication can be used both for scalability, in order to have multiple slaves for read-only queries (for example, slow O(N) operations can be offloaded to slaves), or simply for data redundancy.

    甚至配置文件中的参数slave-read-only yes都在提示着使用者,Redis给你提供了读写分离的功能。所以,为什么不要用呢?

    经过思考过后,我觉得:

    1 如果使用者的业务数据量不大,则完全不必做读写分离,读写均在Master上做即可。但是主从复制还是需要的,可将Slave作为简单的数据转储。
    2 如果使用者的业务数据量比较大,只用一个物理机Master承担读写已不能满足业务或性能的需求,那么则可以做读且分离。即,在项目代码中封装一下对Redis的操作(如封装Jedis操作),将写操作映射给Master,将读操作按照你自己定义的分配策略,映射给某个Slave


一个企业级系统最重要的指标就是“可用性”和“高性能”。

显然,上面的主从复制、读写分离能够简单的提供“高性能”,但也只是提升了“读”的性能,并不能扩展“写”。(写的扩展这里暂且不表)

另一方面,“可用性”也是极其重要的。如上结构可用性并不高,一旦Master宕机则Redis将立即不可写,Slave将只剩下旧数据,系统随即不可用。
必然的,Redis提供了高可用(High Availability)方案,其中之一就是Sentinel-哨兵。


二、Sentinel - 高可用

1. 什么是Sentinel?

见名知意,它是Redis提供的哨兵程序,它是分布式程序,可以这样描述它们:

哨兵一般是好几个一起站岗,他们共同监视一个Master以及其Slaves。当哨兵看到Master挂掉了,他们就会互相确认有没有看走眼,一旦多数哨兵都说它挂了,那么他们就能得出结论:Master挂了。
此时第一个发现的Sentinel会负责进行自动故障迁移,它会立即在Slaves中选出一个担任Master,所有Slaves从属于新Master,所有客户端对Master的操作转而到这台新Master上。

Sentinel的主要工作如下:

  1. 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。

  2. 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。

  3. 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。

2. 配置Sentinel

哨兵应该被放在独立的服务器上,最好最少应该有3个哨兵(3台服务器)。

  1. 配置文件sentinel.conf

    // 26379模式是sentinel的运行端口,6379是redis-server的
    port 26379
    // 作为守护进程
    daemonize yes
    // 工作目录,设置到你统一规划的地方
    dir /tmp
    // log文件
    dir /....
    
    // protected-mode必须要设置的,不设置不行
    protected-mode no
    
    // 配置监视的Master,注意无需配置其Slave,Sentinel会自己去询问Master
    // sentinel monitor master-name ip redis-port quorum
    // quorum 哨兵们认为master客观死亡(Objectively Down)所需要的法定人。无论是否设置这个值,想要启动failover都必须有多数哨兵同意
    sentinel monitor yewu01 127.0.0.1 6379 2
    
    // 如果30000 ms后master还是不回应,就说明Master处于主观死亡(Subjectively Down)
    sentinel down-after-milliseconds yewu01 30000
    
    // 当发生failover的同时,1个slave开始与新master进行同步。意思是:此slave开始接收master的RDB文件而不能对外提供服务了,而其它slave还能对外服务(具体能否对外服务看第二个//),所以越少意味着redis能越快恢复对外服务
    // 同时还要搭配配置slave的redis.conf中的 slave-serve-stale-data参数,指定是否可用过期数据
    sentinel parallel-syncs yewu01 1
    
    // 执行failover多久算failover超时
    sentinel failover-timeout yewu01 180000
  2. 运行sentinel
    虽然 Redis Sentinel 释出为一个单独的可执行文件 redis-sentinel , 但实际上它只是一个运行在特殊模式下的 Redis 服务器, 你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动 Redis Sentinel 。

    // 1. 用redis-server加参数 --sentinel的方式启动
    redis-server /path/to/sentinel.conf --sentinel
    // 2. 用redis-sentinel 方式启动
    redis-sentinel /path/to/sentinel.conf
    
    //注意!注意!注意!不要忘记在防火墙添加端口,我的是CentOS7,所以如下
    firewall-cmd --zone=public --add-port=26379/tcp --permanent
    
  3. 查看状态
    redis-cli -h <hostname> -p 26379登录到Sentinel;

    Sentinel 可接受的命令(官网页面搜索Sentinel API):

    • PING :返回 PONG 。
    • SENTINEL masters :列出所有被监视的主服务器,以及这些主服务器的当前状态。
    • SENTINEL master <master name>:特定主服务器的当前状态。
    • SENTINEL slaves <master name>:列出给定主服务器的所有从服务器,以及这些从服务器的当前状态。
    • SENTINEL sentinels <master name> Show a list of sentinel instances for this master, and their state.
    • SENTINEL get-master-addr-by-name <master name> : 返回给定名字的主服务器的 IP 地址和端口号。 如果这个主服务器正在执行故障转移操作, 或者针对这个主服务器的故障转移操作已经完成, 那么这个命令返回新的主服务器的 IP 地址和端口号。
    • SENTINEL reset <pattern>: 重置所有名字和给定模式 pattern 相匹配的主服务器。 pattern 参数是一个 Glob 风格的模式。 重置操作清楚主服务器目前的所有状态, 包括正在执行中的故障转移, 并移除目前已经发现和关联的, 主服务器的所有从服务器和 Sentinel 。
    • SENTINEL failover : 当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移 (不过发起故障转移的 Sentinel 会向其他 Sentinel 发送一个新的配置,其他 Sentinel 会根据这个配置进行相应的更新)。
  4. sentinel.conf配置被改变

    每当一个Sentinel启动后,它就会修改并通知其它Sentinel同时修改自身的sentinel.conf文件,例如:

    生成一个myid

    sentinel myid 0f9bd55b18aa54a5f5efc6fb7b3371da56d48d4a

    文件最后会加上如下:

    
    # Generated by CONFIG REWRITE
    
    sentinel known-sentinel yewu01 192.168.0.1 26379 58a141a0f97669925bcc84e3a3b3dbc8602dea99
    sentinel known-sentinel yewu01 192.168.0.2 26379 a0fbf10df21374f8b5cac1f410d9df3b26618575
    sentinel current-epoch 0

3. failover - 故障转移

  1. 执行pkill redis-sever关掉Master观察Sentinel日志如下:

    这是一个被选为failover执行者的sentinel的日志,英文挺清晰明了的就不翻译了:

    6480:X 14 Feb 19:46:54.746 # +sdown master yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:54.798 # +odown master yewu01 10.173.244.98 6379 #quorum 3/2
    6480:X 14 Feb 19:46:54.798 # +new-epoch 1
    6480:X 14 Feb 19:46:54.798 # +try-failover master yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:54.807 # +vote-for-leader 214bd3df8363327488cd8c430166cf48cd2ab33a 1
    6480:X 14 Feb 19:46:54.819 # f7462491e6881da2c1efbfd6465ece6380c653cf voted for 214bd3df8363327488cd8c430166cf48cd2ab33a 1
    6480:X 14 Feb 19:46:54.823 # 6c95942bbcc39a0703ec5d54a76d6a696a500a17 voted for 214bd3df8363327488cd8c430166cf48cd2ab33a 1
    6480:X 14 Feb 19:46:54.907 # +elected-leader master yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:54.907 # +failover-state-select-slave master yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:54.974 # +selected-slave slave 10.174.249.145:6379 10.174.249.145 6379 @ yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:54.974 * +failover-state-send-slaveof-noone slave 10.174.249.145:6379 10.174.249.145 6379 @ yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:55.057 * +failover-state-wait-promotion slave 10.174.249.145:6379 10.174.249.145 6379 @ yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:55.534 # +promoted-slave slave 10.174.249.145:6379 10.174.249.145 6379 @ yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:55.534 # +failover-state-reconf-slaves master yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:55.581 * +slave-reconf-sent slave 10.251.22.210:6379 10.251.22.210 6379 @ yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:55.957 # -odown master yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:56.041 * +slave-reconf-inprog slave 10.251.22.210:6379 10.251.22.210 6379 @ yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:56.042 * +slave-reconf-done slave 10.251.22.210:6379 10.251.22.210 6379 @ yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:56.096 # +failover-end master yewu01 10.173.244.98 6379
    6480:X 14 Feb 19:46:56.096 # +switch-master yewu01 10.173.244.98 6379 10.174.249.145 6379
    6480:X 14 Feb 19:46:56.097 * +slave slave 10.251.22.210:6379 10.251.22.210 6379 @ yewu01 10.174.249.145 6379
    6480:X 14 Feb 19:46:56.097 * +slave slave 10.173.244.98:6379 10.173.244.98 6379 @ yewu01 10.174.249.145 6379
    6480:X 14 Feb 19:47:26.148 # +sdown slave 10.173.244.98:6379 10.173.244.98 6379 @ yewu01 10.174.249.145 6379

    这是非failover执行者的Sentinel的日志:

    30052:X 14 Feb 19:46:54.725 # +sdown master yewu01 10.173.244.98 6379
    30052:X 14 Feb 19:46:54.816 # +new-epoch 1
    30052:X 14 Feb 19:46:54.823 # +vote-for-leader 214bd3df8363327488cd8c430166cf48cd2ab33a 1
    30052:X 14 Feb 19:46:55.584 # +config-update-from sentinel 214bd3df8363327488cd8c430166cf48cd2ab33a 10.251.22.210 26379 @ yewu01 10.173.244.98 6379
    30052:X 14 Feb 19:46:55.584 # +switch-master yewu01 10.173.244.98 6379 10.174.249.145 6379
    30052:X 14 Feb 19:46:55.584 * +slave slave 10.251.22.210:6379 10.251.22.210 6379 @ yewu01 10.174.249.145 6379
    30052:X 14 Feb 19:46:55.584 * +slave slave 10.173.244.98:6379 10.173.244.98 6379 @ yewu01 10.174.249.145 6379
    30052:X 14 Feb 19:47:25.602 # +sdown slave 10.173.244.98:6379 10.173.244.98 6379 @ yewu01 10.174.249.145 6379

    日志显示,其中一个Slave被提升为了Master

  2. failover后配置被变更

    Sentinel首先通过命令的方式来做redis-serversentinel的配变更。之后会将配置持久化到redis.confsentinel.conf文件中。

    1. redis.conf
      被选为Master的,其slaveof键值被直接删除;
      仍然还是Slave的,其slaveof值被指定为新Master的地址;

    2. 所有Sentinel的sentinel.conf
      sentinel monitor 被指定为新Master的地址;

      // epoch “时期”(版本的意思)被自增1
      sentinel current-epoch 1

4. Jedis操作

显然,经过故障转移后,主从结构已经发生了改变且主已经死亡,如果还按照之前那样写死IP的方式连接Redis的话,势必会出现错误。可以想到,在Sentinel结构下,你必须向哨兵询问来获取谁是Master

    private static final JedisSentinelPool pool;
    static 
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(10);
        jedisPoolConfig.setMaxIdle(5);
        jedisPoolConfig.setMinIdle(5);

        Set<String> sentinels = new HashSet<>(Arrays.asList(
                "111.111.111.111:26379",
                "111.111.111.112:26379",
                "111.111.111.113:26379"
        ));
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxTotal(10);
        poolConfig.setMaxIdle(5);
        poolConfig.setMinIdle(5);
        pool = new JedisSentinelPool("yewu01", sentinels, jedisPoolConfig);
    

    public static void main(String[] args) throws Exception 
        String key1 = "key1";
        try (Jedis jedis = pool.getResource()) 
            jedis.set(key1, "222");
            System.out.println(jedis.get(key1));
         catch (Exception e) 
            e.printStackTrace();
        
    

以上。


参考文献:

[ 1 ] https://redis.io/topics/sentinel
[ 2 ] http://www.redis.cn/topics/sentinel.html

缓存加速------redis主从复制,哨兵模式,集群(代码片段)

目录前言一.Redis主从复制1.Redis主从复制概述2.Redis主从复制作用3.Redis主从复制流程4.搭建Redis主从复制①环境准备②安装Redis③修改Redis配置文件(Master节点操作)④修改Redis配置文件(Slave节点操作)⑤验证主从效果⑥在Master节点上验... 查看详情

缓存加速------redis主从复制,哨兵模式,集群(代码片段)

目录前言一.Redis主从复制1.Redis主从复制概述2.Redis主从复制作用3.Redis主从复制流程4.搭建Redis主从复制①环境准备②安装Redis③修改Redis配置文件(Master节点操作)④修改Redis配置文件(Slave节点操作)⑤验证主从效果⑥在Master节点上验... 查看详情

redis高可用之主从复制哨兵模式集群模式(代码片段)

目录前言一、Redis主从复制1.1Redis主从复制的概念1.2Redis主从复制的作用1.3Redis主从复制的流程1.4Redis主从复制的搭建1.4.1环境准备,在主从服务器上安装Redis服务1.4.2修改Master节点Redis配置文件1.4.3修改Slave节点Redis配置文件验证... 查看详情

redis的主从复制哨兵模式以及群集模式(相关概念及实验详解)(代码片段)

目录前言一.Redis主从复制1.Redis主从复制概述2.Redis主从复制作用3.Redis主从复制流程4.搭建Redis主从复制①环境准备②安装Redis③修改Redis配置文件(Master节点操作)④修改Redis配置文件(Slave节点操作)⑤验证主从效果⑥在Master节点上验... 查看详情

redis(主从复制哨兵模式集群)概述及部署(代码片段)

Redis(主从复制、哨兵模式、集群)概述及部署前言一、Redis主从复制1、Redis主从复制的概念2、Redis主从复制的作用3、Redis主从复制的流程4、Redis主从复制的搭建1、环境配置/安装包2、安装Redis(所有主机)3、修改... 查看详情

redis主从复制哨兵集群模式(代码片段)

Redis主从复制、哨兵、集群模式单节点模式SpringBoot整合@Bean(name="singleClient")publicRedissonClientsingleRedissonClient()tryConfigconfig=newConfig();config.useSingleServer().setAddress("redis://& 查看详情

docker搭建redis主从+哨兵(代码片段)

文章目录redis哨兵搭建主从服务器——一主两从启动哨兵客户端api连接哨兵存取数据redis哨兵redis主从复制结构中,当主服务器宕机,哨兵可以监控到服务宕机,在从服务器中选举产生一个新的主服务器。搭建主从服务... 查看详情

nosql之redis主从复制哨兵和集群介绍及详细搭建步骤(代码片段)

Redis主从复制、哨兵和集群一、主从复制1.1主从复制的概念1.2主从复制的作用1.3主从复制的流程1.4部署Redis主从复制步骤1.5部署Redis主从复制的具体操作步骤(实操)二、哨兵模式2.1哨兵模式的原理2.2哨兵模式的作用2.3哨... 查看详情

redis数据库主从哨兵群集(代码片段)

...论前言与介绍1.1前言1.2Redis群集介绍二、Redis三种模式2.1主从模式2.2哨兵模式2.3Cluster群集三、实验搭建3.1Redis主从复制模式3.1.1实验环境3.1.2三台服务器安装Redis5.0.73.1.3Master节点3.1.4Slaves节点3.1.5在Master节点查看验证3.2哨兵模式3.2.1... 查看详情

高可用集群架构——redis的主从复制与哨兵模式,cluster(代码片段)

...redis的集群模式1、三种模式2、redis集群与哈希槽二、Redis主从复制概述1、Redis主从复制概述2、主从复制流程三、哨兵模式1、简单介绍2、哨兵的工作原理5、哨兵模式下的故障迁移四、Cluster群集redis-Cluster的故障转移:实验部分一、... 查看详情

redis主从哨兵集群(代码片段)

文章目录Redis主从复制哨兵模式分片集群Redis主从复制概念主从复制,是指将一台Redis服务器的数据,复制到其他Redis服务器。前者称为主节点(master/leader),后者称为从结点(slave/follower);数据的... 查看详情

redis——主从复制哨兵模式集群服务(代码片段)

Redis一、主从复制1.1概述概念作用流程1.2服务搭建准备工作修改Redis配置文件验证主从二、哨兵模式2.1原理2.2作用2.3结构2.4服务搭建准备工作修改配置文件(所有节点)启动哨兵模式查看哨兵信息模拟故障查看结果三、集... 查看详情

redis集群介绍与搭建(主从哨兵cluster集群)!(代码片段)

...群的优势3.Redis集群的实现方法二.Redis三种模式原理介绍1.主从模式2.哨兵模式(Sentinel)(1)哨兵模式集群架构(2)哨兵模式主要功能(3)哨兵们监控整个系统节点的过程(4)哨兵模式下的故障迁移3... 查看详情

redis集群介绍与搭建(主从哨兵cluster集群)!(代码片段)

...群的优势3.Redis集群的实现方法二.Redis三种模式原理介绍1.主从模式2.哨兵模式(Sentinel)(1)哨兵模式集群架构(2)哨兵模式主要功能(3)哨兵们监控整个系统节点的过程(4)哨兵模式下的故障迁移3... 查看详情

redis技术探索「高可用架构模式」哨兵(sentinel)模式实现主从故障互切换模式详解(代码片段)

哨兵(sentinel)模式实现主从故障互切换模式详解Redis的多种模式Redis单机模式Redis单机模式的优点Redis单机模式的缺点Redis主从复制旧版本配置新版本配置查看主节点信息主从模式的优点主从复制的弊端Redis哨兵模式分析哨... 查看详情

redis群集(代码片段)

Redis群集一.Redis群集模式1.1主从复制模式1.2哨兵模式1.3集群二.Redis群集三.Redis主从复制3.1Redis主从复制概述3.2主从复制流程四.哨兵模式4.1哨兵模式集群架构4.2哨兵模式主要功能4.3哨兵监控整个系统节点的过程4.4哨兵的工作原理4.5... 查看详情

redis高可用方案主从及哨兵(代码片段)

Redis集群——主从复制以及哨兵模式##主从复制的定义Redis的主从复制表示将Redis的服务器分为主服务器(Master)以及多个从服务器(Slaves),其目的是减少主服务器的读取数据的压力。一个Master可以有多个该服... 查看详情

redis数据库主从哨兵群集(代码片段)

...论前言与介绍1.1前言1.2Redis群集介绍二、Redis三种模式2.1主从模式2.2哨兵模式2.3Cluster群集三、实验搭建3.1Redis主从复制模式3.1.1实验环境3.1.2三台服务器安装Redis5.0.73.1.3Master节点3.1.4Slaves节点3.1.5在Master节点查看验证3.2哨兵模式3.2.1... 查看详情