redis集合数据过期_如何给redis集合中的元素设置过期时间

我们知道redis中的过期时间只能作用于key上。对于string数据结构来说,因为它是key/value的形式,只有一个value与key对应,所以当过期时间到了,整个key/value被移除,符合心理预期,皆大欢喜。但好多时候我们用到的是其他数据结构,比如:一个拥有多个元素的集合。由于过期时间只能作用于key(集合数据结构可以理解为集合ID)上,当过期时间到了,整个集合被移除。一般使用集合的场景都不希望各个元素在同一时间过期,有时也希望进行与时间相关的查询,这该怎么办呢?

redis有一种数据结构是Sorted Set,有序集合,它的实现是hash table(element->score, 用于实现zscore及判断element是否在集合内)和skiplist(score->element,按score排序)的混合体。 skiplist有点像平衡二叉树那样,不同范围的score被分成一层一层,每层是一个按score排序的链表。其中zadd/zrem是O(log(N)),zrangebyscore/zremrangebyscore是O(log(N)+M),N是Set大小,M是结果/操作元素的个数。可见,原本可能很大的N被很关键的Log了一下,1000万大小的Set,复杂度也只是几十不到。当然,如果一次命中很多元素M很大那谁也没办法了。

这里我们用到了它如下特性:

1. 元素唯一

2. 每个元素拥有一个score

3. 所有元素依据score进行有序排列

4. 可通过score来进行查询

我们可以借助这些特性来让集合中的元素拥有时间维度。每当add一个元素时,把当前时间的unix timestamp作为score设置到这个元素上,这样sorted set会根据这个timestamp将元素排序存储。

场景一:当我们查询最近1分钟内有更新的元素时,可以使用命令 zrangebyscore key min max来获取。例如:

zadd set1 1522598879 "one"

zadd set1 1522598969 "two"

zadd set1 1522598979 "three"

执行查询:zrangebyscore set1 1522598920 1522598980

返回值:"two"和"three"

场景二:当我们查询最新更新的2个元素,可以使用 zrevrange key start stop来获取。例如:

zadd set1 1522598879 "one"

zadd set1 1522598969 "two"

zadd set1 1522598979 "three"

执行查询:zrevrange set1 0 1

返回值:"three"和"two"

场景三:当我们需要删除最近1分钟没有过更新的元素,可以使用 zremrangebyscore key min max 来删除过期元素。例如:

zadd set1 1522598879 "one"

zadd set1 1522598969 "two"

zadd set1 1522598979 "three"

执行命令: zremrangebyscore set1 0 1522598920

执行结果:删除了元素"one"

一般来讲,我们会启动一个后台任务来不断进行过期元素的删除操作,任务的重复执行间隔可以视业务对过期数据的容忍度。如果容忍度较高,可以设置时间久一点,相反可以设置时间短一些。

当我们应用到生产环境时,还应该考虑内存占用和访问效率。有序集合的长度较短或者体积较小的时候,Redis可以选择使用ziplist的紧凑存储方式来存储这些结构,从而达到优化存储空间的目的。然而,ziplist会以序列化的方式存储数据,这些序列化数据每次被读取的时候都要就行解码,每次被写入的时候都要进行局部的重新编码,并且可能需要对内存里的数据进行移动。因此读写一个长度较大的ziplist可能会造成性能问题。从我们的生产运维经验上来讲,以下参数设置可以借鉴(根据业务和实际情况进行不断调整):

zset-max-ziplist-entries 128

zset-max-ziplist-value 64

即:当有序集合的元素都小于64字节并且元素数量小于128个的时候,使用ziplist,反之使用skiplist。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值