大数据专家,教你学Redis缓存穿透终极解决方案,手写布隆过滤器

前言

缓存穿透概念

当查询一个一定不存在的数据,由于缓存不命中,去查询数据库也无法查询出结果,因此不会写入到缓存中,这会导致每个查询都去请求数据库,造成缓存穿透。

解决方案:

布隆过滤对所有的可能查询的参数以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 来免费获取啦~~

错过今天,时不再来!

好的东西就要分享给大家学习!

你可能感兴趣的:(大数据专家,教你学Redis缓存穿透终极解决方案,手写布隆过滤器)