redis分布式工具类 ----RedisShardedPoolUtil
这个是redis分布式的工具类,看非分布式的看 这里
说一下redis的分布式,分布式,无疑,肯定不是一台redis服务器。假如说,我们有两台redis服务器,一个6379端口,一个6380端口。那么,我们存储一个数据,他会存在哪个redis服务器上呢?那我们要是取该如何取呢?这是我们需要关心的事情。
下面这个工具类,解决了你上面的困扰,他会把数据尽可能的平均分配到每个redis服务器上面。然后你获取也不用纠结哪个服务器上获取。
大体思路和上一篇单机redis差不多,无非是类不一样。
既然是分布式,肯定是需要你获取一个一个redis连接,然后搞一个List放进去,然后写上你需要的一些hash算法,选取规则什么的,这就得到了一个redisPool
看代码吧。
pom.xml
<dependencies> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <!--加速开发的工具,可以省略getset和日志类,只需要注解就可以--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.6</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.5</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.2</version> <scope>compile</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.1.2</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.logback-extensions</groupId> <artifactId>logback-ext-spring</artifactId> <version>0.1.1</version> </dependency> </dependencies>
RedisShardedPool.java
import lombok.extern.slf4j.Slf4j; import redis.clients.jedis.*; import redis.clients.util.Hashing; import redis.clients.util.Sharded; import java.util.ArrayList; import java.util.List; /** * Created by 敲代码的卡卡罗特 */ @Slf4j public class RedisShardedPool { private static ShardedJedisPool pool;//sharded jedis连接池 private static Integer maxTotal = Integer.parseInt(PropertiesUtil.getProperty("redis.max.total","20")); //最大连接数 private static Integer maxIdle = Integer.parseInt(PropertiesUtil.getProperty("redis.max.idle","20"));//在jedispool中最大的idle状态(空闲的)的jedis实例的个数 private static Integer minIdle = Integer.parseInt(PropertiesUtil.getProperty("redis.min.idle","20"));//在jedispool中最小的idle状态(空闲的)的jedis实例的个数 private static Boolean testOnBorrow = Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.borrow","true"));//在borrow一个jedis实例的时候,是否要进行验证操作,如果赋值true。则得到的jedis实例肯定是可以用的。 private static Boolean testOnReturn = Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.return","true"));//在return一个jedis实例的时候,是否要进行验证操作,如果赋值true。则放回jedispool的jedis实例肯定是可以用的。 private static String redis1Ip = PropertiesUtil.getProperty("redis1.ip"); private static Integer redis1Port = Integer.parseInt(PropertiesUtil.getProperty("redis1.port")); private static String redis2Ip = PropertiesUtil.getProperty("redis2.ip"); private static Integer redis2Port = Integer.parseInt(PropertiesUtil.getProperty("redis2.port")); private static void initPool(){ JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(maxTotal); config.setMaxIdle(maxIdle); config.setMinIdle(minIdle); config.setTestOnBorrow(testOnBorrow); config.setTestOnReturn(testOnReturn); config.setBlockWhenExhausted(true);//连接耗尽的时候,是否阻塞,false会抛出异常,true阻塞直到超时。默认为true。 JedisShardInfo info1 = new JedisShardInfo(redis1Ip,redis1Port,1000*2); JedisShardInfo info2 = new JedisShardInfo(redis2Ip,redis2Port,1000*2); List<JedisShardInfo> jedisShardInfoList = new ArrayList<JedisShardInfo>(2); jedisShardInfoList.add(info1); jedisShardInfoList.add(info2); //这就是我上面说的一些参数啥的hash算法之类的 pool = new ShardedJedisPool(config,jedisShardInfoList, Hashing.MURMUR_HASH, Sharded.DEFAULT_KEY_TAG_PATTERN); } static{ initPool(); } public static ShardedJedis getJedis(){ return pool.getResource(); } public static void close(ShardedJedis jedis){ try { if (jedis != null) { jedis.close(); } } catch (Exception e) { log.error("return redis resource exception", e); } } public static void main(String[] args) { /*ShardedJedis jedis = pool.getResource(); System.out.println(jedis.get("key1")); for(int i =0;i<10;i++){ jedis.set("key"+i,"value"+i); } close(jedis); pool.destroy();//临时调用,销毁连接池中的所有连接 System.out.println("program is end");*/ pool.destroy();//临时调用,销毁连接池中的所有连接 } }
RedisShardedPoolUtil.java
import lombok.extern.slf4j.Slf4j; import redis.clients.jedis.ShardedJedis; /** * Created by 敲代码的卡卡罗特 */ @Slf4j public class RedisShardedPoolUtil { /** * 设置key的有效期,单位是秒 * @param key * @param exTime * @return */ public static Long expire(String key,int exTime){ ShardedJedis jedis = null; Long result = null; try { jedis = RedisShardedPool.getJedis(); result = jedis.expire(key,exTime); } catch (Exception e) { log.error("expire key:{} error",key,e); RedisShardedPool.close(jedis); return result; } RedisShardedPool.close(jedis); return result; } //exTime的单位是秒 public static String setEx(String key,String value,int exTime){ ShardedJedis jedis = null; String result = null; try { jedis = RedisShardedPool.getJedis(); result = jedis.setex(key,exTime,value); } catch (Exception e) { log.error("setex key:{} value:{} error",key,value,e); RedisShardedPool.close(jedis); return result; } RedisShardedPool.close(jedis); return result; } public static String set(String key,String value){ ShardedJedis jedis = null; String result = null; try { jedis = RedisShardedPool.getJedis(); result = jedis.set(key,value); } catch (Exception e) { log.error("set key:{} value:{} error",key,value,e); RedisShardedPool.close(jedis); return result; } RedisShardedPool.close(jedis); return result; } public static String get(String key){ ShardedJedis jedis = null; String result = null; try { jedis = RedisShardedPool.getJedis(); result = jedis.get(key); } catch (Exception e) { log.error("get key:{} error",key,e); RedisShardedPool.close(jedis); return result; } RedisShardedPool.close(jedis); return result; } public static Long del(String key){ ShardedJedis jedis = null; Long result = null; try { jedis = RedisShardedPool.getJedis(); result = jedis.del(key); } catch (Exception e) { log.error("del key:{} error",key,e); RedisShardedPool.close(jedis); return result; } RedisShardedPool.close(jedis); return result; } public static String getSet(String key,String value) { ShardedJedis jedis = null; String result = null; try { jedis = RedisShardedPool.getJedis(); result = jedis.getSet(key,value); } catch (Exception e) { log.error("getset key:{} error", key, e); RedisShardedPool.close(jedis); return result; } RedisShardedPool.close(jedis); return result; } public static Long setnx(String key, String value) { ShardedJedis jedis = null; Long result = null; try { jedis = RedisShardedPool.getJedis(); result = jedis.setnx(key, value); } catch (Exception e) { log.error("setnx key:{} value:{} error", key, value, e); RedisShardedPool.close(jedis); return result; } RedisShardedPool.close(jedis); return result; } public static void main(String[] args) { ShardedJedis jedis = RedisShardedPool.getJedis(); System.out.println(jedis.get("key1")); System.out.println("end"); } }
mmall.properties
#redis config start redis1.ip=127.0.0.1 redis1.port=6379 redis2.ip=127.0.0.1 redis2.port=6380 ##Tips:以上redis1和redis2的ip和port改成你自己的哟 #最大连接数 redis.max.total=20 #最大空闲数 redis.max.idle=10 #最小空闲数 redis.min.idle=2 #从jedis连接池获取连接时,校验并返回可用的连接 redis.test.borrow=true #把连接放回jedis连接池时,校验并返回可用的连接 redis.test.return=false #redis config end
PropertiesUtil.java
import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import java.io.IOException; import java.io.InputStreamReader; import java.util.Properties; /** * Created by 敲代码的卡卡罗特 */ @Slf4j public class PropertiesUtil { private static Properties props; static { String fileName = "mmall.properties"; props = new Properties(); try { props.load(new InputStreamReader(PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName),"UTF-8")); } catch (IOException e) { log.error("配置文件读取异常",e); } } public static String getProperty(String key){ String value = props.getProperty(key.trim()); if(StringUtils.isBlank(value)){ return null; } return value.trim(); } public static String getProperty(String key,String defaultValue){ String value = props.getProperty(key.trim()); if(StringUtils.isBlank(value)){ value = defaultValue; } return value.trim(); } public static void main(String[] arg){ System.out.println(PropertiesUtil.getProperty("redis.port")); } }