是否有支持 Redis 集群上事务的 Redis 客户端(Java 首选)?

Is there any Redis client (Java prefered) which supports transactions on Redis cluster?

我在网上仔细查找,但找不到提供此功能的成熟 Redis 客户端。只找到这个project。 有人知道提供上述内容的 Redis 客户端吗?谢谢你。

Redis 集群中的事务与 Redis Standalone 中的事务不同。

TL;DR;

与其说是客户问题,不如说是关于保证和 trade-offs 的概念性问题。

说明

在 Redis Cluster 中,一个特定的节点是一个或多个 hash-slots 的主节点,这是在多个节点之间分片数据的分区方案。一个 hash-slot,根据命令中使用的键计算,存在于一个节点上。具有多个键的命令仅限于产生相同的 hash-slot。否则,他们将被拒绝。这样的星座叫做cross-slot.

交易似乎是对 cross-slot 键执行命令的解决方案,但在某一时刻,人们会离开一个节点的范围,需要另一个节点来继续交易。如果一个键位于一个节点上而另一个键位于另一个节点上,则可能会出现这种情况。仍然没有事务协调,这有时会成为 Redis 集群问题。

一个high-levelAPI为Redis Cluster提供事务支持面临多个问题,目前有两种策略,如何在Redis Cluster中处理事务:

如果所有键都位于一个节点上,则支持事务

此选项允许 fully-featured 笔交易。要求客户端库跟踪交易执行的节点,并在交易进行时禁止槽范围外的键。因为插槽只能通过使用包含密钥的命令来确定,所以客户端需要设置一个事务标志,并且在包含密钥的第一个命令上,需要在事务中的第一个命令之前发出 MULTI 命令。这里的限制显然是要求所有键都位于一个节点上。

分布式事务

在这种情况下,在所有加入分布式事务的节点上启动了多个事务。此分布式事务可以包含来自所有主节点的密钥。一旦事务执行,客户端库触发事务的执行,库收集所有结果(以维护命令结果的顺序)并return发送给调用者。

这种交易方式对客户来说是透明的。一旦请求特定节点上的密钥并且该节点尚未成为交易的一部分,就会发出 MULTI 命令以将该节点加入交易。这里的缺点是交易不再是有条件的(WATCH)。单个事务不知道密钥是否在不同节点上更改,因此一个事务可以回滚,而其他事务会成功。听起来有点像 two-phase-commit.

结论

Redis Transactions 感觉就像可以有条件的原子命令批处理。重要的是要记住,命令执行是延迟的,因为在事务执行时读取结果 return 而不是在命令发出时读取结果。

对于Redis Cluster,客户还没有决定全局策略。在特定的 Redis 集群节点上 运行 事务是安全的,但您只能使用该节点提供的键。这两种可能的策略都具有可能对某些人有用的属性 use-cases 但也有局限性。