项目是做一个问题社区,前端进行分页展示。这些问题数据以问题ID(自动递增)为score,存放到redis的ZSet中。前端发送请求的规则为xxx?page=x&size=y,其中page为要访问的页码,size为每页展示多少条数据。问题来了,假设现在redis中没有任何数据,那么前端发送请求xxx?page=2&size=5,这样就跳过了第一页的访问,直接访问了第二页的数据,并且将第二页的数据放到了redis的ZSet中。那么现在又有人访问第一页,但是由于代码我写的代码的问题,程序会将这第二页的数据当成第一页的数据来展示,然后如果再访问第二页时,缓存中是有第二页的数据,但是却因为代码问题需要去查数据库。这个bug我一直没想出来有什么比较好的办法解决。下面是我的部分代码。
findQuestion(int page,int size){
        redisUtil.zrevrange("key",(page-1)×size,page×size);
        ........
}

解决方案 »

  1.   

    如果表是热点表,为什么不一开始就表加载到redis中?
      

  2.   

    如果xxx?page=2&size=5这个数据集中,其中某几条被修改了,会同步redis.
      

  3.   

     如果xxx?page=2&size=5这个数据集中,其中某几条被修改了,会同步redis吗?.
      

  4.   

    会同步到redis,并且新插入的数据也能正常分页,就是在跨页访问会出现BUG。
    目前我是通过再添加一个hash来记录每一页数据的第一条数据ID和最后一条数据ID,然后在访问时,先取出当页的第一条数据ID和最后一条数据ID,然后通过zrevrangeByScore来获取数据。这种方式对于固定的size请求可能会正常响应,如果不是固定的size请求,可能会出BUG。我目前想不到更好的方法,先用这种方法代替吧。
      

  5.   

    好把,只是比较不理解,为什么要这么做, 用这种方式来搞就像你说的那样,应用场景又固定,操作起来也频繁,一些同步更新的操作又要做一些事务等等处理,感觉有必要做的这么复杂吗. 直接用 mysql、oracle类型的数据库查不行么.
      

  6.   

    好把,只是比较不理解,为什么要这么做, 用这种方式来搞就像你说的那样,应用场景又固定,操作起来也频繁,一些同步更新的操作又要做一些事务等等处理,感觉有必要做的这么复杂吗. 直接用 mysql、oracle类型的数据库查不行么.
      

  7.   

    这个场景有必要使用redis么?如果是无状态服务,直接为每个不同参数组合的结果做缓存,并缓存几秒可以足够减轻数据库压力,甚至不需要用redis,毕竟数据变化比较大,你修改一个数据同步到缓存可以比较简单实现,但假如修改的列刚好是查询条件,那就是个问题了
    比如你查询列A = 1的数据,但修改A=2,你只能同步缓存的A的值为A,但实际的查询结果不应该包括A=2这条记录了
      

  8.   

    看起来没必要,但是挡不住有领导想用啊,
    缓存列表查询就按我说的那种,缓存个几秒,并发高还是有用,但不能太久,毕竟会数据不一致,就看容忍度了
    如果要长期的话,一条一条去缓存,主键为key,结果集不会因为其他记录修改而改变