布隆过滤器的demo
/**
* 缓存击穿
* @author
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:config/spring/spring-dao.xml",
"classpath:config/spring/spring-bean.xml",
"classpath:config/spring/spring-redis.xml"})
public class CacheBreakDownTest {
private static final Logger logger = LoggerFactory.getLogger(CacheBreakDownTest.class); private static final int THREAD_NUM = 100;//线程数量 @Resource
private UserDao UserDao; @Resource
private RedisTemplate redisTemplate; private int count = 0; //初始化一个计数器
private CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUM); private BloomFilter<String> bf; List<UserDto> allUsers; @PostConstruct
public void init(){
//将数据从数据库导入到本地
allUsers = UserDao.getAllUser();
if(allUsers == null || allUsers.size()==0){
return;
}
//创建布隆过滤器(默认3%误差)
bf = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), allUsers.size());
//将数据存入布隆过滤器
for(UserDto userDto : allUsers){
bf.put(userDto.getUserName());
}
} @Test
public void cacheBreakDownTest(){
for(int i=0;i<THREAD_NUM;i++){
new Thread(new MyThread()).start();
//计数器减一
countDownLatch.countDown();
}
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} class MyThread implements Runnable{ @Override
public void run() {
try {
//所有子线程等待,当子线程全部创建完成再一起并发执行后面的代码
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
//随机产生一个字符串
String randomUser = UUID.randomUUID().toString();
// String randomUser = allUsers.get(new Random().nextInt(allUsers.size())).getUserName();
String key = "Key:"+randomUser; //如果布隆过滤器中不存在这个用户直接返回,将流量挡掉
if(!bf.mightContain(randomUser)){
System.out.println("bloom filter don't has this user");
return;
}
//查询缓存,如果缓存中存在直接返回缓存数据
ValueOperations<String,String> operation = (ValueOperations<String, String>) redisTemplate.opsForValue();
synchronized (countDownLatch) {
Object cacheUser = operation.get(key);
if(cacheUser!=null){
System.out.println("return user from redis");
return;
}
//如果缓存不存在查询数据库
List<UserDto> user = UserDao.getUserByUserName(randomUser);
if(user == null || user.size() == 0){
return;
}
//将mysql数据库查询到的数据写入到redis中
System.out.println("write to redis");
operation.set("Key:"+user.get(0).getUserName(), user.get(0).getUserName());
}
} }
}
demo2
@RunWith(SpringRunner.class)
@SpringBootTest
public class BloomFilterTest {
private BloomFilter<Integer> bloomFilter; private int size = 1000000;
@Before
public void init(){
//不设置第三个参数时,误判率默认为0.03
//bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size);
//进行误判率的设置,自动计算需要几个hash函数。bit数组的长度与size和fpp参数有关
//过滤器内部会对size进行处理,保证size为2的n次幂。
bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.01);
for(int i = 0; i < size; i++){
bloomFilter.put(i);
}
}
@Test
public void testBloomFilter(){
for(int i = 0; i < size; i++){
if(!bloomFilter.mightContain(i)){
//不会打印,因为不存在的情况不会出现误判
System.out.println("不存在的误判" + i);
}
} List<Integer> list = new ArrayList<>(1000);
for (int i = size + 10000; i < size + 20000; i++) {
if (bloomFilter.mightContain(i)) {
list.add(i);
}
}
//根据设置的误判率
System.out.println("存在的误判数量:" + list.size());
}
}
布隆过滤器有以下应用场景:
1、黑名单,比如邮件黑名单过滤器,判端邮件地址是否在黑名单中。
2、网络爬虫,判端url是否已经被爬取过。
3、首次访问,判端访问网站的IP是否是第一次访问。
4、缓存击穿,防止非法攻击,频繁发送无法命中缓存的请求,导致缓存击穿,最总引起缓存雪崩。
5、检查英文单词是否拼写正确。
6、K-V系统快速判断某个key是否存在,典型的例子有Hbase,Hbase的每个Region中都包含一个BloomFilter,用于在查询时快速判断某个key在该region中是否存在,如果不存在,直接返回,节省掉后续的查询。
扩展,如何让布隆过滤器支持删除。
进行计数删除,但是计数删除需要存储一个数值,而不是原先的 bit 位,会增大占用的内存大小。这样的话,增加一个值就是将对应索引槽上存储的值加一,删除则是减一,判断是否存在则是看值是否大于0。
布隆过滤器的demo的更多相关文章
- 浅析布隆过滤器及实现demo
布隆过滤器 布隆过滤器(Bloom Filter)是一种概率空间高效的数据结构.它与hashmap非常相似,用于检索一个元素是否在一个集合中.它在检索元素是否存在时,能很好地取舍空间使用率与误报比例. ...
- 【布隆过滤器】基于Hutool库实现的布隆过滤器Demo
布隆过滤器出现的背景: 如果想判断一个元素是不是在一个集合里,一般想到的是将集合中所有元素保存起来,然后通过比较确定.链表.树.散列表(又叫哈希表,Hash table)等等数据结构都是这种思路,存储 ...
- 布隆过滤器(BloomFilter)持久化
摘要 Bloomfilter运行在一台机器的内存上,不方便持久化(机器down掉就什么都没啦),也不方便分布式程序的统一去重.我们可以将数据进行持久化,这样就克服了down机的问题,常见的持久化方法包 ...
- 【面试突击】-缓存击穿(布隆过滤器 Bloom Filter)
原文地址:https://blog.csdn.net/fouy_yun/article/details/81075432 前面的文章介绍了缓存的分类和使用的场景.通常情况下,缓存是加速系统响应的一种途 ...
- python实现布隆过滤器及原理解析
python实现布隆过滤器及原理解析 布隆过滤器( BloomFilter )是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地 ...
- 细谈布隆过滤器及Redis实现
何为布隆过滤器? 本质上是一种数据结构,是1970年由布隆提出的.它实际上是一个很长的二进制向量(位图)和一系列随机映射函数(哈希函数).可以用于检索一个元素是否在一个集合中. 数据结构: 布隆过 ...
- 布隆过滤器的概述及Python实现
布隆过滤器 布隆过滤器是一种概率空间高效的数据结构.它与hashmap非常相似,用于检索一个元素是否在一个集合中.它在检索元素是否存在时,能很好地取舍空间使用率与误报比例.正是由于这个特性,它被称作概 ...
- 【转】Bloom Filter布隆过滤器的概念和原理
转自:http://blog.csdn.net/jiaomeng/article/details/1495500 之前看数学之美丽,里面有提到布隆过滤器的过滤垃圾邮件,感觉到何其的牛,竟然有这么高效的 ...
- 布隆过滤器(Bloom Filter)详解——基于多hash的概率查找思想
转自:http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html 布隆过滤器[1](Bloom Filter)是由布隆(Burton ...
随机推荐
- zabbix4.0开源监控部署
---恢复内容开始--- 1.安装依赖环境 yum -y install telnet net-tools python-paramiko dejavu-sans-fonts python-setup ...
- MySQL 1364 错误提示:#1364 - Field "details" doesn't have a default value
原因:mysql字段设计的时候为not null,结果此字段没有插入值,解决方法: 运行以下命令. SET @@GLOBAL.sql_mode="NO_AUTO_CREATE_USER,NO ...
- php Swoole实现毫秒级定时任务
项目开发中,如果有定时任务的业务要求,我们会使用linux的crontab来解决,但是它的最小粒度是分钟级别,如果要求粒度是秒级别的,甚至毫秒级别的,crontab就无法满足,值得庆幸的是swoole ...
- 使用C#+FFmpeg+DirectX+dxva2硬件解码播放h264流
本文门槛较高,因此行文看起来会乱一些,如果你看到某处能会心一笑请马上联系我开始摆龙门阵 如果你跟随这篇文章实现了播放器,那你会得到一个高效率,低cpu占用(单路720p视频解码播放占用1%左右cpu) ...
- ubuntu server 1604 关机和重启
命令有很多,记住以下两三个就够了 重启: sudo reboot (这个短,易记) sudo shutdown -r now 统一的shutdown形式 关机:sudo shutdown -P no ...
- python gui tkinter快速入门教程 | python tkinter tutorial
本文首发于个人博客https://kezunlin.me/post/d5c57f56/,欢迎阅读最新内容! python tkinter tutorial Guide main ui messageb ...
- Dart Learn Notes 02
Functions Dart是一门面向对象的语言,所以即便是方法也是一个对象,它的类型是Function. 这就意味着方法可以指向变量,也可以作为方法中的参数供其他方法使用.甚至可以让 一个类作为一个 ...
- BeautifulSoup模块的常用方法小结
Beautiful Soup库是解析.遍历.维护“标签树”的功能库. url = "http://desk.zol.com.cn/" request = requests.get( ...
- .Net Core使用分布式缓存Redis:基础
一.前言 Redis的介绍网上很多不再赘述.本次环境为net core 2.2,使用的StackExchange.Redis来操作Redis. 二.引用Microsoft.Extensions.Cac ...
- HTML 5 中的textarea标签
HTML 5 中的textarea标签 定义和用法 定义一个文本区域 (text-area) (一个多行的文本输入区域).用户可在此文本区域中写文本.在一个文本区中,您可输入无限数量的文本.文本区中的 ...