1.为了提升系统性能,我们一般都会将部分数据放入缓存中,加速访问。而db承担数据落盘工作。
哪些数据适合放入缓存?
1.即时性,数据一致性要求不高的
2.访问量大且更新频率不高的数据(读多,写少)
注意:要设定缓存时间
最简单的缓存Map 本地缓存
分布式下有问题,数据不同步
分布式共同使用缓存中间件 例如redis
高可用,高性能
整合redis:
1)引入data-redis-starter
2) 简单配置redis的host等信息
3)使用springboot自动配置好的StringRedisTemplate
压测时产生OutOfDirectMemoryError 堆外内存溢出
springboot2.0 以后默认使用lettuce作为操作redis 的客户端,它使用netty进行网络通信
2.lettuce的bug导致netty堆外内存溢出
netty如果没有指定堆外内存就会使用-xmx300m,没有及时释放内存
--可以通过-Dio.netty.maxDirectMemory进行使用
3.解决方案:
1)升级lettuce
2)切换使用jedis 采用
//只要是同一把锁,就能锁住需要这个锁的素所有线程
synchronized(this) 进程锁
分布式应该使用分布式锁
分布式锁演进
删除锁也得是原子操作
使用脚本删锁
Redisson 是一个在Redis的基础上实现的java驻内存数据网格
整合redisson作为分布式锁的依赖
<!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.0</version>
</dependency>
1.可重入锁。
2.公平锁
3.读写锁
4.信号量 (占坑操作)(Semaphore)
分布式限流操作
5.闭锁 (CountDownLatch)
放假锁门,所有班走完了,才可锁门
使用canal更新缓存,解决数据异构
Spring Cache 通过注解来实现缓存
整合springcache
1.配置redis缓存类型
spring.cache.type = redis
2.开启缓存功能
@EnableCaching
3.只需要注解就能完成缓存
@Cacheable 代表当前方法的结果需要缓存,如果缓存终于,方法不用调用,没有调用,并存入缓存
4.默认行为
1)如果缓存中有,方法不会调用
2)key默认自动生成,缓存的名字::SimpleKey[] (自动生成的Key)
3)缓存的value的值,默认使用jdk序列化机制,将序列化后的数据存到redis
4)默认时间TTl:-1 永远存在
自定义:
1)指定生成的缓存使用的key
@Cacheable(value=("category") , key = "'category'")
以方法名做key
key = "#root.method.name"
2)指定缓存数据存活的时间
配置文件中修改,毫秒为单位
spring.cache.redis.time-to-live=360000 //1个小时
3)保存的数据以json格式
原理:CancheAutoConfiguration-> RedisCacheConfiguration
->自动配置了RedisCacheManager->初始化所有的缓存->每个缓存决定使用什么配置
->如果RedisCacheConfiguration有就用这个,没有就用默认
->配置redisCacheConfiguration
spring.cache.redis.key-prefix=CACHE_
spring.cache.redis.use-key-prefix = true
#是否缓存空值,防止缓存穿透
spring.cache.redis.cache-null-value = true
4.spring-cache的不足:
1》读模式:
缓存穿透:查询一个null数据,可以缓存null数据,解决cache-null-value = true
缓存击穿:大量并发进来同时查询一个正好过期的数据。解决:加锁? sync = true (加锁,解决击穿,本地锁)
缓存雪崩: 大量的key同时过期。 解决 :加随机时间 加上过期时间
2》写模式:(缓存与数据库一致)
1)读写加锁
2)引入Canal
3)读多写多,直接去数据库查询就行
总结:
常规数据(读多写少,即时性,一致性要求不高的数据)完全可以用springCache
特殊数据:特殊设计
原理
CacheManager(RedisCacheManager)->Cache(RedisCache)->Cache负责缓存读写
网友评论