项目中使用redis更新每日数据,并且在当日写缓存时不会污染昨日缓存

之前项目有一个需求:开发首页的各类分析数据,一共有五个图表需要进行分析,因为首页是最频繁访问的,每个接口都要求响应速度很快,所以一定要写到缓存中,然后在每天走定时任务的时候更新当天的新数据

首页数据是这样展示的:有两个下拉单选框作为筛选项,部门和导购

因为部门下有n个导购,单选导购可以筛选出这个导购下的分析图表,单选部门可以筛选部门下所有导购的图表

所以设计上每个图表的接口都会存在一个hash结构下,并拼上日期,以其中一个图表为例data_portrait_member_id_2021-12-01

同时需要再写一个缓存,记录当天的日期data_date_time

在这里插入图片描述
hash里面存的key就是对应的导购id,value是里面算出来的图表,多个key就能组成部门的图表了
在这里插入图片描述
写入的代码实现

redisUtils.hmSet(Constant.DATA_PORTRAIT_MEMBER_ID + sf.format(c.getTime())
,wechatQuery.getWorkerId().toString()
,JSON.toJSONString(portraitVO));

所有的缓存单独存一个key,这里部门就不用拿出来遍历去算

if (isAll){
            redisUtils.hmSet(Constant.DATA_PORTRAIT_MEMBER_ID + sf.format(c.getTime())
                    ,"all"
                    ,JSON.toJSONString(portraitVO));
}

取缓存

Object result = redisUtils.hmGet(Constant.DATA_PORTRAIT_MEMBER_ID + sf.format(c.getTime())
                    ,"all");
if (result!=null){
     return JSONObject.toJavaObject(
               JSONObject.parseObject(result.toString()),PortraitVO.class);
}

部门取缓存用到hmGetList取出list遍历算部门

List<Object> portraitVOList = redisUtils.hmGetList(Constant.DATA_PORTRAIT_MEMBER_ID + sf.format(c.getTime()),memberIds);
if (portraitVOList.size()>0){
    for (Object o:portraitVOList) {
    	if (o!=null){
                    PortraitVO portraitVO = JSONObject.toJavaObject(
                            JSONObject.parseObject(o.toString()),PortraitVO.class);
//-----------------其他代码实现
		}
	}
}

封装了下multiGet

 public List<Object> hmGetList(String key, List<String> hashKey) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        Collection collection = hashKey;
        return hash.multiGet(key, collection);
    }

最后再说一下data_date_time缓存的作用
每次进方法的时候调用一下

Calendar c = getDataNowOrYesterday();

目的是为了今天凌晨的时候跑定时任务,先访问缓存,先看昨天的key是否还存在,存在则返回false,然后Calendar调用昨天的缓存

public Calendar getDataNowOrYesterday(){
        Calendar c = Calendar.getInstance();
        if (!isDataNow()){
            c.add(Calendar.DAY_OF_YEAR, -1);
        }
        return c;
}

public boolean isDataNow() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_YEAR, -1);
        //今天访问缓存,先看昨天的key是否还存在,存在则返回false
        if (redisUtils.get(Constant.DATA_DATE_TIME) != null
                && redisUtils.get(Constant.DATA_DATE_TIME).equals(sf.format(c.getTime()))) {
            return false;
        } else {
            return true;
        }
}

这样就确保了即使用户凌晨在跑定时任务的时候访问系统,只会访问到昨天的图表,而在今天的缓存写入之后,更新data_date_time,读到今天的新图表,确保了隔离
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值