整合redis步骤
- 1)、引入data-redis-start
- 2)、简单配置redis的host信息
- 3)、使用springboot自动配置好的StringRedisTemplaes来操作redis
redis->map 存放key,数据值value
一、整合redis
pom.xml引入redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
二、application添加redis配置
spring:
redis:
host: 127.0.0.1
port: 6379
三、测试
@Autowired
StringRedisTemplate stringRedisTemplate;
@Test
public void testStringRedisTemplate(){
ValueOperations<String, String> ops= stringRedisTemplate.opsForValue();
// 保存
ops.set("hello","value_"+ UUID.randomUUID().toString());
// 查询
String hello = ops.get("hello");
System.out.println("之前保存的数据是:"+hello);
}
-
1)、springboot2.0以后默认使用lettuce作为操作redis的客户端,它使用netty进行网络通信。
-
2)、lettuce的bug导致netty堆外溢出 -Xmx300m;netty如果没有指定堆外内存,默认使用-Xmx300m
-
解决方案:不能使用-Dio.netty.maxDirectMemory只去调大堆外内存
1、升级lettuce客户端
2、切换使用jedis
redisTemplate:
lettuce,jedis操作redis底层客户端。spring再次封装redisTemplace;
缓存穿透
缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中,将去查询数据库,但是数
据库也无此记录,我们没有将这次查询的 null 写入缓存,这将导致这个不存在的数据每次
请求都要到存储层去查询,失去了缓存的意义。
在流量大时,可能 DB 就挂掉了,要是有人利用不存在的 key 频繁攻击我们的应用,这就是
漏洞。
解决:
缓存空结果、并且设置短的过期时间。
缓存击穿
对于一些设置了过期时间的 key,如果这些 key 可能会在某些时间点被超高并发地访问,
是一种非常“热点”的数据。
这个时候,需要考虑一个问题:如果这个 key 在大量请求同时进来前正好失效,那么所
有对这个 key 的数据查询都落到 db,我们称为缓存击穿。
解决:
加锁
缓存雪崩
缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失
效,请求全部转发到 DB,DB 瞬时压力过重雪崩。
解决:
原有的失效时间基础上增加一个随机值,比如 1-5 分钟随机,这样每一个缓存的过期时间的
重复率就会降低,就很难引发集体失效的事件。
Redisson 完成分布式锁
Redisson 是架设在 Redis 基础上的一个 Java 驻内存数据网格(In-Memory Data Grid)。充分
的利用了 Redis 键值数据库提供的一系列优势,基于 Java 实用工具包中常用接口,为使用者
提供了一系列具有分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的工
具包获得了协调分布式多机多线程并发系统的能力,大大降低了设计和研发大规模分布式
系统的难度。同时结合各富特色的分布式服务,更进一步简化了分布式环境中程序相互之间
的协作。
官方文档:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95
缓存数据一致性
保证一致性模式
1、双写模式
2、失效模式
3、改进方法 1-分布式读写锁
- 缓存的所有数据都有过期时间,数据过期下一次查询触发主动更新
- 读写数据的时候,加上分布式的读写锁
4、改进方法 2-使用 cananl
四、spring-cache的不足
* 1)读模式
* 缓存穿透:查询一个null数据。解决:缓存空数据:spring.cache.redis.cache-null-values=true
* 缓存击穿:大量并发进来同时查询一个正好过期的数据。解决:加锁 默认无加锁 sync = true加锁
* 缓存雪崩:大量key同时过期。解决:加随机时间。加上过期时间:spring.cache.redis.time-to-live=3600000
* 2)写模式:(缓存与数据库一致)
* 1)读写加锁
* 2)引入canal,感知mysql的更新去更新数据库
* 3)读多写多,直接去数据库查询就行
* 总结:常规数据,(读多写少,即时性,一致性要求不高的数据):完全可以使用Spring-Cache;写模式,只要缓存的的数据有过期时间就行
* 特殊数据:特殊设计
* 原理:
* CacheManager(RedisCacheManager)->Cache(RedisCache)->Cache负责缓存的读写
网友评论