使用 Redis 排序集成员管理 TTL

dzm*_*dzm 3 redis

我正在设置自动完成功能,并正在考虑使用 redis 排序集。关于此有相当多的文档,但要点是添加前缀,abc例如ZADD mySet- 0 a, 0 ab, 0 abc, 0 abc*

然后,当查询在查询上使用时ZRANK,然后基于该查询,使用ZRANGE来获取匹配结果。

无论如何,我不想在集合上实现 TTL,而是在集合的特定成员上实现 TTL。我知道这在 Redis 中是不可能的,所以我正在考虑实施替代解决方案。一种选择是使用时间戳作为排名,但这在自动完成中不起作用,因为排名很重要,它们需要具有相同的分数才能按字典顺序排序。

我正在考虑的解决方案是将已排序的集合有效地复制到未排序的集合中。这将存储诸如 之类的值<prefix>:timestamp。然后按计划可以在此处获取成员,检查时间,如果过期则从排序集中删除。显然这会增加内存使用量,但这是合适的。

我的问题是有没有更好的方法来做到这一点?就规模和/或简单性而言。谢谢!

Ita*_*ber 6

使用另一个排序集来跟踪类似 TTL 的时间戳作为分数,定期或在每次调用时查询它,以查找并删除“过期”前缀。


for*_*ack 5

@Itamar Haber 的答案很好,但它需要一个额外的排序集。为了减少内存使用,可以将过期时间编码到成员中。以词典索引解决方案为例:

指数

假设您想要索引abc1549161254 ,并在(unix 时间戳)使其过期。您可以将术语和时间戳编码为成员名称,并用\xFE, ie分隔abc\xFE1549161254

ZADD set 0 "abc\xFE1549161254"
Run Code Online (Sandbox Code Playgroud)

询问

当用户输入ab时,您可以进行查询:

ZRANGEBYLEX set "[ab" "[ab\xFF"
Run Code Online (Sandbox Code Playgroud)

这将返回abc\xFE1549161254,然后您可以用 分割字符串\xFE。第一部分是匹配成员,第二部分是过期时间。如果过期,则从排序集中删除,否则返回给用户。

使用此解决方案,您不需要额外的设置来保存 TTL,并且它应该更加节省内存。