maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置
redis:
host: 192.168.16.223
# password:
# port:
使用
redistemplate
springredistemplate
问题记录
产生堆外内存溢出
原因
lettuce 操作netty产生堆外溢出
解决
- 升级lettuce
- 使用jedis
<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>
缓存穿透
缓存穿透指的是查询一个不存在的数据,由于缓存没有命中就会查库,库中也没有,我们没有将null写入数据库 则每次都往复,失去缓存意义。 导致的问题是 数据库压力过大 。
解决办法是将null存入缓存,并加入短暂过期时间。
缓存雪崩
缓存雪崩指的是我们设置缓存时key使用相同的过期时间,导致某一时刻同时失效,数据库压力过大雪崩。
解决办法时在原有失效时间的基础上加一个随机值。
缓存击穿
缓存击穿是指某些过期时间的key在某个时间点高并发访问。
解决办法是 加锁,大并发只能让一个人查 其他人等待。
缓存击穿解决方法
- 本地锁(单机可以用)
synchronized - 分布式锁(分布式必须用)
redisson
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.0</version>
</dependency>
package com.jhj.gulimall.product.config;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
/**
* @Description MyRedissonConfig
* @Author jhj
* @Date 2022/6/3014:38
**/
@Configuration
public class MyRedissonConfig {
@Bean(destroyMethod = "shutdown")
public RedissonClient redisson() throws IOException{
Config config = new Config();
//单节点
config.useSingleServer().setAddress("redis://192.168.16.223:6379");
return Redisson.create();
}
}
使用
@Resource
RedissonClient redissonClient;
读写锁 保证读到最新数据
并发读 等于无锁
有写则必须等待
闭锁 等待线程都执行结束了 才能执行
信号 可以添加以及释放线程数 也可以用作限流
缓存与数据库一致性
- 双写模式
加锁
允许有延迟 - 失效模式
加锁
允许有延迟
最终方案是 改的频繁的不要用缓存 或者canal
作者声明
如有问题,欢迎指正!