• 我在工作中遇到的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
    #在获取连接的时候检查有效性, 默认false
    TestOnBorrow=false
    #用returnObject方法时,是否进行有效检查
    TestOnReturn=false
    #获取连接时的最大等待毫秒数
    MaxWaitMillis=-1
    #在空闲时检查有效性
    TestWhileIdle=false
    #逐出扫描的时间间隔
    TimeBetweenEvictionRunsMillis=-1
    #每次逐出检查时 逐出的最大数目
    NumTestsPerEvictionRun=3
    #逐出连接的最小空闲时间,默认10分钟
    TimeMillis=600000
    #用户信息过期时间为1天
    userPastTime=86400
    #分割时间设置过期为5分钟
    LoanPastTime=300
    #产品过期时间
    ProductPastTime=60

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

     //redis初始化,JedisPoolConfig为jedis的参数对象,redis在java里封装的对象时redis,参数信息从配置文件读取

    //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")));
    config.setTestOnBorrow(Boolean.parseBoolean(BusinessService.getInstance().getParameter("TestOnBorrow")));
    config.setTestOnReturn(Boolean.parseBoolean(BusinessService.getInstance().getParameter("TestOnReturn")));
    config.setMaxWaitMillis(Long.parseLong(BusinessService.getInstance().getParameter("MaxWaitMillis")));
    config.setTestWhileIdle(Boolean.parseBoolean((BusinessService.getInstance().getParameter("TestWhileIdle"))));
    config.setTimeBetweenEvictionRunsMillis(Long.parseLong(BusinessService.getInstance().getParameter("TimeBetweenEvictionRunsMillis")));
    config.setNumTestsPerEvictionRun(Integer.parseInt(BusinessService.getInstance().getParameter("NumTestsPerEvictionRun")));



    //
    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,

    报这个错的原因:ShardJedisPool是分片处理的,当为集群环境的时候,是不支持路由的,所以会报数据迁移失败

    初始化:

            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();
            }
        }

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

  • 相关阅读:
    BeanUtils在web项目中的应用
    BeanUtils的日期问题
    使用BeanUtils组件
    调用数据库过程函数mysql
    sql注入
    如何取SO中的特性
    Read config detail from SO
    Parts-Ufida ERP project 1
    常用医疗英语
    April 24th 2020
  • 原文地址:https://www.cnblogs.com/weiloong/p/5354705.html
Copyright © 2020-2023  润新知