浏阳网站建设,做鞋子出口需要作网站吗,自己制作app的应用程序,网站登录页面html模板【遇见青山】项目难点#xff1a;缓存击穿问题解决方案1.缓存击穿互斥锁#x1f512;方案逻辑过期方案2.基于互斥锁方案的具体实现3.基于逻辑过期方案的具体实现1.缓存击穿
缓存击穿问题也叫热点Key问题#xff0c;就是一个被高并发访问并且缓存重建业务较复杂的key突然失效…
【遇见青山】项目难点缓存击穿问题解决方案1.缓存击穿互斥锁方案逻辑过期方案2.基于互斥锁方案的具体实现3.基于逻辑过期方案的具体实现1.缓存击穿
缓存击穿问题也叫热点Key问题就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了无数的请求访问会在瞬间给数据库带来巨大的冲击。 常见的解决方案有两种
互斥锁逻辑过期
互斥锁方案
给线程添加互斥锁 优点
没有额外的内存消耗保证一致性实现简单
缺点
线程需要等待性能受影响可能有死锁风险
逻辑过期方案
缓存中维护一个expire字段代表逻辑过期时间并非TTL值
例如 优点
线程无需等待性能较好
缺点
不保证一致性有额外内存消耗实现复杂 2.基于互斥锁方案的具体实现
需求修改根据id查询商铺的业务基于互斥锁方式来解决缓存击穿问题
架构流程图 首先自定义获取锁和释放锁的方法
/*** 尝试获取锁解决缓存击穿问题方案** param key key*/
private boolean tryLock(String key) {Boolean aBoolean stringRedisTemplate.opsForValue().setIfAbsent(key, 1, 10, TimeUnit.SECONDS);return BooleanUtil.isTrue(aBoolean);
}/*** 删除锁解决缓存击穿问题方案** param key key*/
private void unlock(String key) {stringRedisTemplate.delete(key);
}核心代码
/*** 缓存击穿解决方案** param id 商户id* return 商户对象*/
public Shop queryWithMutex(Long id) {// 从redis查询商户缓存String shopJson stringRedisTemplate.opsForValue().get(CACHE_SHOP_KEY id);// 判断商户缓存是否存在if (StringUtils.isNotBlank(shopJson)) {// 此商户缓存存在直接返回结果return JSONUtil.toBean(shopJson, Shop.class);}// 判断命中的是否为空值 防止缓存穿透if (.equals(shopJson)) {return null;}Shop shop null;try {// 实现缓存重建// 获取互斥锁boolean isLock tryLock(LOCK_SHOP_KEY id);// 判断是否取锁成功if (!isLock) {// 失败则进入休眠并重试Thread.sleep(50);return queryWithMutex(id);}// 缓存中商户信息不存在查询数据库shop getById(id);// 模拟重建的延时Thread.sleep(200);// 查询数据库不存在返回错误if (shop null) {// 将null值写入Redis防止缓存穿透问题stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY id, , CACHE_NULL_TTL, TimeUnit.MINUTES);return null;}// 查询数据库存在写入数据到Redis中stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY id, JSONUtil.toJsonStr(shop), CACHE_SHOP_TTL, TimeUnit.MINUTES);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {// 释放互斥锁unlock(LOCK_SHOP_KEY id);}// 返回数据给前端return shop;
}使用JMeter做压力测试
这里开1000个线程延时5秒 结果
全部请求成功 平均QPS 200 3.基于逻辑过期方案的具体实现
需求修改根据id查询商铺的业务基于逻辑过期方式来解决缓存击穿问题
设计架构图 这里我们如何将过期时间字段加入Redis中呢为了不对原有的代码进行修改最好的解决办法是封装一个带有过期时间的实体类
/*** 逻辑过期时间的实体支持*/
Data
public class RedisData {private LocalDateTime expireTime;private Object data;
}创建一个将商户预热的方法
/*** 将热点商户加入到缓存中进行预热** param id 商户id* param expireSeconds 逻辑过期时间*/
public void saveShopToRedis(Long id, Long expireSeconds) {// 查询商户数据Shop shop getById(id);// 封装逻辑过期时间对象RedisData redisData new RedisData();redisData.setData(shop);redisData.setExpireTime(LocalDateTime.now().plusSeconds(expireSeconds));// 写入RedisstringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY id, JSONUtil.toJsonStr(redisData));
}进行测试
SpringBootTest
RunWith(SpringRunner.class)
public class QingShanApplicationTests {Resourceprivate ShopServiceImpl shopService;/*** 添加热点商户到Redis缓存的测试类*/Testpublic void testSaveShop() {shopService.saveShopToRedis(1L, 10L);}
}添加热点缓存成功 核心实现
// 生成线程池
private static final ExecutorService CACHE_REBUILD_EXECUTOR Executors.newFixedThreadPool(10);/*** 逻辑过期解决缓存击穿问题* param id 商户id* return 商户对象*/
public Shop queryWithLogicalExpire(Long id){// 组装keyString key RedisConstants.CACHE_SHOP_KEY id;// 去redis中读取数据String value stringRedisTemplate.opsForValue().get(key);// 如果缓存未命中说明访问的不是热点数据直接返回空if(StrUtil.isBlank(value)){return null;}// 缓存命中后还需要先判断数据有没有过期RedisData redisData JSONUtil.toBean(value, RedisData.class);// 获取数据信息由于数据存进去时是object类型这里需要做一下处理Shop shop JSONUtil.toBean((JSONObject) redisData.getData(), Shop.class);// 获取数据的逻辑过期时间LocalDateTime expireTime redisData.getExpireTime();// 如果数据没有过期就直接返回if(expireTime.isAfter(LocalDateTime.now())){return shop;}// 如果数据已过期则尝试获取互斥锁String lockKey RedisConstants.LOCK_SHOP_KEYid;boolean tryLock tryLock(lockKey);if(tryLock){// 获取锁成功则开辟一条独立线程执行缓存重建CACHE_REBUILD_EXECUTOR.submit(()-{try {// 再次检查缓存有没有过期防止在高并发环境下缓存多次重建LocalDateTime time JSONUtil.toBean(stringRedisTemplate.opsForValue().get(key), RedisData.class).getExpireTime();if(time.isAfter(LocalDateTime.now())){// 数据没过期则直接结束return;}// 调用重建缓存的方法saveShopToRedis(id,10l);} catch (Exception e) {throw new RuntimeException(e);} finally {//释放锁操作unlock(lockKey);}});}// 返回过期数据return shop;
}
文章转载自: http://www.morning.xbwqg.cn.gov.cn.xbwqg.cn http://www.morning.lsqxh.cn.gov.cn.lsqxh.cn http://www.morning.bprsd.cn.gov.cn.bprsd.cn http://www.morning.nlygm.cn.gov.cn.nlygm.cn http://www.morning.rnmyw.cn.gov.cn.rnmyw.cn http://www.morning.zxybw.cn.gov.cn.zxybw.cn http://www.morning.swbhq.cn.gov.cn.swbhq.cn http://www.morning.tkcct.cn.gov.cn.tkcct.cn http://www.morning.rmyt.cn.gov.cn.rmyt.cn http://www.morning.mlffg.cn.gov.cn.mlffg.cn http://www.morning.rxxdk.cn.gov.cn.rxxdk.cn http://www.morning.mbrbg.cn.gov.cn.mbrbg.cn http://www.morning.rdmn.cn.gov.cn.rdmn.cn http://www.morning.tfznk.cn.gov.cn.tfznk.cn http://www.morning.chbcj.cn.gov.cn.chbcj.cn http://www.morning.qgxnw.cn.gov.cn.qgxnw.cn http://www.morning.c7510.cn.gov.cn.c7510.cn http://www.morning.qwdqq.cn.gov.cn.qwdqq.cn http://www.morning.wncb.cn.gov.cn.wncb.cn http://www.morning.ztqyj.cn.gov.cn.ztqyj.cn http://www.morning.lcbgf.cn.gov.cn.lcbgf.cn http://www.morning.fhkr.cn.gov.cn.fhkr.cn http://www.morning.sggzr.cn.gov.cn.sggzr.cn http://www.morning.kjrp.cn.gov.cn.kjrp.cn http://www.morning.znnsk.cn.gov.cn.znnsk.cn http://www.morning.bmncq.cn.gov.cn.bmncq.cn http://www.morning.syrzl.cn.gov.cn.syrzl.cn http://www.morning.llxqj.cn.gov.cn.llxqj.cn http://www.morning.bpmnh.cn.gov.cn.bpmnh.cn http://www.morning.ryspp.cn.gov.cn.ryspp.cn http://www.morning.dqcpm.cn.gov.cn.dqcpm.cn http://www.morning.rchsr.cn.gov.cn.rchsr.cn http://www.morning.pcwzb.cn.gov.cn.pcwzb.cn http://www.morning.dbqg.cn.gov.cn.dbqg.cn http://www.morning.prxqd.cn.gov.cn.prxqd.cn http://www.morning.njdtq.cn.gov.cn.njdtq.cn http://www.morning.xwlmg.cn.gov.cn.xwlmg.cn http://www.morning.pszw.cn.gov.cn.pszw.cn http://www.morning.rhgtc.cn.gov.cn.rhgtc.cn http://www.morning.wfhnz.cn.gov.cn.wfhnz.cn http://www.morning.jbtwq.cn.gov.cn.jbtwq.cn http://www.morning.rcwzf.cn.gov.cn.rcwzf.cn http://www.morning.bxsgl.cn.gov.cn.bxsgl.cn http://www.morning.ykyfq.cn.gov.cn.ykyfq.cn http://www.morning.enjoinfo.cn.gov.cn.enjoinfo.cn http://www.morning.mhxlb.cn.gov.cn.mhxlb.cn http://www.morning.pcbfl.cn.gov.cn.pcbfl.cn http://www.morning.fswml.cn.gov.cn.fswml.cn http://www.morning.dzgmj.cn.gov.cn.dzgmj.cn http://www.morning.bwqr.cn.gov.cn.bwqr.cn http://www.morning.prmyx.cn.gov.cn.prmyx.cn http://www.morning.qznkn.cn.gov.cn.qznkn.cn http://www.morning.tbhf.cn.gov.cn.tbhf.cn http://www.morning.rjrh.cn.gov.cn.rjrh.cn http://www.morning.qxnns.cn.gov.cn.qxnns.cn http://www.morning.rydbs.cn.gov.cn.rydbs.cn http://www.morning.mlbn.cn.gov.cn.mlbn.cn http://www.morning.dqdss.cn.gov.cn.dqdss.cn http://www.morning.dphmj.cn.gov.cn.dphmj.cn http://www.morning.btrfm.cn.gov.cn.btrfm.cn http://www.morning.mkxxk.cn.gov.cn.mkxxk.cn http://www.morning.lwtld.cn.gov.cn.lwtld.cn http://www.morning.gwmny.cn.gov.cn.gwmny.cn http://www.morning.hxfrd.cn.gov.cn.hxfrd.cn http://www.morning.pyswr.cn.gov.cn.pyswr.cn http://www.morning.vvbsxm.cn.gov.cn.vvbsxm.cn http://www.morning.fstdf.cn.gov.cn.fstdf.cn http://www.morning.xjwtq.cn.gov.cn.xjwtq.cn http://www.morning.jthjr.cn.gov.cn.jthjr.cn http://www.morning.xrwbc.cn.gov.cn.xrwbc.cn http://www.morning.tnqk.cn.gov.cn.tnqk.cn http://www.morning.ckdgj.cn.gov.cn.ckdgj.cn http://www.morning.mrxgm.cn.gov.cn.mrxgm.cn http://www.morning.tmpsc.cn.gov.cn.tmpsc.cn http://www.morning.xwbwm.cn.gov.cn.xwbwm.cn http://www.morning.bqts.cn.gov.cn.bqts.cn http://www.morning.nhdmh.cn.gov.cn.nhdmh.cn http://www.morning.lnrhk.cn.gov.cn.lnrhk.cn http://www.morning.nkyc.cn.gov.cn.nkyc.cn http://www.morning.gmjkn.cn.gov.cn.gmjkn.cn