實現布隆過濾器的三種方式
一、谷歌布隆過濾器
專案地址:https://gitee.com/quancong/redis.git
BloomFilter專案
需求:判斷是否是已註冊過的使用者
1、引入布隆過濾器pom依賴
<!-- 谷歌布隆過濾器-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
2、資料庫中表資料
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '使用者名稱',
`password` varchar(20) NOT NULL DEFAULT '' COMMENT '使用者建立時間',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
BEGIN;
INSERT INTO `user` VALUES (1, '張三', '2020-07-31 17:08:42');
INSERT INTO `user` VALUES (2, '李四', '2020-07-31 07:10:14');
INSERT INTO `user` VALUES (3, '王五', '2020-07-31 20:30:09');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
3、啟動springboot專案時將使用者id新增到布隆過濾器中來
/**
* 啟動時初始化布隆過濾器
*/
@Service
public class BloomFilterService implements ApplicationRunner {
@Autowired
private UserDao userDao;
private BloomFilter<Integer> bf;
/**
* 啟動時將資料庫中使用者id載入到布隆過濾器中來
* @param args
* @throws Exception
*/
@Override
public void run(ApplicationArguments args) throws Exception {
List<Integer> userIdList = userDao.findAllUserId();
if (CollectionUtils.isEmpty(userIdList)) return;
//建立布隆過濾器 誤判率預設為3%
bf = BloomFilter.create(Funnels.integerFunnel(),userIdList.size());
for (Integer userId : userIdList) {
bf.put(userId);
}
}
/***
* 判斷id可能存在於布隆過濾器裡面
* @param id
* @return
*/
public boolean userIdExists(int id){
return bf.mightContain(id);
}
}
這裡同時還有一個判斷使用者id可能存在的方法
4、編寫controller測試一下
@RestController
public class UserController {
@Autowired
private BloomFilterService bloomFilterService;
@RequestMapping("/bloom/idExists")
public boolean ifExists(int id){
return bloomFilterService.userIdExists(id);
}
}
瀏覽器輸入http://localhost:8080/bloom/idExists?id=1,即一個已存在的使用者id
輸入一個存在的使用者id返回true
輸入一個不存在的使用者id返回false
二、redis原生setbit命令實現
因篇幅過長,可參見我的另一篇部落格。
https://blog.csdn.net/qq_41963899/article/details/108911244
三、使用redis布隆過濾器外掛實現
1、安裝布隆過濾器
git clone git://github.com/RedisLabsModules/rebloom
cd rebloom
make
2、有一個redisbloom.so檔案,複製路徑,假如為path,在redis.conf中指定該模組
loadmodule /path/rebloom.so
3、重啟redis
redis-server ./redis.conf
4、測試
redis-cli bf.add myBloom redis1 # 向myBloom布隆過濾器新增redis1鍵
redis-cli bf.add myBloom redis2
redis-cli # 進入redis客戶端
判斷yBloom布隆過濾器是否存在redis1、redis2、redis3這些鍵
bf.exists myBloom redis1
bf.exists myBloom redis2
bf.exists myBloom redis3
5、springboot整合redis布隆過濾器
專案原始碼:https://gitee.com/quancong/redis.git
@Service
public class RedisBloomFilter {
@Autowired
private RedisTemplate redisTemplate;
public Boolean bloomFilterAdd(String filterName,int value){
DefaultRedisScript<Boolean> bloomAdd = new DefaultRedisScript<>();
bloomAdd.setScriptSource(new ResourceScriptSource(new ClassPathResource("bloomFilterAdd.lua")));
bloomAdd.setResultType(Boolean.class);
List<Object> keyList= new ArrayList<>();
keyList.add(filterName);
keyList.add(value+"");
Boolean result = (Boolean) redisTemplate.execute(bloomAdd,keyList);
return result;
}
public Boolean bloomFilterExists(String filterName,int value){
DefaultRedisScript<Boolean> bloomExists= new DefaultRedisScript<>();
bloomExists.setScriptSource(new ResourceScriptSource(new ClassPathResource("bloomFilterExist.lua")));
bloomExists.setResultType(Boolean.class);
List<Object> keyList= new ArrayList<>();
keyList.add(filterName);
keyList.add(value+"");
Boolean result = (Boolean) redisTemplate.execute(bloomExists,keyList);
return result;
}
}
測試一下:
@RestController
public class RedisController {
@Autowired
private RedisBloomFilter redisBloomFilter;
@RequestMapping("/bloom/redisIdExists")
public boolean redisidExists(int id){
return redisBloomFilter.bloomFilterExists("myBloom",id);
}
@RequestMapping("/bloom/redisIdAdd")
public boolean redisidAdd(int id){
return redisBloomFilter.bloomFilterAdd("myBloom",id);
}
}
先往布隆過濾器中新增兩條資料
http://localhost:8080/bloom/redisIdAdd?id=1
再測試一下redis布隆過濾器不存在的資料
http://localhost:8080/bloom/redisIdExists?id=3
成功!
相關文章
- PHP實現布隆過濾器PHP過濾器
- 布隆過濾器過濾器
- 詳解布隆過濾器的原理和實現過濾器
- Guava的布隆過濾器Guava過濾器
- 詳解布隆過濾器原理與實現過濾器
- Redis 中的布隆過濾器Redis過濾器
- 淺談布隆過濾器過濾器
- Redis-布隆過濾器Redis過濾器
- 布隆過濾器(Bloom Filter)過濾器OOMFilter
- 大白話布隆過濾器過濾器
- 布隆過濾器 Bloom Filter過濾器OOMFilter
- Bloom Filter 布隆過濾器OOMFilter過濾器
- 利用 Redis 的 bitmap 實現簡單的布隆過濾器Redis過濾器
- 布隆過濾器(BloomFilter)原理 實現和效能測試過濾器OOMFilter
- Redis 應用-布隆過濾器Redis過濾器
- victoriaMetrics庫之布隆過濾器過濾器
- 布隆過濾器 與 Redis BitMap過濾器Redis
- Xor過濾器:比布隆Bloom過濾器更快,更小過濾器OOM
- 從點陣圖到布隆過濾器,C#實現過濾器C#
- 布隆過濾器-使用場景的思考過濾器
- 布隆過濾器的原理及應用過濾器
- 布隆過濾器(Bloom Filter)詳解過濾器OOMFilter
- 還有人不懂布隆過濾器嗎?過濾器
- 5分鐘掌握布隆過濾器過濾器
- 布隆過濾器實戰【防止快取擊穿】過濾器快取
- 品味布隆過濾器的設計之美過濾器
- 冷飯新炒:理解布隆過濾器演算法的實現原理過濾器演算法
- 從快取穿透聊到布隆過濾器快取穿透過濾器
- 演算法(3)---布隆過濾器原理演算法過濾器
- Redis詳解(十三)------ Redis布隆過濾器Redis過濾器
- Redis布隆過濾器分析與總結Redis過濾器
- 特殊的資料結構(布隆過濾器)的原理和實現及探究資料結構過濾器
- AI考拉技術分享--布隆過濾器實戰AI過濾器
- 那些有趣的演算法之布隆過濾器演算法過濾器
- LevelDB 學習筆記1:布隆過濾器筆記過濾器
- 【實戰問題】-- 快取穿透之布隆過濾器(1)快取穿透過濾器
- 一文徹底弄清Redis的布隆過濾器Redis過濾器
- Redis快取穿透解決方案--布隆過濾器Redis快取穿透過濾器