redis 的哈希队列中有一些值,程序需要保持该队列只有 3 个成员。
例如:
127.0.0.1:6379> HSET hash2 user1 "name1"
127.0.0.1:6379> HSET hash2 user2 "name2"
127.0.0.1:6379> HSET hash2 user3 "name3"
当插入一个新的键“user4”时,程序中的队列应该从hash2中移除“user1”。
我们知道列表有一个“ltrim”函数可以很容易地保持列表的固定计数。
至于哈希,我找不到一个函数可以轻松做到这一点。 如果 hash2 的计数小于 512,则 redis 将键存储为“ziplist”数据结构。它的行为就像一个序列表。 有没有办法让哈希队列保持固定数量,当一个新值插入到该队列时,应该删除最早进入队列的键?
现在,我可以通过以下方式将新值插入到哈希队列中:
读取hash2的长度
如果长度小于3,直接插入队列,否则执行步骤3。
如果长度大于3,**从redis读取所有key**
删除第一个
将新值插入哈希队列。
最佳答案
HASH
中的元素没有顺序,您无法分辨哪个是最早的/最新的。所以对于HASH
,没有类似ltrim
的命令。
您的解决方案之所以可行,是因为 Redis 将小哈希编码为 zipmap。正如您提到的,zipmap 类似于 LIST
,元素按插入时间排序。但是,依赖它并不是一个好主意。如果有人更改了hash-max-zipmap-entries
和hash-max-zipmap-value
的配置,或者你的HASH
的个数超过限制,您的解决方案可能会失败。
解决方案
Use an extra LIST to record the order
您可以使用额外的 LIST
记录元素/字段的顺序,而不是依赖于 zipmap 的顺序。每次在 HASH
中插入一个元素时,也会将该字段rpush
到 LIST
中。如果HASH
的大小达到限制,lpop
LIST
中的第一个元素,并删除HASH<中的相应字段
.
HSET hash2 user1 "name1"
RPUSH list2 user1
HSET hash2 user2 "name2"
RPUSH list2 user2
HSET hash2 user3 "name3"
RPUSH list2 user3
HSET hash2 user4 "name4" // reach the limit
LPOP list2 // remove the oldest from list to get "user1"
HDEL hash2 user1 // remove it from hash
关于hash - redis中如何通过添加命令删除第一个key,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40204289/