Redis04——穿透、击穿

103 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

缓存击穿

数据库是架构的瓶颈,为了使有效请求能够到达数据库,即便放大前置环节的复杂度和成本

image-20210309132305485

缓存穿透:查询数据时Redis中没有数据数据库也没有数据.

若这样的无效请求多了,会导致数据库有效请求变慢增大数据库压力,黑客也可能使用这种方式攻击。

解决方式

(1)key null,将无效请求的数据作为key,value设置空值null存入redis中。

缺点: (1) 浪费空间,无效key多了,占用空间越来越大 (2) 无法解决大量穿透的情况

(2)布隆过滤器

将数据库的所有数据hash到一个足够大的bitmaps位图类型数据中,每次查询key时,先用key的hash值到bitmaps中查询,若未命中则不需要再到redis或数据库中查询;若命中则说明数据有可能在redis或数据库中(为什么不是一定呢?因为hash冲突)。

Bitmaps 是位图数据结构,使用二进制位来记录信息,只有0和1两个状态

缓存击穿

image-20210309133256790

缓存击穿:查询数据时请求了数据库有但redis没有缓存的数据.(网上经常说是热点key过期,不是本质)

比如一个热点key在某一时刻key过期了,大量关于该key的请求在缓存中查不到就会全部打到数据库,导致数据库被一瞬间压垮。

解决方案

(1)人工解决+永不过期

人工解决:派人实时监控热点数据,实时调整key的过期时长。缺点不可靠

因为不知道哪个key何时会被高并发请求,要从一开始就假设所有key都可能被高并发请求才安全,才能保障到达数据库的都是有效请求

永不过期:不设置过期时间,每个数据设置逻辑过期时间,通过单独的线程重建缓存

(2)使用分布式锁

查询为空的请求要获取锁才能继续到数据库中查询,没抢到锁的请求则阻塞,获取到锁的请求查询后更新redis(其他线程阻塞影响性能)。

【set key value ex 100 nx】 (注意设置key的过期时间value设置为唯一标志防止锁被误删,使用LUA脚本原子性删除锁)