我在工作中遇到的redis集群使用

Posted Darren_w

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我在工作中遇到的redis集群使用相关的知识,希望对你有一定的参考价值。

写次随笔,给自己工作学习中记录一个笔记

废话不多说,直接上代码:

功能:将相关信息存到redis中,并设置过期时间,如果redis中有,从redis获取,如果没有,从mysql中获取。redis配置了三台集群环境

1:首先,是配置文件中相关配置信息,在java代码中,相关配置直接从配置文件中读取:

#redis配置
MaxActive=10
#最大空闲连接数
MaxIdle=5
#最小空闲连接数
MinIdle=3
#最大连接数
MaxTotal=8
#jedis集群地址A
JedisA.host=192.168.0.191
portA=6300
#jedis集群地址B
JedisB.host=192.168.0.192
portB=6300
#jedis集群地址C
JedisC.host=192.168.0.193
portC=6300
#是否先进先出
Lifo=true
#逐出连接的最小空闲时间,默认10分钟
TimeMillis=600000
#用户信息过期时间为1天
userPastTime=86400
#分割时间设置过期为5分钟
LoanPastTime=300
#产品过期时间
ProductPastTime=60

2:在项目启动的时候,对redis进行初始化:

 //redis初始化,JedisPoolConfig为jedis的参数对象,redis在java里封装的对象时redis,参数信息从配置文件读取
 JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(Integer.parseInt(BusinessService.getInstance().getParameter(
"MaxIdle")));
config.setMaxTotal(Integer.parseInt(BusinessService.getInstance().getParameter(
"MaxTotal")));
config.setMinIdle(Integer.parseInt(BusinessService.getInstance().getParameter(
"MinIdle")));
config.setLifo(Boolean.parseBoolean((BusinessService.getInstance().getParameter(
"Lifo"))));
config.setMinEvictableIdleTimeMillis(Long.parseLong((BusinessService.getInstance().getParameter(
"TimeMillis"))));

//
RedisUtils(config)为工具类,在初始化的时候调用一次,对jedis对象进行初始化
 new RedisUtils(config);

3:RedisUtils类

public RedisUtils(JedisPoolConfig config)
    {
       
        synchronized(this)
        {
            if(jedisCluster==null)
            {
                Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
                jedisClusterNodes.add(new HostAndPort(BusinessService.getInstance().getParameter("JedisA.host"), Integer.parseInt(BusinessService.getInstance().getParameter("portA"))));  
                jedisClusterNodes.add(new HostAndPort(BusinessService.getInstance().getParameter("JedisB.host"), Integer.parseInt(BusinessService.getInstance().getParameter("portB"))));  
                jedisClusterNodes.add(new HostAndPort(BusinessService.getInstance().getParameter("JedisC.host"), Integer.parseInt(BusinessService.getInstance().getParameter("portC"))));
                jedisCluster = new JedisCluster(jedisClusterNodes,2000,2000,config);
            }
        }
        
        
    }

4:jedisCluster存值

/**
     * 
     * @author weishaolong
     * @date 2016-3-29 下午5:13:10 输入参数
     * @param key key
     * @param seconds 有效时间 单位秒
     * @param strValue 值
     */
    public static void setJedis(String key,int seconds,String strValue)
    {
        try
        {
            jedisCluster.setex(key,seconds,strValue);
            
        }
        catch(Exception e)
        {
            log.error("Redis存值异常!By:RedisUtils.setJedis"+e.toString());
        }
        
    }


5:jedisCluster取值

public static String getJedisValue(String key)
    {
        String strJedisVal = null;
        try
        {
            strJedisVal=jedisCluster.get(key);
            return strJedisVal;
        }
        catch(Exception e)
        {
            log.error("Redis取值异常!By:RedisUtils.getJedisValue"+e.toString());
        }
        return strJedisVal;
        
    }

6:这样,使用jedisCluster就可以进行使用了,java业务代码直接RedisUtils.getJedisValue("");就可以获取值了

 

7:其中集群还可以使用ShardJedisPool,但是ShardJedisPool我一直报

jedis.exceptions.JedisMovedDataException: MOVED 632 192.168.0.192:6301,怎么解决,暂时我还没找到解决办法,只知道把193redis服务器改成191或者192就可以解决

初始化:

        List<JedisShardInfo> jdsInfoList =new ArrayList<JedisShardInfo>(3);
         JedisShardInfo infoA = new JedisShardInfo(BusinessService.getInstance().getParameter("JedisA.host"),
                         Integer.parseInt(BusinessService.getInstance().getParameter("portA")));
         JedisShardInfo infoB = new JedisShardInfo(BusinessService.getInstance().getParameter("JedisB.host"),
                         Integer.parseInt(BusinessService.getInstance().getParameter("portB")));
         JedisShardInfo infoC = new JedisShardInfo(BusinessService.getInstance().getParameter("JedisC.host"),
                         Integer.parseInt(BusinessService.getInstance().getParameter("portC")));
         jdsInfoList.add(infoA);
         jdsInfoList.add(infoB);
         jdsInfoList.add(infoC);
         ShardJedisPool =new ShardedJedisPool(config, jdsInfoList);

存值:

public static void setJedis(String key,int seconds,String strValue)
    {
        try
        {
            ShardedJedis shardJedis=ShardJedisPool.getResource();
            shardJedis.setex(key,seconds,strValue);
            ShardJedisPool.returnResourceObject(shardJedis);
            
        }
        catch(Exception e)
        {
            log.error("Redis存值异常!By:RedisUtils.setJedis"+e.toString());
        }
        
    }

取值:

public static String getJedisValue(String key)
    {
        String strJedisVal = null;
        try
        {
            ShardedJedis shardJedis=ShardJedisPool.getResource();
            strJedisVal=shardJedis.get(key);
            ShardJedisPool.returnResourceObject(shardJedis);
            return strJedisVal;
        }
        catch(Exception e)
        {
            log.error("Redis取值异常!By:RedisUtils.getJedisValue"+e.toString());
        }
        return strJedisVal;
        
    }

最后,要注意一点:ShardJedisPool是一个连接池,和mysql的连接池是很类似的,每次从池子中获取值之后,要记得把这个连接返还给池子

ShardJedisPool.returnResourceObject(redis);

项目停止的时候,关闭连接池

public static void closeJedisPool()
    {
        if(ShardJedisPool!=null){
            ShardJedisPool.destroy();
        }
    }

好了,主要是代码层次的讲解,原理方面没怎么说,后期进行补充....

以上是关于我在工作中遇到的redis集群使用的主要内容,如果未能解决你的问题,请参考以下文章

如何利用redis来进行分布式集群系统的限流设计

Node.JS、Socket.IO 和集群中的 WebSocket 握手不起作用

如何删除与 Redis 集群中的模式匹配的键

片段事务中的实例化错误

onRequestPermissionsResult 在片段中不起作用

redis介绍 window 下redis的集群