如何防止两个消息消费者(如Azure服务总线消费者)同时更新相同的redis值

问题描述 投票:0回答:1

我有两个 Azure Aervice Bus (ASB) 使用者在两个不同的 Pod 上运行。它们都从同一个 ASB 队列中消费并写入 Redis。现在,两个 ASB 使用者可能会更新某个键的相同 Redis 值。您能否让我知道如何处理这种情况,以便当一个 Pod 的使用者实例更新 Redis 值时,在第一个使用者完成之前不应允许另一个使用者实例更新它。一旦第一个消费者完成,第二个消费者就可以继续更新值。

我看到一些选项,例如使用带有 NX 和 PX 选项的 SET 命令的锁定机制或使用 WATCH 和 EXEC 处理事务,但不确定哪种方法更适合解决这种情况,或者是否有其他有效的方法。现在有人可以让我知道如何处理/修复这种情况吗

我正在使用redis 7.2.3 azure pass服务。从技术堆栈的角度来看,我正在使用 Spring Boot(Spring data redis lettuce 库)、Java 等。即使有人有一些代码示例或链接,也请分享相同的

redis azureservicebus
1个回答
0
投票

这应该不是问题,因为 Redis 是单线程的。对 SET 的调用只会排队并运行,不会出现问题。

如果您有多个调用需要以原子方式发生,这会变得很棘手,您将需要使用事务(即WATCH、MULTI和EXEC)。 WATCH 启动乐观锁。 MULTI 开始对命令进行排队而不运行它们。 EXEC 然后运行整个 shebang。

这是一个例子:

redis.cloud> WATCH foo bar baz   # watches the keys for changes
OK
redis.cloud> MULTI               # starts the transaction
OK
redis.cloud(TX)> SET foo 42      # queues commands
QUEUED
redis.cloud(TX)> SET bar 23
QUEUED
redis.cloud(TX)> SET baz 13
QUEUED
redis.cloud> EXEC                # executes the queued commands

如果在命令排队时没有其他人进行更改,那么您将得到排队命令的结果:

1) OK                            # returns result of all commands
2) OK
3) OK

如果另一个客户端已经修改了任何WATCH'd键,则对EXEC的调用将返回(nil)。再试一次。

(nil)                            # failed transaction, nil returned
© www.soinside.com 2019 - 2024. All rights reserved.