关于使用redis作为缓存几点疑问

cly_0 2017-07-25 04:10:40
由于当前业务有一个报表功能,由于数据量庞大,导致查询结果很慢,所以现在想考虑用redis作为缓存。
原来一直没用过缓存,所以现在是第一次用,有几点疑问没搞明白;
1,报表的数据都是联表后的复杂sql语句查询结果,直接将结果存于redis后,那么怎么保证缓存数据与数据库中的数据一致性,看见很多的说在更新表数据的时候更新缓存,但这种应该只限于单表查询的吧,联表查询,更新了其中一个表的数据如何更新缓存?
2,缓存都有过期时间,也就是没有缓存的时候都需要查询数据库,如果缓存过期时间为一天,那么每天第一次击查询的时候都特别慢,这种问题该怎么解决,总不可能让自己每天爬起来去点击查询一次吧?
求大神解答。
...全文
309 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
潇湘如梦 2017-07-25
  • 打赏
  • 举报
回复
引用 4 楼 cly_0 的回复:
[quote=引用 3楼潇湘如梦 的回复:]使用缓存的目的是为了高速访问高频读低频写的数据。如果每一次sql查询的语句都是固定的或者只有很少的几个查询语句的结果需要放在缓存中,且这些数据修改频率很低,比如可能一天修改一次,且用户访问量很大,那么这种情况是可以使用redis的。但lz应该知道,redis本身也是数据库,但如果几分钟甚至几秒钟就要修改一次,且每次修改的数据量很大,那么redis的压力也会很大,查询速度不见得能达到项目要求。不知道lz用的是java的什么框架,在spring中实际上有自身的缓存机制(可参考@Cacheable注解),是将内存中的一片区域用于缓存数据,对于修改频率较高且查询较慢的数据可以考虑这种方式。但无论怎样做,都免不了要对sql本身进行优化。 针对lz所说的情况,我觉得你设置一个定时任务,具体如下: 时间间隔设置为1小时(可根据项目实际要求的修改生效时间进行调整),依次执行sql查询和修改缓存数据,在修改缓存数据的时候需要刷新redis失效时间为一天。 这样可以保证redis中的数据始终有效,且具有较高的时效性。
其实我这的修改频率也不高,一天最多一两次。 我主要不明白的是这样的情况下,该用什么方法去更新缓存。或许这样是更新不了的吧。关于第二点用定时器,确实是个解决的方法。[/quote] 我在项目中是这样写的:
 BoundValueOperations<String, String> ops = stringRedisTemplate.boundValueOps(KEY);
        ops.set(VALUE, 过期时间, TimeUnit.SECONDS);
但这是用于新增,我没有尝试过修改,你可以试试看。如果这还不行的话那就先删除在用上面的方法新增,删除的实现如下:
public void delete(String key) {
        RedisSerializer<String> keySerializer = (RedisSerializer<String>) stringRedisTemplate.getKeySerializer();
        stringRedisTemplate.execute(new RedisCallback<Boolean>() {
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.del(keySerializer.serialize(key)) > 0;
            }
        });
    }
cly_0 2017-07-25
  • 打赏
  • 举报
回复
引用 2楼一个治疗术 的回复:
关于缓存时间过期问题,可以用定时任务来重新缓存数据
嗯 是个方法
cly_0 2017-07-25
  • 打赏
  • 举报
回复
引用 3楼潇湘如梦 的回复:
使用缓存的目的是为了高速访问高频读低频写的数据。如果每一次sql查询的语句都是固定的或者只有很少的几个查询语句的结果需要放在缓存中,且这些数据修改频率很低,比如可能一天修改一次,且用户访问量很大,那么这种情况是可以使用redis的。但lz应该知道,redis本身也是数据库,但如果几分钟甚至几秒钟就要修改一次,且每次修改的数据量很大,那么redis的压力也会很大,查询速度不见得能达到项目要求。不知道lz用的是java的什么框架,在spring中实际上有自身的缓存机制(可参考@Cacheable注解),是将内存中的一片区域用于缓存数据,对于修改频率较高且查询较慢的数据可以考虑这种方式。但无论怎样做,都免不了要对sql本身进行优化。 针对lz所说的情况,我觉得你设置一个定时任务,具体如下: 时间间隔设置为1小时(可根据项目实际要求的修改生效时间进行调整),依次执行sql查询和修改缓存数据,在修改缓存数据的时候需要刷新redis失效时间为一天。 这样可以保证redis中的数据始终有效,且具有较高的时效性。
其实我这的修改频率也不高,一天最多一两次。 我主要不明白的是这样的情况下,该用什么方法去更新缓存。或许这样是更新不了的吧。关于第二点用定时器,确实是个解决的方法。
潇湘如梦 2017-07-25
  • 打赏
  • 举报
回复
使用缓存的目的是为了高速访问高频读低频写的数据。如果每一次sql查询的语句都是固定的或者只有很少的几个查询语句的结果需要放在缓存中,且这些数据修改频率很低,比如可能一天修改一次,且用户访问量很大,那么这种情况是可以使用redis的。但lz应该知道,redis本身也是数据库,但如果几分钟甚至几秒钟就要修改一次,且每次修改的数据量很大,那么redis的压力也会很大,查询速度不见得能达到项目要求。不知道lz用的是java的什么框架,在spring中实际上有自身的缓存机制(可参考@Cacheable注解),是将内存中的一片区域用于缓存数据,对于修改频率较高且查询较慢的数据可以考虑这种方式。但无论怎样做,都免不了要对sql本身进行优化。 针对lz所说的情况,我觉得你设置一个定时任务,具体如下: 时间间隔设置为1小时(可根据项目实际要求的修改生效时间进行调整),依次执行sql查询和修改缓存数据,在修改缓存数据的时候需要刷新redis失效时间为一天。 这样可以保证redis中的数据始终有效,且具有较高的时效性。
一个治疗术 2017-07-25
  • 打赏
  • 举报
回复
关于缓存时间过期问题,可以用定时任务来重新缓存数据
minemine0418 2017-07-25
  • 打赏
  • 举报
回复
个人意见 1、放在缓存中的应当是不会经常性改变的数据,如果是经常性改变,那么建议还是不要用缓存,你做的报表功能,好比查询过去一年的业务量,这个是不会改变的数据 2、缓存当然有过期的时间,针对你的第二点,如过期需要重新查询数据库,这个应该是避免不了的,至少只需要加载一次,加载完成之后的读取性能还是比较可以的

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