没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
试读
13页
本文深入探讨了Redis缓存的关键策略与性能优化技巧。首先,解决缓存穿透,强调缓存空对象与布隆过滤器的应用。接着,针对缓存击穿与雪崩问题,提出过期时间随机化和高可用架构设计的解决方案。特别强调热点Key重建优化,避免并发高峰时的性能问题。另外,详细阐述了缓存与数据库双写一致性问题及解决策略。最后,提供了Redis键值设计和性能优化的实用建议,如合理的key名设计、避免bigkey、选择合适的数据类型,以及客户端连接池使用优化。这些内容对于提升Redis应用性能、保障系统稳定性具有重要意义。
资源推荐
资源详情
资源评论
多级缓存架构
缓存设计
缓存穿透
缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,通常出于容错的考虑,如果从存储
层查不到数据则不写入缓存层。
缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端存储的意义。
造成缓存穿透的基本原因有两个:
第一,自身业务代码或者数据出现问题。
第二,一些恶意攻击、爬虫等造成大量空命中。
缓存穿透问题解决方案:
1、缓存空对象
1 Stringget(Stringkey){
2 //从缓存中获取数据
3 StringcacheValue=cache.get(key);
4 //缓存为空
5 if(StringUtils.isBlank(cacheValue)){
6 //从存储中获取
7 StringstorageValue=storage.get(key);
8 cache.set(key,storageValue);
9 //如果存储数据为空,需要设置一个过期时间(300秒)
10 if(storageValue==null){
11 cache.expire(key,60*5);
12 }
13 returnstorageValue;
14 }else{
15 //缓存非空
16 returncacheValue;
17 }
18 }
2、布隆过滤器
对于恶意攻击,向服务器请求大量不存在的数据造成的缓存穿透,还可以用布隆过滤器先做一次过滤,对于不
存在的数据布隆过滤器一般都能够过滤掉,不让请求再往后端发送。当布隆过滤器说某个值存在时,这个值可
能不存在;当它说不存在时,那就肯定不存在。
布隆过滤器就是一个大型的位数组和几个不一样的无偏hash函数。所谓无偏就是能够把元素的hash值算得
比较均匀。
向布隆过滤器中添加key时,会使用多个hash函数对key进行hash算得一个整数索引值然后对位数组长度
进行取模运算得到一个位置,每个hash函数都会算得一个不同的位置。再把位数组的这几个位置都置为1就
完成了add操作。
向布隆过滤器询问key是否存在时,跟add一样,也会把hash的几个位置都算出来,看看位数组中这几个位
置是否都为1,只要有一个位为0,那么说明布隆过滤器中这个key不存在。如果都是1,这并不能说明这个
key就一定存在,只是极有可能存在,因为这些位被置为1可能是因为其它的key存在所致。如果这个位数组
比较稀疏,这个概率就会很大,如果这个位数组比较拥挤,这个概率就会降低。
这种方法适用于数据命中不高、数据相对固定、实时性低(通常是数据集较大)的应用场景,代码维护较为
复杂,但是缓存空间占用很少。
可以用redisson实现布隆过滤器,引入依赖:
1 <dependency>
2 <groupId>org.redisson</groupId>
3 <artifactId>redisson</artifactId>
4 <version>3.6.5</version>
5 </dependency>
示例伪代码:
1 packagecom.redisson;
2
3 importorg.redisson.Redisson;
4 importorg.redisson.api.RBloomFilter;
5 importorg.redisson.api.RedissonClient;
6 importorg.redisson.config.Config;
7
8 publicclassRedissonBloomFilter{
9
10 publicstaticvoidmain(String[]args){
11 Configconfig=newConfig();
12 config.useSingleServer().setAddress("redis://localhost:6379");
13 //构造Redisson
14 RedissonClientredisson=Redisson.create(config);
15
16 RBloomFilter<String>bloomFilter=redisson.getBloomFilter("nameList");
17 //初始化布隆过滤器:预计元素为100000000L,误差率为3%,根据这两个参数会计算出底层的bit数组大小
18 bloomFilter.tryInit(100000000L,0.03);
19 //将zhuge插入到布隆过滤器中
20 bloomFilter.add("zhuge");
21
22 //判断下面号码是否在布隆过滤器中
23 System.out.println(bloomFilter.contains("guojia"));//false
24 System.out.println(bloomFilter.contains("baiqi"));//false
25 System.out.println(bloomFilter.contains("zhuge"));//true
26 }
27 }
使用布隆过滤器需要把所有数据提前放入布隆过滤器,并且在增加数据时也要往布隆过滤器里放,布隆过滤器
缓存过滤伪代码:
1 //初始化布隆过滤器
2 RBloomFilter<String>bloomFilter=redisson.getBloomFilter("nameList");
3 //初始化布隆过滤器:预计元素为100000000L,误差率为3%
4 bloomFilter.tryInit(100000000L,0.03);
5
6 //把所有数据存入布隆过滤器
7 voidinit(){
8 for(Stringkey:keys){
9 bloomFilter.put(key);
10 }
11 }
12
13 Stringget(Stringkey){
14 //从布隆过滤器这一级缓存判断下key是否存在
15 Booleanexist=bloomFilter.contains(key);
16 if(!exist){
17 return"";
18 }
19 //从缓存中获取数据
20 StringcacheValue=cache.get(key);
21 //缓存为空
剩余12页未读,继续阅读
资源评论
- shiweixia2023-12-16学习了,资源不错 #完美解决问题 #运行顺畅
光芒软件工匠
- 粉丝: 789
- 资源: 64
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功