布隆過濾器實現的兩種方法

解決(緩解)大量不存在的緩存請求到數據庫,即緩存擊穿

由布隆提出的,她本身是一個很長的二進制向量

也就是說布隆過濾器只能判斷數據是否一定不存在,而無法判斷數據是否一定存在。

  • 優點:由於存放的不是完整的數據,所以佔用的內存很少,而且新增,查詢速度夠快;
  • 缺點: 隨着數據的增加,誤判率隨之增加;無法做到刪除數據;只能判斷數據是否一定不存在,而無法判斷數據是否一定存在。

 

guava實現布過濾器

 

 

  private static int size = 1000000;//預計要插入多少數據
    private static double fpp = 0.01;//期望的誤判率
    private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, fpp);
    public static void main(String[] args) {
        //插入數據
        for (int i = 0; i < 1000000; i++) {
            bloomFilter.put(i);
        }
        int count = 0;
        for (int i = 1000000; i < 2000000; i++) {
            if (bloomFilter.mightContain(i)) {
                count++;
                System.out.println(i + "誤判了");
            }
        }
        System.out.println("總共的誤判數:" + count);
    }

redisson實現布隆過濾器

 

 

 

假設一個網頁黑名單有URL爲100億,每個樣本爲64B,失誤率爲0.01%,

經過上述公式計算後,需要布隆過濾器大小爲25GB,這遠遠小於使用哈希表的640GB的空間。

並且由於是通過hash進行查找的,所以基本都可以在O(1)的時間完成!

 

  @PostMapping("/addUser")
    public Integer insert(@RequestBody MUser user) {
        RBloomFilter<String> bloomFilter = redisson.getBloomFilter(Constant.REDISSON_BLOOMFILTER_USER);
        //布隆過濾器計算的正確率爲97%,初始化布隆過濾器容量爲50000L
        bloomFilter.tryInit(500000L,0.03);
        if (bloomFilter.contains(user.getName())) {
            throw new InvalidArgumentException("用戶名:" + user.getName() + "已經存在");
        }
 
        user.setId(null);
        int res = userMapper.insertSelective(user);
        if (res > 0) {
            //加入布隆過濾器
            bloomFilter.add(user.getName());
        }
        return user.getId();
    }

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章