Redis读写Map数据

391 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情

场景说明

将业务系统的商品数据,根据业务系统标识作为Key . 将业务系统下的商品的序列号作为哈希key, 值为商品记录 缓存起来。前端查询的时候,使用序列号读取对应的商品记录。

Redis数据缓存效果展示

image.png

数据库展示

image.png

代码演示

@Override
public List<PromotionGoods> listCacheable(List<String> ids) {
    long st = System.currentTimeMillis();
    String redisKey = "PROMOTION:GOODSSERIAL:";
    HashOperations ops = redisTemplate.opsForHash();

    long size = ops.size(redisKey + "SLD10001");
    if (size == 0L) {
        log.debug("==null, 查询DB");
        List<PromotionGoods> list = list();
        Map<String, List<PromotionGoods>> channelMap = StreamEx.of(list).collect(Collectors.groupingBy(PromotionGoods::getChannel));
        for (Map.Entry<String, List<PromotionGoods>> entry : channelMap.entrySet()) {
            //Map<String, List<PromotionGoods>> serialMap = StreamEx.of(entry.getValue()).collect(Collectors.groupingBy(PromotionGoods::getGoodsSerial));
            Map<String, PromotionGoods> serialMap = new HashMap<>(16);
            for (PromotionGoods goods : entry.getValue()) {
                serialMap.put(goods.getGoodsSerial(), goods);
            }
            ops.putAll(redisKey + entry.getKey(), serialMap);
            log.debug("设置缓存 ,key={}", redisKey + entry.getKey());
        }

    }
    List<PromotionGoods> goodsList = ops.multiGet(redisKey + "SLD10001", ids);
    return goodsList;
}

代码演示

redis从缓存读取多个商品的核心API接口:ops.multiGet(redisKey + "SLD10001", ids)

缺陷分析

读取出来的是一个List数据结果。需要使用代码额外做数据结果转换成map, 在数据量少的情况下,性能跟数据库查询相差不大。测试环境下,1700条数据,查询耗时大概在176毫秒。唯一有点,数据库查询在资源精确的时候,会有175毫秒到1700毫秒之间的数据查询演示波动。尤其是在微服务里面seata事务处理。

总结

数据量少的情况下,做表的关联映射效果不明显,还出现一个数据更新的时效性问题,在应用上优势不突出;数据量上升到10W级别,会有比较不错的性能对别。