Redisr Cluster集群搭建(主从模式)与SpringBoot集成(从0开始搭建)

一、 Redis Cluster集群搭建

在linux环境下redis集群的搭建,需要准备的工作:

1.1. 此次直接讲解redis集群,单节点版暂且不讲;redis集群至少需要3个节点,因为容错机制要求超过半数节点认为某个节点挂了该节点才是挂了,所以2个节点无法构成集群;
1.2. 要保证集群的高可用,需要每个节点都有从节点,也就是备份节点,所以Redis集群至少需要6台服务器。但是我没有那么多服务器,所在这里搭建的是伪分布式集群,即一台服务器虚拟运行6个redis实例,修改端口号为(7001-7006);
1.3. 安装redis5.0.0;
1.4. 关闭防火墙,因为后续客户端访问redis服务器需要由有口权限,为了搭建方便,暂时关闭防火墙;在生产环境中,最好不要直接关闭防火墙,给相应的端口开通访问权限即可;
•关闭防火墙命令:systemctl stop firewalld
•启用防火墙命令:systemctl enable firewalld
•查看防火墙状态命令:systemctl start firewalld
•查看防火墙状态 :systemctl status firewalld
1.5. 安装ruby;
•安装ruby的命令:yum install ruby

二、操作步骤

2.1.在usr/local目录下新建redis-cluster目录,用于存放集群节点
进入local目录命令:cd /usr/local/
创建目录的命令:mkdir redis-cluster
Redisr Cluster集群搭建(主从模式)与SpringBoot集成(从0开始搭建)_第1张图片
2.2把redis目录下的bin目录下的所有文件复制到/usr/local/redis-cluster/redis01目录下
执行命令:cp -r redis/bin/ redis-cluster/redis01
2.3. 删除redis01目录下的快照文件dump.rdb和nodes.conf(有的话就删,没有的话就不用管),并且修改该目录下的redis.conf文件,具体修改两处地方:一是端口号修改为7001,二是开启集群创建模式,打开注释即可。分别如下所示:
•删除dump.rdb文件命令:rm -rf dump.rdb
•删除nodes.conf命令:rm -rf nodes.conf
•修改端口号:将redis.conf文件中port参数改为7001
Redisr Cluster集群搭建(主从模式)与SpringBoot集成(从0开始搭建)_第2张图片
开启集群:将cluster-enabled yes的注释打开
Redisr Cluster集群搭建(主从模式)与SpringBoot集成(从0开始搭建)_第3张图片

关于redis.conf中ip的配置问题,一开始我以为和单机点配置是一样的,ip需要配置服务器的ip,假设我的服务器ip是192.168.1.110,即redis.conf中ip需要配置为
bind 192.168.1.110,最后发现启动的时候还是客户端连接redis服务的时候,一直失败,具体原因我也忘记了;后来发现就是ip配置的有问题,所以在redis-cluster模式下,ip无需配置也可以;
Redisr Cluster集群搭建(主从模式)与SpringBoot集成(从0开始搭建)_第4张图片

再来这里说下为什么要删除nodes.conf这个文件,因为我在搭建过程的后期,在启动redis集群的时候经常会报错,报错的原因是redis.conf中配置的ip或者端口配置的有问题,然而配置文件中的配置项数据会存到nodes.conf中;所以如果有关于ip或者端口配置的有问题,需要重新配置的时候,需要删除nodes.conf文件,否则即使修改了redis.conf文件,集群启动仍然会有问题;

2.5将redis-cluster/redis01文件复制5份到redis-cluster目录下(redis02-redis06),创建6个redis实例,模拟Redis集群的6个节点。然后将其余5个文件下的redis.conf里面的端口号分别修改为7002-7006。
在这里插入图片描述
2.6启动redis节点:
•进入到redis01目录下:cd /usr/local/redis-cluster/redis01
•执行启动命令:./redis-server redis.conf
然后,挨个启动各个节点
2.7安装redis-3.0.0.gem
下载地址:https://rubygems.org/gems/redis/versions/3.0.0
安装命令:gem install redis-3.0.0.gem
在这里插入图片描述
2.8将redis解压文件的源代码里,即redis/src目录下的redis-cli文件拷贝到/usr/local/redis/下
在这里插入图片描述
然后执行集群启动命令:
./redis-cli --cluster create 192.168.1.110:7001 192.168.1.110:7002 192.168.1.110:7003 192.168.1.110:7004 192.168.1.110:7005 192.168.1.110:7006
这个地方是个坑,网上很多文章是用./redis-trib.rb create --replicas来启动,其实对于redis5.0.0版本,这个命令已经没法用了,但是具体是从哪个版本开始,我倒是忘记了;所以,对于不同的版本,redis集群版本启动命令是不一样的,这点大家要注意;
2.9启动成功后,进入redis01节点目录下,执行连接命令:./redis-cli -p 7001 -c ,测试下
在这里插入图片描述

三、SpringBoot与Redisr Cluster集成

springboot中的jedis版本为1.8.6,redis.clients版本为2.9.0
3.1.pom文件添加依赖:

        
            org.springframework.boot
            spring-boot-starter-data-redis
        

        
            redis.clients
            jedis
        

3.2application.yml文件配置:

