spring中Redis的集群简单实现-为我女神而写,我女神jbb

2016-10-19 09:56:57来源:oschina作者:Ta真的很棒人点击

第七城市

通过自己在网上找资料在LINUX系统中安装reids,然后通过一个简单的deno来测试改redis集群是否可用。。


1.通过在网上下载redis的tar安装包( https://github.com/antirez/redis/archive/3.0.0-rc2.tar.gz ),上传到服务器中,

tar-zxvfredis-3.0.0-rc2.tar.gz 解压
mvredis-3.0.0-rc2.tar.gzredis3.0 新建文件并移动到改文件中
cd/usr/local/redis3.0
make
makeinstall 安装

2.一切就绪之后,接下来就是创建集群坏境中所需要的文件

新建文件 mkdir cluster 并在改文件中新建集群的目录文件(7000/7001/7002/7003/7004/7005)
cd cluster ,新建配置文件:redis.conf
vi redis.conf

设置一下参数:port7000

daemonizeyes

cluster-enabledyes

cluster-config-filenodes.conf

cluster-node-timeout5000

appendonlyyes bind 127.0.0.1 192.168.8.98(本机IP,这一步是为了待会在window系统中可以连接该redis)


修改完redis.conf配置文件中的这些配置项之后把这个配置文件分别拷贝到7000/7001/7002/7003/7004/7005目录下面 ,并修改redis.conf文件中port的值分别对应目录的名称


分别启动这6个redis的实例:./redis.server redis.conf

执行redis的创建集群命令创建集群 : ./redis-trib.rbcreate--replicas1127.0.0.1:7000127.0.0.1:7001127.0.0.1:7002127.0.0.1:7003127.0.0.1:7004127.0.0.1:7005


6.1执行上面的命令的时候会报错,因为是执行的ruby的脚本,需要ruby的环境


错误内容:/usr/bin/env:ruby:Nosuchfileordirectory


所以需要安装ruby的环境,这里推荐使用yuminstallruby安装



yuminstallruby

6.2然后再执行第6步的创建集群命令,还会报错,提示缺少rubygems组件,使用yum安装

错误内容:

./redis-trib.rb:24:in`require':nosuchfiletoload--rubygems(LoadError)

from./redis-trib.rb:24


yuminstallrubygems

6.3再次执行第6步的命令,还会报错,提示不能加载redis,是因为缺少redis和ruby的接口,使用gem安装

错误内容:

/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in`gem_original_require':nosuchfiletoload--redis(LoadError)

from/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in`require'

from./redis-trib.rb:25


geminstallredis



6.4再次执行第6步的命令,正常执行


至此redis集群即搭建成功!


分割线--------------------------------------------------------------------------------------------------------------------------------


接下来是在spring代码中去操作该reids,demo通过大致的三层结构实现,代码有点多


1.新建文件:applicationContext-redis.xml 配置如下:



2.新建切面类:RedisCacheInterceptor


@Component @Aspect public class RedisCacheInterceptor {


private Logger logger = Logger.getLogger(this.getClass());private static final String ADD = "@annotation(AddToRedis)";private static final String DELETE = "@annotation(DeleteToRedis)";private static final String GET = "@annotation(GetFromRedis)";private static final String UPDATE = "@annotation(UpdateToRedis)";@Autowiredprivate IRedisCommandService redisCommandService;@Around(ADD)public Object add(ProceedingJoinPoint pjp) throws Throwable{ AddToRedis anno= getAnnotation(pjp,AddToRedis.class); //命名空间 String key = anno.key();


//缓存类型 ReadCacheType cacheType = anno.cacheType(); //返回值 Object fieldValue = String.valueOf(pjp.proceed()); Object[] args = pjp.getArgs(); //加入到缓存中 if(args!= null && args.length>0 && args[0].getClass() == anno.classType()){try { addRedisCache(key,fieldValue.toString(),args[0],0,cacheType);} catch (Exception e) { e.printStackTrace();}} return fieldValue;}/** * 获取缓存信息*TODO:2016-10-14:上午10:06:39*return Object * @throws Throwable */@Around(value = GET)public Object get(ProceedingJoinPoint pjp) throws Throwable{ GetFromRedis anno= getAnnotation(pjp,GetFromRedis.class); String key = anno.key(); String fieldKey = anno.fieldKey(); ReadCacheType cacheType = anno.cacheType(); Object value = null; if(cacheType == ReadCacheType.Set){value = redisCommandService.smemebers(key, anno.classType());if(value == null){ Log.info("[key]"+key+"cache is not exist"); //缓存中不存在,则去数据库中查询数据 value = pjp.proceed(); if(value != null){redisCommandService.sadd(key, value);Log.info("[info]"+"[key]"+"添加缓存成功"); }} }else if(cacheType == ReadCacheType.List){if(fieldKey != null && !fieldKey.equals("")){ String k = parseKey(fieldKey, getMethod(pjp), pjp.getArgs()); value = redisCommandService.getMapValue(key, k); Class c = anno.classType(); value = JSONArray.parseArray((String) value, c); if(value == null){Log.info("[info]"+key+"cache is not find");value = pjp.proceed();redisCommandService.hSetMapList(key, k, (List<?>) value);Log.info("[info]"+key+"has add to cache"); }


} }else if(cacheType == ReadCacheType.Map){if(fieldKey != null && !"".equals(fieldKey)){ String k = parseKey(fieldKey, getMethod(pjp), pjp.getArgs()); value = redisCommandService.hGet(key, k, anno.classType()); if(value == null){Log.info("[info]"+key+"is not exists in cache");//进入数据库中查询value = pjp.proceed();redisCommandService.hSet(key, k, value);Log.info("[info]"+key+"has add to cache"); }} }else if(cacheType == ReadCacheType.Maps){}else if(cacheType == ReadCacheType.String){if(fieldKey != null && "".equals("")){ String k = parseKey(fieldKey, getMethod(pjp), pjp.getArgs()); value = redisCommandService.hGet(key, k, anno.classType()); if(value == null){Log.info("[info]"+key+"is not exists in cache");//进入数据库中查询value = pjp.proceed();redisCommandService.hSet(key, k, value);Log.info("[info]"+key+"has add to cache"); }} }return value;}/** * 删除缓存*TODO:2016-10-13:下午5:35:48*return Object * @throws Throwable */@Around(DELETE)public Object delete(ProceedingJoinPoint pjp) throws Throwable{ DeleteToRedis anno = getAnnotation(pjp,DeleteToRedis.class); String key = anno.key(); String fieldKey = anno.fieldKey(); Object obj = pjp.proceed(); Long result = null; if(obj != null){fieldKey = parseKey(fieldKey, getMethod(pjp), pjp.getArgs());result = redisCommandService.hMapRemove(key, fieldKey); } return result;}/** * 更新缓存*TODO:2016-10-15:下午4:04:53*return Object * @param * @throws Throwable * @throws SecurityException */public Object update(ProceedingJoinPoint pjp) throws Throwable{ UpdateToRedis anno = getAnnotation(pjp,UpdateToRedis.class); return updateRedis(anno,pjp);}private Long updateRedis(UpdateToRedis anno,ProceedingJoinPoint pjp) throws Throwable{ Object value = pjp.proceed(); String key = anno.key(); String m = anno.mapKeyMethodName(); Object params = pjp.getArgs()[0]; T t = (T)params; Class c =t.getClass(); Method mthod = c.getMethod(m); String pk = mthod.invoke(t, null).toString(); return redisCommandService.hSet(key, pk, value);}private void addRedisCache(String key,String fieldKey,Object value,int expireTime,ReadCacheType cacheType) throws Exception{ if(cacheType == ReadCacheType.Map){redisCommandService.hSet(key, fieldKey, value); }}/** * 获取缓存中的key*TODO:2016-10-15:下午2:22:16*return String */private String parseKey(String key,Method method,Object[] args){ String parseKey = null; LocalVariableTableParameterNameDiscoverer temp = new LocalVariableTableParameterNameDiscoverer(); String[] params = temp.getParameterNames(method); HashMap map = new HashMap(); int i = 0; for (String string : params) {map.put("#"+string, args[i]);i++; } parseKey = map.get(key).toString(); return parseKey;}/** * 获取子类的method(实现类) 因为方法*TODO:2016-10-15:上午10:31:58*return void * @throws NoSuchMethodException * @throws SecurityException */private Method getMethod(ProceedingJoinPoint pjp) throws SecurityException, NoSuchMethodException{ Method method = null; try {Object[] args = pjp.getArgs();Class[] argType = new Class[args.length];for (int i = 0; i < args.length; i++) { argType[i] = args[i].getClass();}method = pjp.getTarget().getClass().getMethod(pjp.getSignature().getName(), argType); } catch (Exception e) {e.printStackTrace(); }


return method;}/** * 获取注解*TODO:2016-10-13:下午4:55:27*return void * @return */private T getAnnotation(ProceedingJoinPoint jp,Class clazz){ MethodSignature joinPointObject = (MethodSignature) jp.getSignature(); Method method = joinPointObject.getMethod(); return method.getAnnotation(clazz);} }


3.新建redis的接口类:IRedisCommandService


public interface IRedisCommandService {


/** * 为一个key设置value值 并 设置有效时间 * 成功返回ok * TODO: 2016-8-3:下午10:19:10 */public String set(String key,Object value,int expire) throws Exception;/** * 更具key获取value值 * TODO: 2016-8-3:下午10:26:11 */public T get(String key,Class t) throws Exception;


//-------------------set集合操作/**将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。假如 key 不存在,则创建一个只包含 member 元素作成员的集合。当 key 不是集合类型时,返回一个错误。返回添加的元素数量,重复的元素将被不记数量**/public Long sadd(String key,Object... member) throws Exception;/** * 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。 * 当 key 不是集合类型,返回一个错误。 * 返回被成功移除的元素数量 * **/public Long srem(String key,Object... member) throws Exception;/** * 返回集合中的所有元素 * 不存在元素则返回空集合 * TODO: 2016-8-3:下午10:47:35 */public Set smemebers(String key,Class t) throws Exception;/** * 根据 key 移除set集合 *返回set map list 集合中被删除的数量个数 * TODO: 2016-8-3:下午10:49:42 */public Long sremove(String key) throws Exception;//--------------------map集合操作/** * 将哈希表 key 中的域 field 的值设为 value 。 * 如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。 * 如果域 field 已经存在于哈希表中,旧值将被覆盖。 *成功返回 1 失败返回 0 * TODO: 2016-8-3:下午10:53:38 *///操作单个值public Long hSet(String key,String field,Object obj) throws Exception;/** * 值是list*TODO:2016-10-15:下午3:31:41*return void */public void hSetMapList(String key,String field,List<?> list) throws Exception;public String getMapValue(String key,String fieldKey) throws Exception;public T hGet(String key,String field,Class t) throws Exception;public Long hMapRemove(String key,String fieldKey);///list集合操作 }


实现,该接口类:RedisCommandServiceImpl


@Service("redisCommandServiceImpl") public class RedisCommandServiceImpl implements IRedisCommandService {

@Autowiredprivate JedisCluster jedisCluster;@Overridepublic String set(String key, Object value, int expire) throws Exception { // TODO Auto-generated method stub String result = jedisCluster.set(key, JSON.toJSONString(value)); if(expire > 0 ){//设置有效时间jedisCluster.expire(key, expire); } return result;}


@Overridepublic T get(String key, Class t) throws Exception { String text = jedisCluster.get(key); return JSON.parseObject(text, t);}


@Overridepublic Long sadd(String key, Object... member) throws Exception { String[] item = new String[member.length]; for (int i = 0;i

@Overridepublic Long srem(String key, Object... member) throws Exception { String[] item = new String[member.length]; for(int i=0;i

@Overridepublic Set smemebers(String key, Class t) throws Exception {Set set = jedisCluster.smembers(key); Set sSet = new HashSet(); Iterator iterator = set.iterator(); while(iterator.hasNext()){String text = iterator.next();sSet.add(JSON.parseObject(text, t)); } return sSet;}


@Overridepublic Long sremove(String key) throws Exception { return jedisCluster.del(key);}


@Overridepublic Long hSet(String key, String field, Object obj) throws Exception {


System.out.println(JSON.toJSONString(obj)); return jedisCluster.hset(key, field, JSON.toJSONString(obj));}@Overridepublic T hGet(String key, String field, Class t) throws Exception { List list = null; try {list = jedisCluster.hmget(key, field);if(list != null){ return JSON.parseObject(list.get(0), t);} } catch (Exception e) {throw e; }return null;}


@Overridepublic String getMapValue(String key, String fieldKey) throws Exception { String value = jedisCluster.hget(key, fieldKey); return value;}


@Overridepublic void hSetMapList(String key, String field, List<?> list)throws Exception {jedisCluster.hset(key, field, JSON.toJSONString(list)); }


@Overridepublic Long hMapRemove(String key, String fieldKey) { return jedisCluster.hdel(key, fieldKey); }


}


3.新建测试的用户信息类:


public class User implements Serializable {


/**描述**/private static final long serialVersionUID = 1L;private String userName;private String userPwd;


public String getUserName() { return userName;}public void setUserName(String userName) { this.userName = userName;}public String getUserPwd() { return userPwd;}public void setUserPwd(String userPwd) { this.userPwd = userPwd;}


}


4.操作用户数据信息的接口类:


public interface IUserDao {/*** 用户增加*TODO:2016-8-8:下午2:20:41*@return Long*@author puxiao*/public Long doCreateUser(User u) throws DaoException; /*** 查询用户信息*TODO:2016-8-8:下午2:23:48*@return User*@author puxiao*/public User getUser(Long userId) throws DaoException; }

5.实现该接口:


@Repository public class UserDaoImpl extends BaseSqlMapClientDao implements IUserDao{@AddToRedis(key=RedisBusinessConstant.KEY_BS_USER,cacheType=ReadCacheType.Map,classType=User.class, expireTime = 0)@Overridepublic Long doCreateUser(User u) throws DaoException { Long s = insert("userInfoVO.doCreateUser", u); System.out.println("ssssssssss>>>>"+s); return s;}


@GetFromRedis(key=RedisBusinessConstant.KEY_BS_USER,cacheType=ReadCacheType.Map,classType=User.class,fieldKey="#userId")@Overridepublic User getUser(Long userId) throws DaoException {return null;}


}


6,编写junit测试类


@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath*:applicationContext-db.xml","classpath*:applicationContext-redis.xml"}) public class TestDataSource {@Autowiredprivate IUserService service;@Testpublic void testRedisCache(){ //addUser(); getUser();}/** * 缓存----测试增加用户*TODO:2016-10-17:下午4:39:36*return void */public void addUser(){ User u = new User(); u.setPdaPwd("admin"); u.setSiteName("admin123"); Long result = service.doCreateUser(u); System.out.println("result:"+result);}/** * 从缓存中获取用户信息 根据用户id去查询用户信息*TODO:2016-10-17:下午5:03:01*return void */public void getUser(){ User userInfo = service.getUser(11517l); System.out.println(userInfo.getUserName()); System.out.println(userInfo.getCreatedBy());} }


启动测试:(1)增加用户


控制台信息:



查询数据库改用户信息被成功添加进去:



我们再来redis中查询是否存在该信息,


可以看到的是该用户信息id为:11601的用户信息 ,是以json的格式存在的,


,从redis长获取该用户,可以看到的是控制台并没有发送sql语句,而取的是存在redis中的用户信息。


第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台