布隆过滤器的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 ...
随机推荐
- pat 1120 Friend Numbers(20 分)
1120 Friend Numbers(20 分) Two integers are called "friend numbers" if they share the same ...
- MySQL常用的查询语句回顾
让你快速复习语句的笔记宝典. create table users( username varchar(20) primary key, userpwd varchar(20) ) alt ...
- P3954 成绩
题目描述 牛牛最近学习了C++入门课程,这门课程的总成绩计算方法是: 总成绩=作业成绩\times 20\%+×20%+小测成绩×30\%+×30%+期末考试成绩\times 50\%×50% 牛牛想 ...
- Django ORM-objects-QuerySet
Django ORM ORM执行查看原生SQL的两种方法 1.在setting中配置 LOGGING = { 'version': 1, 'disable_existing_loggers': Fal ...
- Layui下拉3级联动
这里我就不给大家详细说明了直接附图: js代码: layui.use(['layer', 'form','xform','layer'], function () { var element = la ...
- 二叉树的操作--C语言实现
树是一种比较复杂的数据结构,它的操作也比较多.常用的有二叉树的创建,遍历,线索化,线索化二叉树的遍历,这些操作又可以分为前序,中序和后序.其中,二叉树的操作有递归与迭代两种方式,鉴于我个人的习惯,在这 ...
- Thinkphp5——实现分页(模型和Db分页,多种方法)
现在很多网站的数据量的很多,如果全部在一页里显示效果不好,数据量太大,那怎么办?这时我们就需要分页,而分页的好处就是分段显示数据,这样页面就不用加载很多数据,需要时才加载,下面我教大家实现ThinkP ...
- 【Python3网络爬虫开发实战】6.4-分析Ajax爬取今日头条街拍美图【华为云技术分享】
[摘要] 本节中,我们以今日头条为例来尝试通过分析Ajax请求来抓取网页数据的方法.这次要抓取的目标是今日头条的街拍美图,抓取完成之后,将每组图片分文件夹下载到本地并保存下来. 1. 准备工作 在本节 ...
- .Net Core的API网关Ocelot使用 (一)
1.什么是API网关 API网关是微服务架构中的唯一入口,它提供一个单独且统一的API入口用于访问内部一个或多个API.它可以具有身份验证,监控,负载均衡,缓存,请求分片与管理,静态响应处理等.API ...
- MySQL必知必会(组合Where子句,Not和In操作符)
SELECT prod_id, prod_price, prod_name FROM products ; SELECT prod_id, prod_price, prod_name FROM pro ...