redisCluster:
   jedisClusterNode: 
   192.168.1.110:7001 192.168.1.110:7002 192.168.1.110:7003 192.168.1.110:7004 192.168.1.110:7005 192.168.1.110:7006 
   connectionTimeout: 20000
   soTimeout: 3000
   maxAttempts: 10
   poolConfig:
       maxIdle: 6
       minIdle: 0
       maxActive: 6
       maxWait: -1

3.3创建一个redis配置对象,即RedisProperties.java

/**
 * @Description:redis集群模式配置文件
 * @Date: 2019/8/9 18:12
 */
@Component
@ConfigurationProperties(prefix = "redisCluster")
@Data
public class RedisProperties {

    //集群节点的ip和端口
    private String jedisClusterNode;

    //集群连接超时时间
    private int connectionTimeout;

    //读取数据超时
    private int soTimeout;

    //最大尝试次数
    private int maxAttempts;

    //集群密码
    private String password;

}

3.4创建JedisClusterConfig.java

/**
 * @Description:redis集群配置类,用于初始化连接池和集群实例,集群实例用于操作redis数据库
 * @Date: 2019/8/9 18:10
 */
@Configuration
public class JedisClusterConfig {

    @Autowired
    private GenericObjectPoolConfig poolConfig;

    @Autowired
    private RedisProperties redisProperties;

    /*
    *初始化连接池
     */
    @Bean
    @ConfigurationProperties(prefix = "redisCluster.poolConfig")
    public GenericObjectPoolConfig getRedisConfig(){
        GenericObjectPoolConfig poolConfig=new GenericObjectPoolConfig();
        poolConfig.setMaxIdle(1000);
        return poolConfig;
    }

    /*
     * 该类在spring初始化时,会调用该方法,并将JedisCluster 集群实例注册到spring中
     * 这里的JedisCluster是单例的,可以直接注入到其他类中使用
     */
    @Bean
    public JedisCluster getJedisCluster(){
        String [] serverArray=redisProperties.getJedisClusterNode().split(Constants.COMMA);
        Set nodes=new HashSet();

        for(String ipPort:serverArray){
            String[] ipPortPair=ipPort.split(Constants.COLON);
            nodes.add(new HostAndPort(ipPortPair[0].trim(),Integer.valueOf(ipPortPair[1].trim())));
        }
        if(StringUtils.isEmpty(redisProperties.getPassword())){
            return new JedisCluster(nodes,redisProperties.getConnectionTimeout(),
                    redisProperties.getSoTimeout(),redisProperties.getMaxAttempts(),poolConfig);
        }else{
            return new JedisCluster(nodes,redisProperties.getConnectionTimeout(),
                    redisProperties.getSoTimeout(),redisProperties.getMaxAttempts(),
                    redisProperties.getPassword(),poolConfig);
        }

    }


}

3.5创建RedisClusterTemplate.java,用于java端直接操作redis库

/**
 * @Description:redis集群操作类,可通过集群实例直接操作redis库
 * @Date: 2019/8/9 19:38
 */
@Component
@Slf4j
public class RedisClusterTemplate {

    @Autowired
    private JedisCluster jedisCluster;

    /*
    *发布
     */
    public void publish(){
        System.out.println(jedisCluster.publish("channel1","test"));
    }

    /*
    *订阅
    */
    public void psubscribe(){
        jedisCluster.subscribe(new JedisPubSubListener(),"channel1");
    }

    /*
    *设置key
    */
    public void set(String key, String value) {
        jedisCluster.set(key, value );
    }

    /*
    *设置key
    */
    public void setObject(String key, Object value) {
        String objStr= JsonUtil.parseObject2Str(value);
        jedisCluster.set(key, objStr );
    }

        /*
    *设置key
    */
    public void setObject(String key, Object value, int expiration) {
        String objStr= JsonUtil.parseObject2Str(value);
        jedisCluster.setex(key, expiration, objStr );
    }

    /*
    *设置key及有效期
    */
    public void set(String key, String value, int expiration) {
        jedisCluster.setex(key, expiration, value);
    }

    /*
    *取key对应value
    */
    public String get(String key) {
        return jedisCluster.get(key);
    }

    /*
     *取key对应value
    */
    public  T getObject(String key, Class resultClass) {
        String returnStr=jedisCluster.get(key);
        if(StringUtils.isNotEmpty(returnStr)){
           return JsonUtil.parseObj(returnStr,resultClass);
        }else{
            return null;
        }
    }
}

然后,在相应的业务模块,只直接通过注入RedisClusterTemplate 实例,即可直接操作redis数据,详细的操作方式在这里就不细写了。特别强调下,使用这种方式,RedisClusterTemplate 操作redis的数据的读取只能使用json字符串,不能直接使用java对象,所以要特别注意

在这里有两篇文章,写的也是这种搭建方式,写的也很不错,大家可以参考下

1: https://blog.csdn.net/qq_42815754/article/details/82912130
2: https://www.cnblogs.com/lykxqhh/p/5690923.html

以上内容纯属原创,有些地方也是参考了网上不少教程;这篇文章纯属技术分享,不以任何盈利为目的,如果有侵权的地方,请私信我,我将会进行调整,谢谢!

你可能感兴趣的:(Redis)