diff --git a/docs/high-concurrency/images/redis-caching-avoid-penetration.png b/docs/high-concurrency/images/redis-caching-avoid-penetration.png new file mode 100644 index 0000000..13d0247 Binary files /dev/null and b/docs/high-concurrency/images/redis-caching-avoid-penetration.png differ diff --git a/docs/high-concurrency/redis-caching-avalanche-and-caching-penetration.md b/docs/high-concurrency/redis-caching-avalanche-and-caching-penetration.md index 457b3e6..ed54d3c 100644 --- a/docs/high-concurrency/redis-caching-avalanche-and-caching-penetration.md +++ b/docs/high-concurrency/redis-caching-avalanche-and-caching-penetration.md @@ -48,6 +48,15 @@ 解决方式很简单,每次系统 A 从数据库中只要没查到,就写一个空值到缓存里去,比如 `set -999 UNKNOWN` 。然后设置一个过期时间,这样的话,下次有相同的 key 来访问的时候,在缓存失效之前,都可以直接从缓存中取数据。 +当然,如果黑客如果每次使用不同的负数 id 来攻击,写空值的方法可能就不奏效了。更为经常的做法是在缓存之前增加布隆过滤器,将数据库中所有可能的数据哈希映射到布隆过滤器中。然后对每个请求进行如下判断: + +- 请求数据的 key 不存在于布隆过滤器中,可以确定数据就一定不会存在于数据库中,系统可以立即返回不存在。 +- 请求数据的 key 存在于布隆过滤器中,则继续再向缓存中查询。 + +使用布隆过滤器能够对访问的请求起到了一定的初筛作用,避免了因数据不存在引起的查询压力。 + +![redis-caching-avoid-penetration](./images/redis-caching-avoid-penetration.png) + ### 缓存击穿 缓存击穿,就是说某个 key 非常热点,访问非常频繁,处于集中式高并发访问的情况,当这个 key 在失效的瞬间,大量的请求就击穿了缓存,直接请求数据库,就像是在一道屏障上凿开了一个洞。