目录
场景背景
商品SKU,商品的唯一编码即这里的857
查询过程会不断尝试从Redis服务器拉取热数据,如果Redis中没有则会从数据库中缓存到Redis
场景:正常redis有1000条缓存数据,忽然遭到爬虫/流量攻击攻击,大量不存在的于redis的数据批量查询,由于redis不存在这些数据,会到数据库进行查询。由于数据库对于瞬时高并发访问的承载能力弱,所以可能对数据库造成影响,甚至崩溃。绕过redis服务器进入数据库查询的方式叫做缓存穿透。
缓存穿透攻击
指恶意用户在短时间内大量查询不存在的数据,导致大量请求在被送达数据库进行查询,
当请求数量超过数据库负载上限时,使系统响应出现高延迟甚至瘫痪的行为。
如何预防缓存穿透?布隆过滤器BloomFilter
布隆过滤器:由一个很长的二进制向量和一系列随机映射函数组成,可以用于检索一个元素是否在一个集合中
布隆过滤器特点
1.一定的误识别率(即某一元素存在于某集合中,但是实际上该元素并不在集合中)
2.但是没有识别错误的情形(即如果某个元素确实没有在该集合中,那么Bloom Filter 是不会报告该元素存在于集合中的,所以不会漏报)。也就是:我说你不在你就一定不在,我说在,可能不在。
3.删除困难
了解hash:
Hash(散列函数):是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。
由于这种转换,可能存在 不同的输入可能会散列成相同的输出。
Hash算法可以将一个数据转换为一个标志,这个标志,就是视频说的hash,hash后若不存在,就由0变为1。存在,不变。
视频hash1(858),hash2(858),hash3(858)的原理是:
Hash面临的问题就是冲突。假设 Hash 函数是良好的,如果我们的位阵列长度为 m 个点,那么如果我们想将冲突率降低到例如 1%, 这个散列表就只能容纳 m/100 个元素。显然这就不叫空间有效了(Space-efficient)。
解决方法也简单,就是使用多个 Hash,如果它们有一个说元素不在集合中,那肯定就不在。如果它们都说在,虽然也有一定可能性它们在说谎,不过直觉上判断这种事情的概率是比较低的。
减少误判的措施:
1.增加二进制数组位数。
2.增加Hash次数。
开发中使用布隆过滤器
redisson组件内置布隆过滤器,导入直接使用。
项目中如何使用
应用启动时初始化布隆过滤器(将商品在布隆过滤器中先从0转换成1)
用户请求时判断布隆过滤器是否有编号,若布隆过滤器有,读取redis,若redis没有,则读取数据库,载入redis缓存。若布隆过滤器没有,返回数据不存在消息。
假如布隆过滤器初始化后,有商品被删除了怎么办?
布隆过滤器某一位二进制可能被多个编号hash引用(看hash的特点:不同的输入可能会散列成相同的输出)所以不能直接处理删除布隆过滤器的数据。
解决方案:
1.定时异步重建布隆过滤器
2.计数BloomFilter(可以知道该位被几个引用)