redis热点key缓存击穿

一般缓存设计都是使用缓存+失效时间的模式,这种模式存在一种问题。对于一些热点key的数据,当该key的缓存失效,需要重新从DB数据库获取。这时,涌入大量请求,所有请求并发地访问DB数据库,可能会压垮数据库,这种情况叫做缓存击穿。

解决方案如下

  • 使用互斥分布式锁

在请求并发访问数据库时,对查询数据库操作进行加锁,同一时间只有一个请求操作数据库。示例代码如下:

 public Goods getById(Long id) {

        if (Objects.isNull(id)) {
            return null;
        }
        String key = GOODS + id;
        String goodsJson = redisTemplate.opsForValue().get(key);
        if (StringUtils.isNotBlank(goodsJson)) {
            return JSON.parseObject(goodsJson, WinemallGoods.class);
        }
        String owner = String.valueOf(Thread.currentThread().getId());
        // 使用分布式锁,同一时间只有一个请求成功访问数据库
        redisLock.lock(key, owner, 10000L, 1000L);
        try {
            Goods goods = goodsMapper.selectByPrimaryKey(id);
            if (Objects.nonNull(goods)) {

                redisTemplate.opsForValue().set(key, JSON.toJSONString(goods), RedisConst.DEFAULT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
                return goods;
            } else {

                // 穿透优化
                redisTemplate.opsForValue().set(key, JSON.toJSONString(new WinemallGoods()), RedisConst.DEFAULT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
                return null;
            }
        } finally {
            redisLock.unlock(key, owner);
        }
    }
  • 设置热点key数据永不过期
发布了37 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/new_com/article/details/104253723