zoukankan      html  css  js  c++  java
  • redis集群(多机)分布

    一、实现原理

      一致性哈希算法(Consistent Hashing): http://www.zsythink.net/archives/1182

    二、配置两个redis服务,端口号要不一致

    三、代码

    1. 配置文件
        redis1.ip = 127.0.0.1
        redis1.port=6379
    
        redis2.ip = 127.0.0.1
        redis2.port=6380
    
        #最大连接数
        redis.max.total=20
        #最大空闲数
        redis.max.idle=10
        #最小空闲数
        redis.min.idle=2
        #效验使用可用连接
        redis.test.borrow=true
        #效验归还可用连接
        redis.test.return=false
     1 package com.mmall.common;
     2 
     3 import com.mmall.util.PropertiesUtil;
     4 import redis.clients.jedis.JedisPoolConfig;
     5 import redis.clients.jedis.JedisShardInfo;
     6 import redis.clients.jedis.ShardedJedis;
     7 import redis.clients.jedis.ShardedJedisPool;
     8 import redis.clients.util.Hashing;
     9 import redis.clients.util.Sharded;
    10 import java.util.ArrayList;
    11 import java.util.List;
    12 
    13 /**
    14  * redis分片连接池
    15  */
    16 public class RedisShardedPool {
    17     private static ShardedJedisPool pool ; //jedis连接池
    18     private static Integer maxTotal = Integer.parseInt(PropertiesUtil.getProperty("redis.max.total","20")); //最大连接数
    19     private static Integer maxIdle = Integer.parseInt(PropertiesUtil.getProperty("redis.max.idle","10")); //最大空闲状态
    20     private static Integer minIdle =Integer.parseInt(PropertiesUtil.getProperty("redis.min.idle","2")); //最小空闲状态
    21 
    22     private static Boolean testOnBorrow =Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.borrow","true")); //验证从连接池拿出的jedis实例,一定可用
    23     private static Boolean testOnReturn =Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.return","true")); //验证还回连接池的jedis实例,一定可用
    24 
    25     private static String redis1Ip =PropertiesUtil.getProperty("redis1.ip"); //最小空闲状态
    26     private static Integer redis1Port =Integer.parseInt(PropertiesUtil.getProperty("redis1.port")); //最小空闲状态
    27     private static String redis2Ip =PropertiesUtil.getProperty("redis2.ip"); //最小空闲状态
    28     private static Integer redis2Port =Integer.parseInt(PropertiesUtil.getProperty("redis2.port")); //最小空闲状态
    29 
    30     private static void initPool(){
    31         JedisPoolConfig config = new JedisPoolConfig();
    32         config.setMaxTotal(maxTotal);
    33         config.setMaxIdle(maxIdle);
    34         config.setMinIdle(minIdle);
    35 
    36         config.setTestOnBorrow(testOnBorrow);
    37         config.setTestOnReturn(testOnReturn);
    38 
    39         config.setBlockWhenExhausted(true); //连接耗尽时是否阻塞,false抛出异常;true阻塞到超时。默认true
    40 
    41         JedisShardInfo info1 = new JedisShardInfo(redis1Ip,redis1Port,1000*2);
    42         JedisShardInfo info2 = new JedisShardInfo(redis2Ip,redis2Port,1000*2);
    43         List<JedisShardInfo> jedisShardInfoList = new ArrayList<JedisShardInfo>(2);
    44         jedisShardInfoList.add(info1);
    45         jedisShardInfoList.add(info2);
    46 
    47         pool = new ShardedJedisPool(config,jedisShardInfoList, Hashing.MURMUR_HASH, Sharded.DEFAULT_KEY_TAG_PATTERN);
    48     }
    49 
    50     static{
    51         initPool();
    52     }
    53 
    54     public static ShardedJedis getJedis(){
    55         return pool.getResource();
    56     }
    57 
    58     /**
    59      * redis不正常不可用,将其废弃,最新版本直接将此连接销毁jedis.close();
    60      * @param jedis
    61      */
    62     public static void returnBrokenResource(ShardedJedis jedis){
    63         pool.returnBrokenResource(jedis);
    64     }
    65 
    66     public static void returnResource(ShardedJedis jedis){
    67         pool.returnResource(jedis);
    68     }
    69 
    70     public static void main(String[] args) {
    71         ShardedJedis shardedJedis = pool.getResource();
    72         for (int i = 0; i<10; i++){
    73             shardedJedis.set("key"+i,"value"+i);
    74         }
    75         returnResource(shardedJedis); //使用后的连接放回连接池中
    76 //        pool.destroy(); // 销毁连接池的所有连接
    77         System.out.println("program is end");
    78 
    79     }
    80 }

    运行main方法,查询redis生成的数据:

    封装常用redisAPI

    import com.mmall.common.RedisShardedPool;
    import lombok.extern.slf4j.Slf4j;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.ShardedJedis;
    
    /**
     * 封装分片redis
     */
    @Slf4j
    public class RedisShardedPoolUtil {
    
        /**
         * 设置对应key的有效期
         * @param key
         * @param exTime 有效期,单位秒
         * @return
         */
        public static Long expire(String key, int exTime){
            ShardedJedis shardedJedis = null;
            Long result = null;
            try{
                shardedJedis = RedisShardedPool.getJedis();
                result = shardedJedis.expire(key,exTime);
            }catch (Exception e){
                log.error("set key:{} exTime:{} value:{} error",key,exTime,e);
                RedisShardedPool.returnBrokenResource(shardedJedis);
                return result;
            }
            RedisShardedPool.returnResource(shardedJedis);
            return result;
        }
    
        /**
         * string 添加,存在有效期exTime
         * @param key 键
         * @param value 值
         * @param exTime 有效期,单位秒
         * @return
         */
        public static String setEx(String key, String value, int exTime){
            ShardedJedis shardedJedis = null;
            String result = null;
            try{
                shardedJedis = RedisShardedPool.getJedis();
                result = shardedJedis.setex(key,exTime,value);
            }catch (Exception e){
                log.error("set key:{} exTime:{} value:{} error",key,exTime,value,e);
                RedisShardedPool.returnBrokenResource(shardedJedis);
                return result;
            }
            RedisShardedPool.returnResource(shardedJedis);
            return result;
        }
    
        /**
         * string 添加
         * @param key
         * @param value
         * @return
         */
        public static String set(String key, String value){
            ShardedJedis shardedJedis = null;
            String result = null;
            try{
                shardedJedis = RedisShardedPool.getJedis();
                result = shardedJedis.set(key,value);
            }catch (Exception e){
                log.error("set key:{} value:{} error",key,value,e);
                RedisShardedPool.returnBrokenResource(shardedJedis);
                return result;
            }
            RedisShardedPool.returnResource(shardedJedis);
            return result;
        }
    
        /**
         * string 获取
         * @param key
         * @return
         */
        public static String get(String key){
            ShardedJedis shardedJedis = null;
            String result = null;
            try{
                shardedJedis = RedisShardedPool.getJedis();
                result = shardedJedis.get(key);
            }catch (Exception e){
                log.error("get key:{} error",key,e);
                RedisShardedPool.returnBrokenResource(shardedJedis);
                return result;
            }
            RedisShardedPool.returnResource(shardedJedis);
            return result;
        }
        public static String  getSet(String key, String value){
            ShardedJedis shardedJedis = null;
            String result = null;
            try{
                shardedJedis = RedisShardedPool.getJedis();
                result = shardedJedis.getSet(key,value);
            }catch (Exception e){
                log.error("set key:{} value:{} error",key,value,e);
                RedisShardedPool.returnBrokenResource(shardedJedis);
                return result;
            }
            RedisShardedPool.returnResource(shardedJedis);
            return result;
        }
    
        /**
         * stirng 删除
         * @param key
         * @return
         */
        public static Long del(String key){
            ShardedJedis shardedJedis = null;
            Long result = null;
            try{
                shardedJedis = RedisShardedPool.getJedis();
                result = shardedJedis.del(key);
            }catch (Exception e){
                log.error("get key:{} error",key,e);
                RedisShardedPool.returnBrokenResource(shardedJedis);
                return result;
            }
            RedisShardedPool.returnResource(shardedJedis);
            return result;
        }
    
        public static Long  setnx(String key, String value){
            ShardedJedis shardedJedis = null;
            Long result = null;
            try{
                shardedJedis = RedisShardedPool.getJedis();
                result = shardedJedis.setnx(key,value);
            }catch (Exception e){
                log.error("set key:{} value:{} error",key,value,e);
                RedisShardedPool.returnBrokenResource(shardedJedis);
                return result;
            }
            RedisShardedPool.returnResource(shardedJedis);
            return result;
        }
    }

    四、ShardedJedis相关类介绍

      (1)、ShardedJedisPool

        ShardedJedis是基于一致性哈希算法实现的分布式Redis集群客户端;ShardedJedis的设计分为以下几块:
        对象池设计:Pool,ShardedJedisPool,ShardedJedisFactory
        面向用户的操作封装:BinaryShardedJedis,BinaryShardedJedis
        一致性哈希实现:Sharded

        Sharded一致性哈希实现
        shared一致性哈希采用以下方案:
        Redis服务器节点划分:将每台服务器节点采用hash算法划分为160个虚拟节点(可以配置划分权重)
        将划分虚拟节点采用TreeMap存储
        对每个Redis服务器的物理连接采用LinkedHashMap存储
         对Key or KeyTag 采用同样的hash算法,然后从TreeMap获取大于等于键hash值得节点,取最邻近节点存储;当key的hash值大于虚拟节点hash值得最大值时,存入第一个虚拟节点。

      (2)、JedisShardInfo

          配置每台redis服务器的连接

         JedisShardInfo info1 = new JedisShardInfo(redis1Ip,redis1Port,1000*2);
  • 相关阅读:
    爬虫第一课
    下午写的一个代码,还没调试
    ASP.NET 中添加、删除、修改记录
    C# 学习一(概念)
    读取数据库(SQL 、Access)、数据类型转换(Convert.Tostring)、数据库链接
    投票处理页面 vote.aspx.cs
    ASP.NET 读取数据库(二)
    关于控件、命名空间、参数(object sender,System.EventArgs e)
    控件的简单使用
    ADO(SQL、ACCESS 数据库链接代码)
  • 原文地址:https://www.cnblogs.com/FondWang/p/11690791.html
Copyright © 2011-2022 走看看