第二十节 Redis的集群配置

亮子 2021-08-11 10:15:35 2239 0 0 0

1、Cluster模式介绍

sentinel模式基本可以满足一般生产的需求,具备高可用性。但是当数据量过大到一台服务器存放不下的情况时,主从模式或sentinel模式就不能满足需求了,这个时候需要对存储的数据进行分片,将数据存储到多个Redis实例中。cluster模式的出现就是为了解决单机Redis容量有限的问题,将Redis的数据根据一定的规则分配到多台机器。

cluster可以说是sentinel和主从模式的结合体,通过cluster可以实现主从和master重选功能,所以如果配置两个副本三个分片的话,就需要六个Redis实例。因为Redis的数据是根据一定规则分配到cluster的不同机器的,当数据量过大时,可以新增机器进行扩容。

使用集群,只需要将redis配置文件中的cluster-enable配置打开即可。每个集群中至少需要三个主数据库才能正常运行,新增节点非常方便。

2、cluster集群特点

  • 多个redis节点网络互联,数据共享

  • 所有的节点都是一主一从(也可以是一主多从),其中从不提供服务,仅作为备用

  • 不支持同时处理多个key(如MSET/MGET),因为redis需要把key均匀分布在各个节点上,并发量很高的情况下同时创建key-value会降低性能并导致不可预测的行为

  • 支持在线增加、删除节点

  • 客户端可以连接任何一个主节点进行读写

3、Cluster模式搭建

1)、开启集群配置

这时候需要修改redis的配置文件,并把默认注释的下面选项放开:

cluster-enabled yes

节点是否支持集群,可以通过下面命令来查看:

# 查看集群
cluster nodes

如果没有配置,则出现如下错误:

127.0.0.1:6379> cluster nodes
ERR This instance has cluster support disabled

2)、创建节点

# 运行节点1
docker run -itd --name redis9090 -p 9090:6379 -v D:/app/redis/redis.conf:/usr/local/etc/redis/redis.conf:rw redis:6.0-rc redis-server /usr/local/etc/redis/redis.conf

# 运行节点2
docker run -itd --name redis9091 -p 9091:6379 -v D:/app/redis/redis.conf:/usr/local/etc/redis/redis.conf:rw redis:6.0-rc redis-server /usr/local/etc/redis/redis.conf

# 运行节点3
docker run -itd --name redis9092 -p 9092:6379 -v D:/app/redis/redis.conf:/usr/local/etc/redis/redis.conf:rw redis:6.0-rc redis-server /usr/local/etc/redis/redis.conf

3)、查看集群状态

这时候再运行cluster nodes,则会显示如下界面:

# 查看集群
cluster nodes

图片alt

4、SpringBoot集成

1)、添加依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.8.0</version>
        </dependency>

2)、配置文件

spring.redis.cluster.nodes=127.0.0.1:9090,127.0.0.1:9091,127.0.0.1:9092
spring.redis.timeout=60000
spring.redis.lettuce.pool.max-wait=-1
spring.redis.lettuce.pool.max-active=300
spring.redis.lettuce.pool.max-idle=100
spring.redis.lettuce.pool.min-idle=20

3)、测试代码

package com.shenmazong.demorediscluster;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;

@SpringBootTest
class DemoRedisClusterApplicationTests {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Test
    void contextLoads() {
    }

    @Test
    void testRedisSet() {
        stringRedisTemplate.opsForValue().set("david", "123");
    }

    @Test
    void testRedisGet() {
        String david = stringRedisTemplate.opsForValue().get("david");
        System.out.println(david);
    }

}

当然不可能一帆风顺,第一次运行可能出现如下错误:

org.springframework.data.redis.RedisSystemException: Redis exception; nested exception is io.lettuce.core.cluster.PartitionSelectorException: Cannot determine a partition for slot 2180.

如果出现上面错误,可以通过如下命令来修复一下:

redis-cli --cluster fix 172.17.0.2:6379
redis-cli --cluster fix 172.17.0.3:6379
redis-cli --cluster fix 172.17.0.4:6379

由于redis的节点使用的是docker运行的,所以如果在一台机器上,则需要使用docker的内部ip,docker的内部ip可以通过如下命令获取:

docker inspect redis9092

图片alt

再次运行,应该能够正常运行。

参考文档