redis集群搭建和spring集成使用

redis集群搭建

(单机多节点为例)安装redis,将redis.conf文件复制几份并设置不同得监听端口(8001-8006),我在redis目录下新加了nodes-conf目录来存放我设置了六个不同端口的配置文件。

如果需要密码,配置文件中添加

masterauth 123456  
requirepass 123456

requirepass:每个节点的独立密码,可以相同可以不同。
masterauth:从节点从主节点同步数据时使用的主节点的密码
redis集群搭建和spring集成使用_第1张图片
使用脚本start.sh和stop.sh可以方便集群得启停操作,启动每个端口的节点

start.sh


echo 'start redis cluster ...'

REDISBASE="/opt/app/redis-5.0.4"

cd $REDISBASE

./src/redis-server $REDISBASE/nodes-conf/cluster-node-8001.conf
./src/redis-server $REDISBASE/nodes-conf/cluster-node-8002.conf
./src/redis-server $REDISBASE/nodes-conf/cluster-node-8003.conf
./src/redis-server $REDISBASE/nodes-conf/cluster-node-8004.conf
./src/redis-server $REDISBASE/nodes-conf/cluster-node-8005.conf
./src/redis-server $REDISBASE/nodes-conf/cluster-node-8006.conf

echo 'start redis cluster finish !'

ps -ef|grep cluster

stop.sh

echo 'shutdown redis cluster...'

REDISBASE="/opt/app/redis-5.0.4"

$REDISBASE/src/redis-cli -p 8001 shutdown
$REDISBASE/src/redis-cli -p 8002 shutdown
$REDISBASE/src/redis-cli -p 8003 shutdown
$REDISBASE/src/redis-cli -p 8004 shutdown
$REDISBASE/src/redis-cli -p 8005 shutdown
$REDISBASE/src/redis-cli -p 8006 shutdown

echo 'shutdown redis cluster finish !'

ps -ef|grep cluster

在redis得5+版本之后,使用redis-trib.rb创建集群提示。

[root@localhost src]#  ./redis-trib.rb create --replicas 1 127.0.0.1:8001  127.0.0.1:8002  127.0.0.1:8003  127.0.0.1:8004  127.0.0.1:8005  127.0.0.1:8006
WARNING: redis-trib.rb is not longer available!
You should use redis-cli instead.
 
All commands and features belonging to redis-trib.rb have been moved
to redis-cli.
In order to use them you should call redis-cli with the --cluster
option followed by the subcommand name, arguments and options.
 
Use the following syntax:
redis-cli --cluster SUBCOMMAND [ARGUMENTS] [OPTIONS]
 
Example:
redis-cli --cluster create 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003 127.0.0.1:8004 127.0.0.1:8005 127.0.0.1:8006 --cluster-replicas 1
 
To get help about all subcommands, type:
redis-cli --cluster help

(好像是redis在5.0已上得版本不再使用redis-trib.rb创建集群,这样也生下了ruby的安装和版本问题带来的麻烦)
redis-cli --cluster create 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003 127.0.0.1:8004 127.0.0.1:8005 127.0.0.1:8006 --cluster-replicas 1
然后会输出一些提示。之后进入一个节点
输入cluster nodes会显示出当前集群得节点表示集群创建成功。
redis集群搭建和spring集成使用_第2张图片

spring配置使用redis集群

一般我们直接使用配置JedisCluster连接redis集群,这里使用工厂类。
首先我们写一个redis集群ip:port的配置文件

address1=172.28.18.74:8001
address2=172.28.18.74:8002
address3=172.28.18.74:8003
address4=172.28.18.74:8004
address5=172.28.18.74:8005
address6=172.28.18.74:8006
redis.pass=123456

配置jectPoolConfig和工厂类


        
        
        
        
    


        
            /WEB-INF/config/redis-cluster.properties
        
           

        
        
        
        
    

工厂类JedisClusterFactory.java
(这个方法也是从网上看到的,原方法上使用的是无密码的jedisCluster构造方法,此处使用使用含有密码参数的构造方法)

package com.my.frame.redis.cluster;

import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

public class JedisClusterFactory implements FactoryBean, InitializingBean {

    private Resource addressConfig;
    private String addressKeyPrefix ;

