Java 如何保持列表添加元素在redis上不重复?
例如,redis上的列表1,2,3,4,5,Java 如何保持列表添加元素在redis上不重复?,java,caching,redis,Java,Caching,Redis,例如,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,如果成功,列表将为e1,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,7 我正在制作一个跟踪记录缓存,如何解决这个问题?仅排序集?但是缓存需要lpush排序集是一种方法(甚至是集合)。列表本质上允许重复项。
server1希望1到8,因此它将添加6,7,8,如果成功,列表将为1,2,3,4,5,6,7,8
server2希望1到7,因此它将添加6,7,如果成功,列表将为e1,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,7
我正在制作一个跟踪记录缓存,如何解决这个问题?仅排序集?但是缓存需要lpush
排序集是一种方法(甚至是集合)。列表本质上允许重复项。实现您想要做的事情的唯一方法是使用MULTI/LREM/LPUSH/EXEC,但这不是一个好主意(LREM是O(N),随着列表的增长,这可能会非常昂贵)。如果您真的想使用list,那么您可以添加另一个数据结构来获取数字是否存在fast:Set 使您的数据集与列表保持一致。当您想在列表中输入一个数字时,首先使用SISMEMBER检查该数字是否已经在集合(或列表)中,如果在,则不要输入,如果不在,则添加到集合中并输入到列表中。SISO成员是O(1),因此不会增加太多时间开销 还有一件事需要注意: 有一个事务问题,因为您有两个或多个服务器与redis保持连接。所以在上面,一些动作需要原子化。 例如,如果发生如下顺序的情况: 服务器1检查7使用SISMEMBER=>返回不存在 服务器2检查7使用SISMEMBER=>返回不存在 服务器1将7放入列表并将7放入集合 服务器2将7放入列表并将7放入集合 然后列表将有两个7。那么如何应对呢 至少也是最好的,服务器使用SISMEMBER检查一个数字,如果不存在,则使用SADD inser进入集合,如果存在,则不做任何设置应该是原子的。如果这是原子的,上面类似的东西会是这样的: 服务器1检查7使用SISMEMBER=>返回不存在&&sadd 7到集合中 服务器2检查7使用SISMEMBER=>返回已存在 服务器1 lpush 7进入列表 服务器2什么也不做 如何做到这一点?只需使用MULTI将SISMEMBER和SADD设置为原子
MULTI
SISMEMBER set n
SADD set n
EXEC
然后,您可以使用SISMEMBER的回复来做出决定:lpush还是什么都不做。
而SADD一个重复的元素将被忽略,所以这无关紧要
已编辑
如果您想一次推送多个值,您可以使用来加快SIS成员的速度。例如,在一条管道中:
MULTI
SISMEMBER set n1
SISMEMBER set n2
...
SADD set n1,n2,....
EXEC
并在一个回复中获得每个n的结果(存在或不存在),然后将所有需要lpush的值分组到一个数组中,lpush一次。是的,SortedSet看起来很好,您希望排序(排序)并且没有重复(集)^^@azro,但排序集非常昂贵!sismember每次只检查一个元素,如果服务器1将添加1,2,3,4,5,服务器2将添加3,4,5,6,7,这是否意味着它们将循环很多?是的,这是一个折衷。但由于每个操作都是O(1),因此不会花费太多时间。它只需花费网络传输时间很多倍。如果你想加快速度,你可以试试管道。