摘要:再來看怎么結(jié)合一起使用根據(jù)給定的布隆過濾器添加值不能為空根據(jù)給定的布隆過濾器判斷值是否存在不能為空很簡(jiǎn)單,只有兩個(gè)方法,往里面添加元素,檢查元素是否在里面這里的客戶端使用的是封裝的,可以在我的項(xiàng)目中查看完整的使用代碼。
前言
最近在研究布隆過濾器(如果不了解什么是布隆過濾器的,推薦看這篇如何判斷一個(gè)元素在億級(jí)數(shù)據(jù)中是否存在?了解),發(fā)現(xiàn)Guava提供了封裝好的類,但是只能單機(jī)使用,一般現(xiàn)在的應(yīng)用都是部署在分布式系統(tǒng)的,所以想找個(gè)可以在分布式系統(tǒng)下使用的布隆過濾器,找了半天只找到一個(gè)基于redis開發(fā)的模塊項(xiàng)目ReBloom,但是這個(gè)是需要額外安裝的,而且文檔里只說了怎么在docker下運(yùn)行,沒研究過docker所以放棄了。后來找到一篇博客講怎么利用布隆過濾器統(tǒng)計(jì)消息未讀數(shù)的(博客地址不記得了,是一位淘寶同學(xué)寫的),博客最后放了一份整合redis和bloomFilter的代碼demo,詳見BloomFilter.java,看了下實(shí)現(xiàn)比較簡(jiǎn)單,但是使用方式不是我想要的,所以參考著自己整理了一份。BloomFilterHelper
package com.doodl6.springmvc.service.cache.redis; import com.google.common.base.Preconditions; import com.google.common.hash.Funnel; import com.google.common.hash.Hashing; public class BloomFilterHelper{ private int numHashFunctions; private int bitSize; private Funnel funnel; public BloomFilterHelper(Funnel funnel, int expectedInsertions, double fpp) { Preconditions.checkArgument(funnel != null, "funnel不能為空"); this.funnel = funnel; bitSize = optimalNumOfBits(expectedInsertions, fpp); numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, bitSize); } int[] murmurHashOffset(T value) { int[] offset = new int[numHashFunctions]; long hash64 = Hashing.murmur3_128().hashObject(value, funnel).asLong(); int hash1 = (int) hash64; int hash2 = (int) (hash64 >>> 32); for (int i = 1; i <= numHashFunctions; i++) { int nextHash = hash1 + i * hash2; if (nextHash < 0) { nextHash = ~nextHash; } offset[i - 1] = nextHash % bitSize; } return offset; } /** * 計(jì)算bit數(shù)組長(zhǎng)度 */ private int optimalNumOfBits(long n, double p) { if (p == 0) { p = Double.MIN_VALUE; } return (int) (-n * Math.log(p) / (Math.log(2) * Math.log(2))); } /** * 計(jì)算hash方法執(zhí)行次數(shù) */ private int optimalNumOfHashFunctions(long n, long m) { return Math.max(1, (int) Math.round((double) m / n * Math.log(2))); } }
BloomFilterHelper是實(shí)現(xiàn)功能的關(guān)鍵,包含了計(jì)算bitmap的核心算法,其實(shí)大部分代碼都是來源于Guava庫(kù)里面的BloomFilterStrategies類,但是因?yàn)檫@個(gè)類是專門為Guava的BloomFilter類使用的,所以沒有對(duì)外暴露一些重要的算法邏輯。
再來看怎么結(jié)合redis一起使用BloomFilterHelper
RedisServicepackage com.doodl6.springmvc.service.cache.redis; import com.google.common.base.Preconditions; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Collection; import java.util.Map; import java.util.concurrent.TimeUnit; @Service public class RedisService { @Resource private RedisTemplateredisTemplate; /** * 根據(jù)給定的布隆過濾器添加值 */ public void addByBloomFilter(BloomFilterHelper bloomFilterHelper, String key, T value) { Preconditions.checkArgument(bloomFilterHelper != null, "bloomFilterHelper不能為空"); int[] offset = bloomFilterHelper.murmurHashOffset(value); for (int i : offset) { redisTemplate.opsForValue().setBit(key, i, true); } } /** * 根據(jù)給定的布隆過濾器判斷值是否存在 */ public boolean includeByBloomFilter(BloomFilterHelper bloomFilterHelper, String key, T value) { Preconditions.checkArgument(bloomFilterHelper != null, "bloomFilterHelper不能為空"); int[] offset = bloomFilterHelper.murmurHashOffset(value); for (int i : offset) { if (!redisTemplate.opsForValue().getBit(key, i)) { return false; } } return true; } }
RedisService很簡(jiǎn)單,只有兩個(gè)方法
addByBloomFilter,往redis里面添加元素
includeByBloomFilter,檢查元素是否在redis bloomFilter里面
這里redis的客戶端使用的是spring-data-redis封裝的,可以在我的項(xiàng)目SpringMVC-Project中查看完整的使用代碼。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/72665.html
摘要:方法,即表示自動(dòng)擴(kuò)容,這個(gè)函數(shù)名是從中搬過來的。自動(dòng)擴(kuò)容最后,也是最重要的,其中用了布隆過濾器中計(jì)算型數(shù)組長(zhǎng)度的方法,得到之后使用命令初始化一個(gè)全部為的位數(shù)組。 本文源地址:http://www.fullstackyang.com/...,轉(zhuǎn)發(fā)請(qǐng)注明該地址或segmentfault地址,謝謝! 一、背景知識(shí) 在網(wǎng)上已經(jīng)有很多關(guān)于布隆過濾器的介紹了,這里就不再贅述,下面簡(jiǎn)單地提煉幾個(gè)要點(diǎn)...
摘要:方案二布隆過濾器攔截布隆過濾器介紹概念布隆過濾器英語(yǔ)是年由布隆提出的。這就是布隆過濾器的基本思想。防緩存穿透的布隆過濾器判斷是否為合法非法則不允許繼續(xù)查庫(kù)從緩存中獲取數(shù)據(jù)緩存為空從數(shù)據(jù)庫(kù)中獲取緩存空對(duì)象參考書籍開發(fā)與運(yùn)維 上周在工作中遇到了一個(gè)問題場(chǎng)景,即查詢商品的配件信息時(shí)(商品:配件為1:N的關(guān)系),如若商品并未配置配件信息,則查數(shù)據(jù)庫(kù)為空,且不會(huì)加入緩存,這就會(huì)導(dǎo)致,下次在查詢同...
閱讀 3623·2021-11-24 10:25
閱讀 2549·2021-11-24 09:38
閱讀 1238·2021-09-08 10:41
閱讀 2921·2021-09-01 10:42
閱讀 2603·2021-07-25 21:37
閱讀 1997·2019-08-30 15:56
閱讀 928·2019-08-30 15:55
閱讀 2765·2019-08-30 15:54