缓存穿透解决方案
设置空值
![](https://img-blog.csdnimg.cn/img_convert/472d35bd5ad8f99a804546f4c252e536.jpeg)
布隆过滤器
-
优点
-
-
可以将存在的缓存, 位置设置为1, 然后当不存在的参数过来的时候, 会匹配到0上,这样就会直接返回不存在
-
-
缺点
-
-
存在错误判断, hash冲突
-
删除缓存时无法删除指定的1的位置, 应为存在多数据,同一hash, 所以无法删除
-
增加开发成本, 维护成本提高
-
可以判断一定不存在, 但是不能判断一定存在[存在误判]
使用布隆过滤器
添加依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
编写代码
package com.dance.redis;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import org.junit.jupiter.api.Test;
import java.nio.charset.Charset;
import java.util.stream.IntStream;
public class BlTest {
@Test
public void test(){
// 创建
/**
* 数据类型
* 容量
* 误判率
* 容量越大, 误判率越低, 但是使用的内存就越多
* 误判率设置越小, 误判率越低
*/
BloomFilter<String> bloomFilter = BloomFilter.create(
Funnels.stringFunnel(Charset.defaultCharset())
,100000
,0.001
);
// 放入元素
// boolean html = bloomFilter.put("html");
// 判断可能存在
// boolean html1 = bloomFilter.mightContain("html");
// 存放10万数据
IntStream.range(0,200000).forEach(x -> bloomFilter.put(x+""));
int success = 0;
int fail = 0;
for (int i = 0; i < 10000; i++) {
boolean b = bloomFilter.mightContain("test" + i);
if (b){
fail++;
}else{
success++;
}
}
System.out.println("正确:"+success);
System.out.println("错误:"+fail);
}
}
使用的时候可以根据实际情况, 设置这些阈值
缓存击穿解决方案
-
只让一个请求去查数据库, 其他请求进入CAS自旋, 等待请求返回放入缓存, 然后其他线程去查询缓存
缓存雪崩解决方案
在同一时间点, 缓存大面积失效
解决方案
-
设置热点数据永不过期
-
过期时间分散
-
采用多级缓存
-
采购第三方的Redis(各种云)(花钱解决)
版权声明:本文为flowerStream原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。