gpt4 book ai didi

java - 如何保持列表添加元素不在 redis 上重复?

转载 作者:IT王子 更新时间:2023-10-29 06:13:19 27 4
gpt4 key购买 nike

比如redis上的一个列表1,2,3,4,5,

server1 想要 1 到 8,所以它会添加 6,7,8,如果成功,列表将是 1,2,3,4,5,6,7,8;

server2 想要 1 到 7,所以它会添加 6,7,如果成功,列表将是 1,2,3,4,5,6,7;

你看到元素 6,7 是重复的,所以实际上列表可能是 1,2,3,4,5,6,7,8,6,7 或 1,2,3,4,5,6 ,7,6,7,8

我正在做一个tailking记录缓存,如何解决这个问题?只有排序集?但是缓存需要lpush

最佳答案

如果你真的想用list,那么你可以添加另一个数据结构来快速获取一个数字是否存在:Set。

让你的集合数据与你的列表一致。当你想将一个数字压入你的列表时,首先使用 SISMEMBER 检查该数字是否已经在集合(或列表)中,如果在,则不要 LPUSH,如果不在,SADD 到集合并 LPUSH 到列表。 SISMEMBER是O(1),所以不会增加那么多时间成本。

还有一点需要注意:

存在事务问题,因为您有两个或多个服务器保持与 Redis 的连接。所以在上面,一些 Action 需要是原子的。例如,如果发生这样的顺序:

server 1 check 7 use SISMEMBER => return does not exist

server 2 check 7 use SISMEMBER => return does not exist

server 1 lpush 7 into list & sadd 7 into set

server 2 lpush 7 into list & sadd 7 into set

然后列表将有两个 7。那么如何处理呢?

至少也是最好的,服务器使用 SISMEMBER 检查数字,如果不存在,则使用 SADD 插入到集合中,如果存在,则不做任何设置应该是原子的。如果这是原子的,上面的内容将是这样的:

server 1 check 7 use SISMEMBER => return does not exist && sadd 7 into set

server 2 check 7 use SISMEMBER => return exists already.

server 1 lpush 7 into list

server 2 do nothing

如何实现?只需使用 MULTI 使 SISMEMBER 和 SADD 成为原子。

MULTI
SISMEMBER set n
SADD set n
EXEC

然后您可以使用 SISMEMBER 的回复来做出决定:lpush 或什么都不做。并且 SADD 一个重复的元素将被忽略,所以这无关紧要。

已编辑

如果你想一次推送多个值,你可以使用pipeline加速 SISMEMBER。例如。在一个管道中:

MULTI
SISMEMBER set n1
SISMEMBER set n2
...
SADD set n1,n2,....
EXEC

并在一次回复中得到每一个n的结果(存在与否),然后将所有需要lpushed的值分组到一个数组中,一起lpush一次。

关于java - 如何保持列表添加元素不在 redis 上重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45846446/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com