分布式锁处理缓存redisson实例
对于常规性缓存数据(读多写好 一致性要求非及时性级别)推荐用SpringCache 对于特殊缓存数据的设计 可以借助redisson的各种锁的机制设计模式实现
此方法主要理解 分布式锁工作原理:推荐使用 学习redisson 了解工作原理: 终极方案用springCache的例子 保持原先的查库不变 加一个注解(springCache的一个注解搞定下面两个方法 ) 场景:
首页菜单的数据获取 通过读取缓存来实现 并发请求首页 redis命中 有则返回数据 redis不命中 启动分布式锁 放第一条请求进来 查库防止缓存 非第一条请求 再次先 先验证是否有缓存 有责直接读缓存
@Override public Map<String, List<Catelog2Vo>> getCatalogJson() { //给缓存存放json 拿出的json字符串需要逆转为对象类型【序列化与反序列化】 //1.从缓存取出的json String redisString = stringRedisTemplate.opsForValue().get(RedisConstant.INDEX_CATALOGJSON); if(StringUtils.isEmpty(redisString)){ System.out.println("缓存不命中 查数据库..."); //2.缓存中没有 查询数据库 Map<String, List<Catelog2Vo>> catlogJsonFromDb = getCatalogJsonFromDbWithReddisson(); return catlogJsonFromDb; } System.out.println("缓存命中 直接返回..."); //2. - 直接把缓存取出结果 逆转指定类型 Map<String, List<Catelog2Vo>> result = JSON.parseObject(redisString, new TypeReference< Map<String, List<Catelog2Vo>>>(){ }); return result; }
带有分布式锁的处理缓存:
/** * 缓存里面的数据如何和数据库一致性 * 双写模式: 数据库更新后查出数据把redis更新 存在产生脏数据的风险 -> 读写锁解决 * 失效模式: 数据库更新 删除缓存redis.del(RedisConstant.INDEX_CATALOGJSON_LOCK) 等待下次查询更新 存在产生脏数据的风险 -> 读写锁解决 * * 系统一致性解决方案: * 1.缓存数据都有过期时间,下一次过期触发主动更新数据 * 2.读写数据在 加上分布式的读写锁。 * 经常写 经常读 (读写锁会影响性能 主要是写会影响) * * id udpate -> */ public Map<String,List<Catelog2Vo>> getCatalogJsonFromDbWithReddisson(){ // 1.占分布式锁 (锁的名字 锁的粒度 越细越快) RLock lock = redisson.getLock(RedisConstant.INDEX_CATALOGJSON_LOCK); lock.lock(30,TimeUnit.SECONDS); Map<String, List<Catelog2Vo>> dataFromDb; try{ dataFromDb = getDataFromDb(); }finally { lock.unlock(); } return dataFromDb; }
下一篇:
ZooKeeper源码分析十七之崩溃恢复