缓存的优化策略
对放入redis中key进行优化:key的长度不能太长
1092679493:-364050362:com.wd.dao.UserDao.findAll:0:2147483647:select t_user.id, t_user.name, t_user.age,t_user.bir from t_user:SqlSessionFactoryBean
尽可能将key设计的简短一些
引入算法: MD5处理加密
MD5算法特点:
- 1、一切文件字符串等经过md5处理之后 都会生成32位16进制字符串
- 2、不同内容的文件经过md5进行加密,加密结果一定不一致
- 3、相同内容的文件多次经过md5生成结果始终一致
推荐:在redis整合Mybatis过程中建议将key 进行md5的优化处理
涉及到缓存雪崩的问题:
1、缓存永久存储 (不推荐)
2、针对不同的业务数据一定设置不同的超时时间
优化后的代码
import com.wd.util.ApplicationContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.DigestUtils;
/**
* 自定义Redis缓存实现
*/
@Slf4j
public class RedisCache implements Cache {
// 当前放入缓存的mapper的namespace
private final String id;
// 必须存在构造方法 对id进行赋值
public RedisCache(String id) {
log.info("id: " + id);
this.id = id;
}
// 返回Cache的唯一标识
@Override
public String getId() {
return this.id;
}
/**
* 缓存中放入值
*/
@Override
public void putObject(Object key, Object value) {
log.info("putObject: key: " + key.toString());
log.info("putObject: value: " + value);
// 使用Redis中的Hash类型作为缓存存储模型 key(namespace) hashkey(key)-value(value)
// getRedisTemplate().opsForHash().put(id, key.toString(), value);
getRedisTemplate().opsForHash().put(id, getKeyToMD5(key.toString()), value);
// 缓存超时
if(id.equals("com.wd.dao.UserDao")){
getRedisTemplate().expire(id, 1, TimeUnit.HOURS);
}
if(id.equals("com.wd.dao.CityDao")){
getRedisTemplate().expire(id, 30, TimeUnit.MINUTES);
}
// .... 指定不同的模块设置不同的缓存超时时间
}
/**
* 缓存中获取值
*/
@Override
public Object getObject(Object key) {
log.info("getObject: key: " + key.toString());
// 根据key 从redis的hash类型中获取数据
// return getRedisTemplate().opsForHash().get(id, key.toString());
return getRedisTemplate().opsForHash().get(id, getKeyToMD5(key.toString()));
}
/**
* 根据指定的key删除缓存
* 注意: 这个方法为Mybatis的保留方法, 默认没有实现 后续版本可能会实现
*/
@Override
public Object removeObject(Object key) {
log.info("removeObject: key: " + key);
return null;
}
/**
* 清空缓存
*/
@Override
public void clear() {
log.info("clear");
// 清空 namespace 的缓存
getRedisTemplate().delete(id);
}
/**
* 用来计算缓存的数量
*/
@Override
public int getSize() {
// 获取hash中 key value的数量
return getRedisTemplate().opsForHash().size(id).intValue();
}
// 封装redisTemplate
private RedisTemplate getRedisTemplate(){
// 通过application工具类获取redisTemplate
RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBeanByName("redisTemplate");
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
// 封装一个对key进行md5处理的方法
private String getKeyToMD5(String key){
return DigestUtils.md5DigestAsHex(key.getBytes());
}
}