缓存穿透
高并发下查询一个值,缓存中没有,数据库中也没有,布隆过滤器
解决方案:
如果数据库中值为空,把空写入缓存即可。也可以把所有的可能存在的key放入到一个大的Bitmap中,查询时通过该Bitmap过滤缓存雪崩
缓存中大量数据同时到期,高并发下,所有请求都走向数据库
解决方案:
尽量不要把所有缓存都设置在同一时间过期, 通过加锁或者队列只允许一个线程查询数据库和写缓存, 其他线程等待.
通过加锁或者队列只允许一个线程查询数据库和写缓存,其他线程等待。
热点缓存(缓存击穿)
双重检测锁解决热点缓存问题,需要加volatile防止指令重排
高并发下,一个热点缓存到期,然后去数据库中去取,当还没有放入缓存中时,大量请求过来
解决方案:
双重检测锁Integer count = redis.get("key"); if (count == null) { synchronized { count = redis.get("key"); if (count == null) { count = repo.getCount(); redis.put("key", count); } } }
也可以用redis的setnx互斥锁进行判断if (redis.setnx(lockKey, requestId, NX, PX) == 1) { }
缓存双写一致性
解决方案:
延时双删策略, 先更新数据库,再删缓存
public void write(String key,Object data){ redis.delKey(key); db.updateData(data); // 可以将以下两步作为异步处理 Thread.sleep(1000); redis.delKey(key); }
还没有评论,来说两句吧...