背景
在将redis切换到redis cluster中,也遇到一些问题,借此机会和大家分享一下。
1.spring-data-redis与ibatis冲突
使用spring-data-redis操作redis cluster的话,必须将spring版本升级至4.x以上。
如果老项目中使用了ibatis的话,只能用spring3.x ,无法兼容redis cluster。有两个方法解决:
1)使用mybatis替换ibatis,升级spring至4.x版本
2)使用JedisCluster
封装RedisCluster
2.基于JedisCluster进行简单封装
因为看到JedisCluster的配置比较复杂,因此对其进行简单的封装,代码如下:
package com.utils;import redis.clients.jedis.HostAndPort;import redis.clients.jedis.JedisCluster;import redis.clients.jedis.JedisPoolConfig;import java.io.IOException;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Set;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * Created by Administrator on 2017/9/26. */public class RedisClusterManager { private int threadSize=10; private int maxTotal=500; private int maxIdle=100; private int maxWaitMillis=3000; private int timeout=1000; private String redisNodes; ExecutorService executorService; JedisCluster jedisCluster; public void asyncSet(String key,String value){ executorService.execute(new RunOnce(Type.SET,key,value,jedisCluster)); } public void asyncSetExpire(String key,String value,int expire){ executorService.execute(new RunOnce(Type.SET,key,value,expire,jedisCluster)); } public void asyncDel(String key){ executorService.execute(new RunOnce(Type.DEL,key,jedisCluster)); } public void asyncHmset(String key,Maphmset){ executorService.execute(new RunOnce(Type.HMSET,key,hmset,jedisCluster)); } public void asyncHmsetExpire(String key,Map hmset,int expire){ executorService.execute(new RunOnce(Type.HMSET,key,hmset,expire,jedisCluster)); } public String get(String key){ return jedisCluster.get(key); } public Map hgetAll(String key){ return jedisCluster.hgetAll(key); } public Boolean exists(String key){ return jedisCluster.exists(key); } public void set(String key,String value){ jedisCluster.set(key,value); } public void setExpire(String key,String value,int expire){ jedisCluster.set(key,value); jedisCluster.expire(key,expire); } public Long del(String key){ return jedisCluster.del(key); } public void hmset(String key,Map hmset){ jedisCluster.hmset(key,hmset); } public void hmsetExpire(String key,Map hmset,int expire){ jedisCluster.hmset(key,hmset); jedisCluster.expire(key,expire); } public List hmget(String key,String[] propertys){ return jedisCluster.hmget(key,propertys); } public void init(){ if(null == redisNodes||"".equals(redisNodes.trim())) throw new RuntimeException("shardNodes is empty"); String[] addresses = redisNodes.split(","); if(null == addresses||addresses.length==0) throw new RuntimeException("ip or port is empty"); Set jedisClusterNodes = new HashSet (); for(String address: addresses){ String[] addr = address.split(":"); jedisClusterNodes.add(new HostAndPort(addr[0],Integer.valueOf(addr[1]))); } JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(maxTotal); poolConfig.setMaxIdle(maxIdle); poolConfig.setMaxWaitMillis(maxWaitMillis); jedisCluster = new JedisCluster(jedisClusterNodes,timeout,poolConfig); executorService = Executors.newFixedThreadPool(threadSize); } public void destory(){ executorService.shutdownNow(); try { jedisCluster.close(); } catch (IOException e) { e.printStackTrace(); } } class RunOnce implements Runnable{ Type type; String key; String value; Map hmset; int expire=-1; JedisCluster jedisCluster; public RunOnce(Type type, String key, JedisCluster jedisCluster) { this.type = type; this.key = key; this.jedisCluster = jedisCluster; } public RunOnce(Type type, String key, String value, int expire, JedisCluster jedisCluster) { this.type = type; this.key = key; this.value = value; this.expire = expire; this.jedisCluster = jedisCluster; } public RunOnce(Type type, String key, Map hmset, JedisCluster jedisCluster) { this.type = type; this.key = key; this.hmset = hmset; this.jedisCluster = jedisCluster; } public RunOnce(Type type, String key, String value, JedisCluster jedisCluster) { this.type = type; this.key = key; this.value = value; this.jedisCluster = jedisCluster; } public RunOnce(Type type, String key, Map hmset, int expire, JedisCluster jedisCluster) { this.type = type; this.key = key; this.hmset = hmset; this.expire = expire; this.jedisCluster = jedisCluster; } @Override public void run() { if(Type.SET.equals(type)){ jedisCluster.set(key,value); if(expire!=-1) jedisCluster.expire(key,expire); }else if(Type.DEL.equals(type)){ jedisCluster.del(key); }else if(Type.HMSET.equals(type)){ jedisCluster.hmset(key,hmset); if(expire!=-1) jedisCluster.expire(key,expire); } } } enum Type { SET,DEL,HMSET; } public void setThreadSize(int threadSize) { this.threadSize = threadSize; } public void setRedisNodes(String redisNodes) { this.redisNodes = redisNodes; } public void setMaxTotal(int maxTotal) { this.maxTotal = maxTotal; } public void setMaxIdle(int maxIdle) { this.maxIdle = maxIdle; } public void setMaxWaitMillis(int maxWaitMillis) { this.maxWaitMillis = maxWaitMillis; } public void setTimeout(int timeout) { this.timeout = timeout; }}
1)实现功能
封装了set,expire,del,hmset,get,hgetAll,exists,hmget方法,并提供异步支持
2)spring配置
3)代码使用
import com.utils.RedisClusterManager;import org.junit.After;import org.junit.Before;import org.junit.Test;import java.util.concurrent.CountDownLatch;/** * Created by Administrator on 2017/9/26. */public class RedisClusterManagerJunit { RedisClusterManager manager; @Before public void init(){ manager = new RedisClusterManager(); manager.setRedisNodes("" + "redis-cluster0.service.baihe:6379," + "redis-cluster1.service.baihe:6379," + "redis-cluster2.service.baihe:6379," + "redis-cluster3.service.baihe:6379," + "redis-cluster4.service.baihe:6379," + "redis-cluster5.service.baihe:6379," + "redis-cluster6.service.baihe:6379," + "redis-cluster7.service.baihe:6379," + "redis-cluster8.service.baihe:6379," + "redis-cluster9.service.baihe:6379"); manager.init(); } @After public void destory(){ manager.destory(); } @Test public void set() throws InterruptedException { CountDownLatch latch = new CountDownLatch(100000); for(int i=0;i<100000;i++){ manager.set("test"+i,"1"); latch.countDown(); } latch.await(); } @Test public void get() throws InterruptedException { for(int i=0;i<100000;i++){ System.out.println(manager.get("test"+i)); } } @Test public void exists(){ for(int i=0;i<100000;i++){ System.out.println(manager.exists("test"+i)); } } @Test public void del(){ for(int i=0;i<100000;i++){ manager.del("test"+i); System.out.println("test"+i); } }}