Redis缓存穿透

缓存穿透:

查询一个不存在的数据,mysql查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库。

方法一:

方法二:

布隆过滤器:

简单来说就是一个二进制数组,用0和1来判断数组中是否存在这个元素,整体流程如下:

  1. 将传入的数通过n个哈希函数(不一定是三个)计算出n个哈希值。

  2. 然后在数组中将这n个下标(下标与哈希值相等)中的数由0转换为1。(增)

  3. 判断数是否存在的方法就是看数组中这n个下标中的数是否为1。(查)

缺点:

  1. 删除不便:如下图,假如数组下标为2的位置被用来储存 你好 和 hello 这两个信息,如果想对 你好 进行删除,那我也必然会将 hello 也删除掉

  1. 误判:如下图,id为1的数据将下标为1、3、7的数组数据改为了1,id为2的数据将下标为9、12、14的数组数据改为了1,这时候我们查询id为3的数据,通过三个哈希函数计算出的三个哈希值为3、9、12,数组中明明没有存过这个数据,但是这几个哈希值对应的下标在数组中数据为1,过滤器机会误判数组中存在这个数据。

我们可以通过谷歌的Guava工具类来减少误判

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.nio.charset.Charset;
 
@Configuration
public class BloomFilterConfig {
    /**
     * expectedInsertions:期望添加的数据个数
     * fpp:期望的误判率,期望的误判率越低,布隆过滤器计算时间越长
     *      原因就是fpp越小,占用的空间越大,同时使用的哈希函数越多,出现重复的可能性越小    
     * @return
     */
    @Bean
    public BloomFilter<String> goodsIDBloom(){
        BloomFilter<String> filter = BloomFilter.create(Funnels.stringFunnel(Charset.forName("utf-8")), 1000,0.00001);
        return filter;
    }
 
    @Bean
    public BloomFilter<String> orderBloom(){
        BloomFilter<String> filter = BloomFilter.create(Funnels.stringFunnel(Charset.forName("utf-8")), 1000,0.00001);
        return filter;
    }
}
  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dak2n

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值