Redis-Cluster使用示例

今天学习了redis集群的使用,在此记录一下过程中遇到的问题

一、环境搭建(需要先安装好docker)

这里将使用docker部署4个redis实例(node1-3作为主节点,node4作为1的备节点)

这里把4个redis实例部署在同一台机器上,如果部署在不同机器上,下面有些命令要分开执行

下载redis镜像

docker  pull  redis:5.0.5

 

创建redis实例的数据目录 

mkdir -p /data/redis-data/node1 /data/redis-data/node2 /data/redis-data/node3 /data/redis-data/node4

chmod -R  777 /data

 创建4个redis容器,其中,node1、node2、node3的端口分别是6379、6380、6381

docker create --name redis-node1 --net host -v /data/redis-data/node1:/data redis:5.0.5 --cluster-enabled yes --cluster-config-file nodes-node-1.conf --port 6379

docker create --name redis-node2 --net host -v /data/redis-data/node2:/data redis:5.0.5 --cluster-enabled yes --cluster-config-file nodes-node-2.conf --port 6380

docker create --name redis-node3 --net host -v /data/redis-data/node3:/data redis:5.0.5 --cluster-enabled yes --cluster-config-file nodes-node-3.conf --port 6381

docker create --name redis-node4 --net host -v /data/redis-data/node4:/data redis:5.0.5 --cluster-enabled yes --cluster-config-file nodes-node-4.conf --port 6382

--name :容器名称
--net:网络模式,host表示和主机处于同一个网络命名空间,这样本地程序才能访问到该redis集群
-v:文件目录挂载
--cluster-enabled:是否启动集群
--cluster-config-file:配置文件
--port:服务端口

 启动容器

docker start redis-node1 redis-node2 redis-node3 redis-node4

 

关闭防火墙(不关闭防火墙,程序无法连接上集群)

systemctl stop firewalld

 二、集群搭建

配置主节点集群

docker exec -it redis-node1 bash

redis-cli --cluster create 192.168.19.138:6379  192.168.19.138:6380  192.168.19.138:6381 --cluster-replicas 0
-- 上面的192.168.19.138是该服务器的ip,实际需要换成自己部署的服务器ip

在node1中,执行redis-cli进入redis服务,查询集群节点状态cluster nodes

 复制node1的id,下面要用

 退出node1的docker,进入主服务器

配置备节点,指定node4为node1的备节点

docker exec -it redis-node4 bash

redis-cli --cluster add-node 192.168.19.138:6382 192.168.19.138:6379  --cluster-slave --cluster-master-id 2a8710ea53acaaaa4c611c880109dece6abbaff6

--上面的2a8710ea53acaaaa4c611c880109dece6abbaff6,需要换成实际的id

查看添加备节点后的集群状态

 

 三、Redis-cluster使用

使用springboot搭建一个简单的客户端,用来连接redis集群,并在过程中,停止node1节点,看看集群环境能否正常切换使用

架包引用,只需要一个jedis,springboot会自动关联jedis版本



dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-log4j2")

    compile("redis.clients:jedis")
    compile("org.projectlombok:lombok:1.18.8")
    annotationProcessor ("org.projectlombok:lombok:1.18.8")
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

 配置文件application.yaml,需要指定整个集群的所有redis节点,不需要密码

spring:
  redis:
    cluster:
      nodes: 192.168.19.138:6379,192.168.19.138:6380,192.168.19.138:6381,192.168.19.138:6382

 Main入口

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

 redis配置类

@Configuration
public class RedisConfig {

    @Value("${spring.redis.cluster.nodes:}")
    private String clusterNodes;

    @Bean
    public JedisCluster getJedisCluster(){
        String[] serverArray = clusterNodes.split(",");
        Set<HostAndPort> nodes = new HashSet<>();

        for (String ipPort : serverArray) {
            if(StringUtils.isEmpty(ipPort)){
                continue;
            }
            String[] ipPortPair = ipPort.split(":");
            nodes.add(new HostAndPort(ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim())));
        }
        JedisCluster cluster = new JedisCluster(nodes, 1000);
        return cluster;
    }
}

测试类,每30秒往集群中写数据

@Log4j2
@Component
public class Task implements InitializingBean {

    @Autowired
    JedisCluster cluster;

    @Override
    public void afterPropertiesSet() throws Exception {
        while(true) {
            for (int i = 0; i < 10; i++) {
                try {
                    String key = "abc" + i;
                    cluster.set(key, "" + i);
                    int slot = JedisClusterCRC16.getSlot(key);
                    log.info(cluster.get(key)+" 保存成功,slot:"+slot);
                }catch (Exception e){
                    log.error(e.getMessage());
                }
            }
            Thread.sleep(30000);
        }
    }
}

四、测试结果

当redis集群所有节点正常运行时,node1、node2、node3三个主节点各自保存一部分数据

 

 

node4的数据和node1的数据保持一致

我们关掉node1节点

 

经过几秒后,可以看到redis集群中,node1状态变成fail,node4状态变成master,并且node4的slot分区和之前的node1保持一致

不过30秒后,程序还是报错了

失败后,JedisCluster重新从redis-cluster更新本地状态,这次又能连上备节点。

 后语

此文章的redis环境部署部分参考了以下文章:

基于Docker搭建Redis集群(主从集群) - niceyoo - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值