redis注意点记录

1、stringRedisTemplate  它的key和Value的序列化方式默认就是String类型

2、stringRedisTemplate  操作Hash时:

  2.1 添加数据 ,在实体转换为HashMap需要将对象字段的值转为String( 使用StringRedisTemplateredis需要转换成的map的各个字段都是String类型),eg:
Map<String, Object> userMap = BeanUtil.beanToMap(userDTO,new HashMap<>(),
        CopyOptions.create()
                .setIgnoreNullValue(true)
                .setFieldValueEditor((fieldName,fieldValue)->fieldValue.toString()));
stringRedisTemplate.opsForHash().putAll(LOGIN_USER_KEY + token,userMap);
  
    2.1.1 Hutool工具包的BeanUtil的beanToMap方法------空指针的问题  https://i.cnblogs.com/posts/edit;postId=17077647  修改为:
Map<String, Object> map = BeanUtil.beanToMap(dbShop,new HashMap<>(),
        CopyOptions.create()
                .setIgnoreNullValue(true)
                .setFieldValueEditor((fieldName,fieldValue) -> {
                            if (fieldValue == null){
                                fieldValue = "0";
                            }else {
                                fieldValue = fieldValue.toString();
                            }
                            return fieldValue;
                        }));
stringRedisTemplate.opsForHash().putAll(CACHE_SHOP_KEY + id, map);
  2.2 获取数据,
    2.2.1使用entries获取hashMap 的所有键值对  
Object shopMap = stringRedisTemplate.opsForHash().entries(CACHE_SHOP_KEY + id);
    2.2.2使用get获取hashMap 的一个key  的键值对
Object str = stringRedisTemplate.opsForHash().get(CACHE_SHOP_KEY + id, "name");

3、stringRedisTemplate  操作string对应的实体对象时,需要转换成json,序列化与反序列化

//从redis查商铺信息缓存,存在缓存则直接返回,不存在则查数据库并写回到redis中
String redisShopJson = stringRedisTemplate.opsForValue().get(CACHE_SHOP_KEY + id);
//存在缓存
if (StrUtil.isNotBlank(redisShopJson)){
    //字符串反序列化为实体对象
    Shop shop = JSONUtil.toBean(redisShopJson, Shop.class);
    return Result.ok(shop);
}
//存在缓存,查数据库
Shop dbShop = getById(id);
if(dbShop == null){
    return Result.fail("商铺不存在!");
}
stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id, JSONUtil.toJsonStr(dbShop));
return Result.ok(dbShop);

4、stringRedisTemplate  操作List的实体时,需要转换成json再存入redis   https://blog.csdn.net/weixin_43658899/article/details/121040307

  4.1 存入List类型到redis    --  opsForList().range(key, start, end)   特殊用法:通过stringRedisTemplate.opsForList().range(key, 0, -1)可以查询索引第一个到索引倒数第一个(即所有数据)

https://blog.csdn.net/qq_52793248/article/details/128106178

List<String> shopTypeStr = stringRedisTemplate.opsForList().range(CACHE_TYPES_KEY, 0, -1);
if (CollectionUtil.isNotEmpty(shopTypeStr)){
    List<ShopType> shopTypeList = new ArrayList<>();
    for (int i = 0; i < shopTypeStr.size(); i++) {
        ShopType shopType = JSONUtil.toBean(shopTypeStr.get(i), ShopType.class);
        shopTypeList.add(shopType);
    }
    return Result.ok(shopTypeList);
}
4.2 redis中取出List类型  --  opsForList().rightPushAll   从右侧批量插入
List<ShopType> shopTypeList = query().orderByAsc("sort").list();
if (CollectionUtil.isNotEmpty(shopTypeList)){
    List<String> shopTypeJson = new ArrayList<>();
    for (int i = 0; i < shopTypeList.size(); i++) {
        shopTypeJson.add(JSONUtil.toJsonStr(shopTypeList.get(i)));
    }
    //回写到redis
    stringRedisTemplate.opsForList().rightPushAll(CACHE_TYPES_KEY, shopTypeJson);
    return Result.ok(shopTypeList);
}

5、缓存更新策略

 

 

 

缓存与数据库的不论谁先后都有概率出现问题,由于操作redis的速度比操作数据库的要快,故在更新数据时选择先操作数据库,再删除缓存!

总结:

6、缓存穿透

//不存在缓存,查数据库
Shop dbShop = getById(id);
if(dbShop == null){
    stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id, "",CACHE_NULL_TTL, TimeUnit.MINUTES);
    return Result.fail("商铺不存在!");
}

7、缓存雪崩

8、缓存击穿

 

 

逻辑过期:不给热点key设置TTl,而且在value中增加字段记录有效期时间,在代码中进行判断,如果过期,则开启新线程重建缓存,在重建完成之前,都返回旧的数据。

posted @   dream_of_freedom  阅读(117)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示