Redis集群搭建(v6)

JAVA学习网 2021-07-19 17:54:12

Redis集群搭建

介绍

  • 使用6.2.4 搭建 主从、哨兵、集群模式。

准备

  • 准备三台电脑

    IP地址 主机名称
    172.16.241.2 linux1
    172.16.241.3 linux2
    172.16.241.4 linux3
    172.16.241.5 linux4
    172.16.241.6 linux5
    172.16.241.7 linux6
  • 机器配置

    1. linux 系统

      image-20210716100620011

    2. 关闭防火墙

      systemctl stop firewalld.service // 关闭

      systemctl disable firewalld.service // 禁止开启自动

      systemctl status firewalld.service // 查看防火墙状态

    3. 修改 linux配置

      net.core.somaxconn = 2048
      vm.overcommit_memory=1

  • 下载redis 包,解压并make(如果make指令缺失,执行yum install -y gcc automake autoconf libtool make

    $ wget https://download.redis.io/releases/redis-6.2.4.tar.gz
    $ tar xzf redis-6.2.4.tar.gz
    $ cd redis-6.2.4
    $ make
    
  • 文件目录目录如下:

    image-20210715154658452

主从模式

  • 修改三台机器的redis.conf

    1. master(linux1)

      bind * //允许其他服务器访问
      
    2. 其他两个Salve(linux2, linux3)

      slaveof  linux1 6379  // 配置两个slave属于哪个master
      
  • 启动

    启动master,然后启动两个salve

    进入src目录执行./redis-server ../redis.conf

  • 验证主从模式是否搭建完毕

    访问其中任意一个redis-cli: ./redis-cli 然后输入./redis-server ../redis.conf

    a

    两个salve已经存在。

  • Java调用

    1. pom引入

    2. <dependency>
          <groupId>redis.clients</groupId>
          <artifactId>jedis</artifactId>
          <version>3.6.1</version>
      </dependency>
      
    3. 核心代码

      // 主从模式
      // 1. 向master写
      Jedis jedis = new Jedis("linux1", 6379);
      jedis.set("a", "accccc");
      jedis.close();
      
      // 2.从slave读取
      Jedis readJedis = new Jedis("linux2", 6379);
      String a = readJedis.get("a");
      System.out.println("获取从master中写入的数据a = " + a);
      readJedis.close();
      

Sentinel哨兵模式

  • 按照主从模式的配置,启动三个节点

  • 修改sentinel.conf, 监控master主机

    sentinel monitor mymaster 172.16.241.2 6379 2

  • 启动master(linux1)的sentinel

    image-20210716095204177

  • 启动slave1, slave2, 查看master日志

    image-20210716111246583

  • 测试

    1. 停止slave1,查看master的日志

    2. image-20210716112136530

    3. JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
      jedisPoolConfig.setMaxIdle(5);
      jedisPoolConfig.setMaxTotal(10);
      jedisPoolConfig.setMinIdle(5);
      
      Set<String> sentinels = new HashSet<>();
      sentinels.add("linux1:26379");
      sentinels.add("linux2:26379");
      sentinels.add("linux3:26379");
      JedisSentinelPool jedisSentinelPool = new JedisSentinelPool("mymaster", sentinels, jedisPoolConfig);
      Jedis pj = jedisSentinelPool.getResource();
      pj.set("a", "sentinel");
      String sentinelStored = pj.get("a");
      System.out.println("使用sentinel模式存储的a=" + sentinelStored);
      
    4. 重启master,sentinel会选择其中一个slave升级为master,原master重启后,会变为slave不会重新升级为master。

Cluster 集群

  • 跟着官网教程(https://redis.io/topics/cluster-tutorial)

  • 配置说明

    1. cluster-enabled<yes/no>:启用集群支持
    2. cluster-config-file<filename>:该文件无需用户编辑,是Cluster集群节点变化后时自动持久化集群配置
    3. cluster-node-timeout<milliseconds>:Redis集群节点不可用的最长时间,如果主节点在指定的时间内无法访问,那么由从节点进行故障转移
    4. luster-slave-validity-factor<factor>:如果设置为0,那么从节点始终认为自己有效。将始终尝试对主节点进行故障转移
    5. cluster-migration-barrier<count>:一个主节点的将保持连接的最小从节点数量,以便另一个从节点迁移到不再被任何从站覆盖的主节点
    6. cluster-require-full-coverage<yes/no>:如果将其设置为 yes,默认情况下,如果任何节点未覆盖一定百分比的密钥空间,则集群将停止接受写入。如果该选项设置为 no,即使只能处理有关密钥子集的请求,集群仍将提供查询服务。
    7. luster-allow-reads-when-down<yes/no>:如果设置为 no,默认情况下,当集群被标记为失败时,Redis 集群中的节点将停止服务所有流量,或者当节点无法访问时达到法定人数或未达到完全覆盖时。这可以防止从不知道集群中的变化的节点读取可能不一致的数据。可以将此选项设置为 yes 以允许在失败状态期间从节点读取,这对于希望优先考虑读取可用性但仍希望防止不一致写入的应用程序非常有用。它也可以用于使用只有一个或两个分片的 Redis Cluster 时,因为它允许节点在主节点发生故障但无法自动故障转移时继续提供写入服务。
  • 配置和使用Redis集群(官网教程是在一个机器上启动多个服务的伪集群,本文使用之前准备的三台虚拟机)

    1. 在三台节点上,解压之前的压缩包为redis-cluster, 并执行make指令。

    2. 三台机器都配置redis.conf(因为我之前在这三台机器上启动了redis,我又不想改端口号。所以讲之前的redis和sentinel都关闭)

      最小配置:

      cluster-enabled yes
      cluster-config-file nodes.conf
      cluster-node-timeout 5000
      appendonly yes
      
    3. 分别启动redis

    4. 使用redis-cli启动集群:./redis-cli --cluster create 172.16.241.2:6379 172.16.241.3:6379 172.16.241.4:6379 172.16.241.5:6379 172.16.241.6:6379 172.16.241.7:6379 --cluster-replicas 1

      日志信息如下:

      Performing hash slots allocation on 6 nodes...
      Master[0] -> Slots 0 - 5460
      Master[1] -> Slots 5461 - 10922
      Master[2] -> Slots 10923 - 16383
      Adding replica 172.16.241.6:6379 to 172.16.241.2:6379
      Adding replica 172.16.241.7:6379 to 172.16.241.3:6379
      Adding replica 172.16.241.5:6379 to 172.16.241.4:6379
      M: b31d4478d5b521e289491a89da26976a85b1f3c9 172.16.241.2:6379
      slots:[0-5460] (5461 slots) master
      M: 2cdbe3aba12a65444a00a2170390d1dbf108a865 172.16.241.3:6379
      slots:[5461-10922] (5462 slots) master
      M: 31ac1ad83587697634bae2a363dfdcd58b15d63e 172.16.241.4:6379
      slots:[10923-16383] (5461 slots) master
      S: da22af2f724033b2e7cec8fd49d4e80aae4712f3 172.16.241.5:6379
      replicates 31ac1ad83587697634bae2a363dfdcd58b15d63e
      S: 732ce03d83245d0a0a9b002bbfa8bf959aeb7720 172.16.241.6:6379
      replicates b31d4478d5b521e289491a89da26976a85b1f3c9
      S: 546e7ed39dc7427bed062e5529e5831c9a35bdcb 172.16.241.7:6379
      replicates 2cdbe3aba12a65444a00a2170390d1dbf108a865
      Can I set the above configuration? (type 'yes' to accept): yes
      Nodes configuration updated
      Assign a different config epoch to each node
      Sending CLUSTER MEET messages to join the cluster
      Waiting for the cluster to join
      ..
      Performing Cluster Check (using node 172.16.241.2:6379)
      M: b31d4478d5b521e289491a89da26976a85b1f3c9 172.16.241.2:6379
      slots:[0-5460] (5461 slots) master
      1 additional replica(s)
      M: 2cdbe3aba12a65444a00a2170390d1dbf108a865 172.16.241.3:6379
      slots:[5461-10922] (5462 slots) master
      1 additional replica(s)
      S: 546e7ed39dc7427bed062e5529e5831c9a35bdcb 172.16.241.7:6379
      slots: (0 slots) slave
      replicates 2cdbe3aba12a65444a00a2170390d1dbf108a865
      S: 732ce03d83245d0a0a9b002bbfa8bf959aeb7720 172.16.241.6:6379
      slots: (0 slots) slave
      replicates b31d4478d5b521e289491a89da26976a85b1f3c9
      S: da22af2f724033b2e7cec8fd49d4e80aae4712f3 172.16.241.5:6379
      slots: (0 slots) slave
      replicates 31ac1ad83587697634bae2a363dfdcd58b15d63e
      M: 31ac1ad83587697634bae2a363dfdcd58b15d63e 172.16.241.4:6379
      slots:[10923-16383] (5461 slots) master
      1 additional replica(s)
      [OK] All nodes agree about slots configuration.
      Check for open slots...
      Check slots coverage...
      [OK] All 16384 slots covered.

      截图:

      image-20210716144922752

      槽点分配图

      看到上面的信息,即代表集群搭建成功。

    5. 查看集群节点信息

      image-20210716145043209

      绿色:master几点,黄色代表slave节点

    6. 查看集群信息

      image-20210716145315634

    7. Redis-cli 演示set操作

      image-20210716150202077

      这是什么意思? 原因是a的不会放到该节点上,使用cluster keyslot a ,结果是16475,通过上面创建集群启动日志中我们看到。16475会放到linux3节点上。那么去linux3节点连接redis-cli,./redis-cli 执行set a b,发现没有问题,如图:

      image-20210716150930035

      那么问题来了,如何连接的时候让其自动去查找槽位呢?./redist-cli -c 即可。打开linux1,进入src目录执行./redis-cli -c ,输入 set a b 执行结果如下:

      image-20210716151140213

      可以看到redis自动重定向到指定槽位的节点。

    8. java代码示例

      image-20210716161640993

    9. 使用create-cluster脚本创建集群

    如果不想通过如上所述手动配置和执行单个实例来创建 Redis 集群,则有一个更简单的方法,使用utils/create-cluster 这是个shell脚本。用于创建伪集群。

  • 几种集群对比

  1. 主从模式:

    优点:Master能自动将数据同步到slave,可以进行读写分离,分担master的压力

    ​ master、slave之间的同步是以非阻塞的方式进行的,同步期间,客户端仍然可以提交查询或更新请求

    缺点:不具备自动容错与恢复功能,master和slave的宕机都可能导致客户端请求失败,需要等待机器重启或手动切换客户端ip才能恢复

  2. 哨兵(sentinel)模式

    优点:具有主从模式的所有优点,同时master挂掉可以自动切换,高可用。

    缺点:因为根本是在主从模式上增加了一层sentinel,扩容困难。

  3. cluster模式

    优点:无中心结构,数据通过计算分布到不同的slot,分布在不同的节点上。

    ​ 集群的节点都是平等关系,每个节点保存各自的数据以及这个集群的状态等信息

    ​ 扩容方便,节点可动态添加和删除

    ​ 自动故障转移,通过投票机制选举master

    缺点: 比如客户端实现复杂,数据异步复制(无法保证强制性)、但依然可解,不支持多数据库等等。

  • 实际生产中,参数配置、容灾处理等要求都是很高的。学海无涯,变秃了也变强了,加油吧!
阅读(37) 评论(0)