    private JedisCluster jedisCluster;
    private Integer timeout;
    private Integer maxRedirections;
    private String password;
    private GenericObjectPoolConfig genericObjectPoolConfig;

    private Pattern p = Pattern.compile("^.+[:]\\d{1,5}\\s*$");

    @Override
    public JedisCluster getObject() throws Exception {
        return jedisCluster;
    }

    @Override
    public Class getObjectType() {
        return (this.jedisCluster != null ? this.jedisCluster.getClass() : JedisCluster.class);
    }

    @Override
    public boolean isSingleton() {
        return true;
    }



    private Set parseHostAndPort() throws Exception {
        try {
            Properties prop = new Properties();
            prop.load(this.addressConfig.getInputStream());

            Set haps = new HashSet();
            for (Object key : prop.keySet()) {

                if (!((String) key).startsWith(addressKeyPrefix)) {
                    continue;
                }

                String val = (String) prop.get(key);

                boolean isIpPort = p.matcher(val).matches();

                if (!isIpPort) {
                    throw new IllegalArgumentException("ip 或 port 不合法");
                }
                String[] ipAndPort = val.split(":");

                HostAndPort hap = new HostAndPort(ipAndPort[0], Integer.parseInt(ipAndPort[1]));
                haps.add(hap);
            }

            return haps;
        } catch (IllegalArgumentException ex) {
            throw ex;
        } catch (Exception ex) {
            throw new Exception("解析 jedis 配置文件失败", ex);
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Set haps = this.parseHostAndPort();
        if(genericObjectPoolConfig == null) {
            genericObjectPoolConfig = new GenericObjectPoolConfig();
        }

        //jedisCluster = new JedisCluster(haps, timeout, maxRedirections,genericObjectPoolConfig);
        /*public JedisCluster(Set jedisClusterNode, int timeout, int maxAttempts, GenericObjectPoolConfig poolConfig) {
            super(jedisClusterNode, timeout, maxAttempts, poolConfig);
        }*/
        jedisCluster = new JedisCluster(haps, timeout,timeout,maxRedirections,password,genericObjectPoolConfig);
        /*public JedisCluster(Set jedisClusterNode, int connectionTimeout, int soTimeout, int maxAttempts, String password, GenericObjectPoolConfig poolConfig) {
            super(jedisClusterNode, connectionTimeout, soTimeout, maxAttempts, password, poolConfig);
        }*/

    }
    public void setAddressConfig(Resource addressConfig) {
        this.addressConfig = addressConfig;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public void setMaxRedirections(int maxRedirections) {
        this.maxRedirections = maxRedirections;
    }

    public void setAddressKeyPrefix(String addressKeyPrefix) {
        this.addressKeyPrefix = addressKeyPrefix;
    }

    public void setGenericObjectPoolConfig(GenericObjectPoolConfig genericObjectPoolConfig) {
        this.genericObjectPoolConfig = genericObjectPoolConfig;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

通过注入jedisCluster我们就可以获得一个JedisCluster示例(工厂类注入实际获得工厂类产生的对象),我们可以封装一个接口对一些基础的方法进行封装,实际使用时通过spring注入我们的接口即可。


    
        
    
package com.my.frame.redis.cluster;

import redis.clients.jedis.JedisCluster;

import java.util.Map;

public class RedisCluster {
    private JedisCluster jedis;


    //Hash
    public boolean set(String key, String field, String value) {
        boolean b = false;
        if(!"".equals(field)) {
            jedis.hset(key, field, value);
            b=true;
        }else {

        }
        return b;
    }

    public String get(String key, String field) {
        String value = "";
        if(!"".equals(field)) {
            value = jedis.hget(key, field);
        }
        return value;
    }

    public Map getAll(String key) {
        Map stringStringMap = jedis.hgetAll(key);
        return stringStringMap;
    }


    //清空
    public void clear(String name){
        jedis.del(name);
    }

    //移除
    public void remove(String key,String field){
        jedis.hdel(key, field);
    }

    //获取数量
    public long len(String key){
        return jedis.hlen(key.getBytes());

    }

    public void setJedis(JedisCluster jedis) {
        this.jedis = jedis;
    }
}

你可能感兴趣的:(java,redis,java)