当前位置:   article > 正文

redis队列list时效性过期解决方案_redis list 过期

redis list 过期

redis的list可以用作队列,效率高,好用,但是有个缺点就是队列的时效性只能统一设置,一个list一个,要过期只能批量过期,不能达到只过旧的数据,新数据保留的情况。

网上解决方法是换成sring,每个单个项目单独设置ttl,不用list ,批量用keys + * 正则表表达式过滤,可以批量pos数据出来达到队列效果,但是redis官网上描述有keys只能用作debug模式,性能上会产生比较大的影响。

另一种解决方案就是采用多个list,分时间片段做队列,取队列优先按照到期时间近的队列取,队列分别过期方式,大概实现方法如下


规则:

(1) 设置两个list --> parta , partb

(2) 时限分为 2个区域 【总ttl】 = 【可写入】 + 【不可写入等待期】

比如: ttl = 48小时 , 写入list队列规则为 0~24 小时可写, 24~48 小时队列不再写入,等到ttl到期销毁 , ttl=24+24

(3)两个 parta , partb 分别轮流时间写入

创建parta--->写入parta队列--->parta到了等待期 ---> 创建partb 写入 ---->写入partb队列--->partb到了等待期---->创建parta写入(此时前一个parta应该已经销毁)


代码:

  1. long expire_a = redisUtil.getExpire(parta_list);
  2. long expire_b = redisUtil.getExpire(partb_list);
  3. //(24小时等待过期)
  4. long expire_out = 24;
  5. //两个分区时间间隔大小
  6. long expire = 24 * 2;
  7. if (expire_a > expire_out && expire_a>=expire_b-100) {
  8. //队列a还有剩余时间 ,且 a >= b (100秒作为误差)
  9. redisUtil.ListSet("parta", ob);//不设置ttl
  10. } else if (expire_b > expire_out && expire_a<=expire_b) {
  11. //队列b还有剩余时间 ,且 b >= a
  12. redisUtil.ListSet("partb", ob);//不设置ttl
  13. } else if ((expire_a < 0 && expire_b < 0) || (expire_a < 0 && expire_b <= expire_out))
  14. {
  15. //队列a ,b 不存在,新建队列a
  16. //队列a(a可能-1,-2)没有剩余时间且<0, 队列b没有剩余时间(b可能>0,=0,=-1,=-2),新建队列a
  17. redisUtil.ListSet("parta", ob, expire);//设置ttl
  18. } else if (expire_a <= expire_out && expire_b < 0) {
  19. //队列a(a可能-2,-1,0,>0)没有有剩余时间 且 队列b(b可能-2,-1)没有剩余时间且<0,新建队列b
  20. redisUtil.ListSet("partb", ob, expire);//设置ttl
  21. }
  22. else
  23. {
  24. //此处属于意外情况,理论上不存在,比如 a和b 几乎相同(不可能)
  25. //或者 a|b消亡一瞬间的,由于物理原因延迟几秒,还存在0状况,或未被及时销毁不为-2 ,造成 a|b 两个不可写入时间重叠,两个都无法写入
  26. //谁剩余时间大,写谁,不设置ttl
  27. if (expire_a >= expire_b)
  28. redisUtil.ListSet("parta", ob);//不设置ttl;
  29. else
  30. redisUtil.ListSet("partb", ob);//不设置ttl
  31. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/695098
推荐阅读
相关标签
  

闽ICP备14008679号