前言
缓存穿透概念
当查询一个一定不存在的数据,由于缓存不命中,去查询数据库也无法查询出结果,因此不会写入到缓存中,这会导致每个查询都去请求数据库,造成缓存穿透。
解决方案:
布隆过滤对所有的可能查询的参数以hash形式存储,在控制器层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力。bloomfilter就类似于一个hash set,用于快速判某个元素是否存在于集合中,其典型的应用场景就是快速判断一个key是否存在于某容器,不存在就直接返回。举例:将真实正确Id在添加完成之后便加入到过滤器当中,每次再进行查询时,先确认要查询的Id是否在过滤器中,如果不在,则说明Id为非法Id。
缓存空对象当从数据库查询不到值,就把参数和控制缓存起来,设置一个简短的过期时间(因为缓存是需要内存的,如果有过多空值key,占用内存多),在该时间段如果有携带此参数再次请求,就可以直接返回。可能导致该段时间缓存层和数据库数据不一致,对于需要保持一致性的业务有影响。
小编觉得学习的话,就得视频+代码+课件配合着学习,这样才能够理解的最够透彻,掌握到知识的精髓,这不,已经都给大家准备好了,大家可以好好学习一波!!!!
BloomFilter_Test.java (手写布隆过滤器代码)
import com.google.common.hash.Funnels;
import com.google.common.hash.Hashing;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
import java.nio.charset.Charset;
public class BloomFilter_Test {
private JedisPool jedisPool = null;
private Jedis jedis = null;
//要存储的数据量··
private static long n = 10000;
//所能容忍错误率
private static double fpp = 0.01F;
//bit数组长度
private static long numBits = optimalNumOfBits(n, fpp);
//hash函数个数
private int numHashFunctions = optimalNumOfHashFunctions(n, numBits);
public static void main(String[] args) {
System.out.println(numBits);
// long[] indexs = new BloomFilter_Test().getIndexs("hello");
BloomFilter_Test filterTest = new BloomFilter_Test();
filterTest.init();
int ex_count = 0;
int ne_count = 0;
/**
* 存在: 不一定存在
* 不存在:一定不存在
*/
for(int i = 0; i < 20000; i++) {
// filterTest.put("bf",100 + i +"");
boolean exist = filterTest.isExist("bf", 100 + i +"");
if(exist){
ex_count++;
}else{
ne_count++;
}
}
//ex_count:6729ne_count 3271
System.out.println("ex_count:"+ ex_count +"\t"+"ne_count "+ ne_count);
}
public voidinit(){
//测试连接redis
jedisPool = new JedisPool("192.168.150.111", 6379);
jedis = jedisPool.getResource();
}
private longgetCount(){
Pipeline pipeline = jedis.pipelined();
Response bf = pipeline.bitcount("bf");
pipeline.sync();
Long count = bf.get();
pipeline.close();
returncount;
}
/**
* 判断keys是否存在于集合where中
*/
public boolean isExist(Stringwhere, String key) {
long[] indexs = getIndexs(key);
boolean result;
//这里使用了Redis管道来降低过滤器运行当中访问Redis次数 降低Redis并发量
Pipeline pipeline = jedis.pipelined();
try {
for(long index : indexs) {
pipeline.getbit(where, index);
}
result = !pipeline.syncAndReturnAll().contains(false);
} finally {
pipeline.close();
}
//if(!result) {
// put(where, key);
// }
returnresult;
}
/**
* 将key存入redis bitmap
*/
private void put(Stringwhere, String key) {
long[] indexs = getIndexs(key);
//这里使用了Redis管道来降低过滤器运行当中访问Redis次数 降低Redis并发量
Pipeline pipeline = jedis.pipelined();
try {
for(long index : indexs) {
pipeline.setbit(where, index,true);
}
pipeline.sync();
/**
* 把数据存储到mysql中
*/
} finally {
pipeline.close();
}
}
这只是部分代码~~~
布隆过滤器算法课件
Redis缓存穿透终极解决方案,手写布隆过滤器,学习视频+代码+课件
需要的小伙伴,可以转发评论关注小编,+++V X :bjmashibing001 来免费获取啦~~
错过今天,时不再来!
好的东西就要分享给大家学习!