gpt4 book ai didi

java - Spring-Data-Redis 与 Jedis putIfAbsent 用于分布式锁 - 不正确的行为

转载 作者:行者123 更新时间:2023-12-02 09:22:18 28 4
gpt4 key购买 nike

我在使用 Spring Data Redis 创建分布式锁时遇到一些问题。为此,使用 CacheManager 中的 putIfAbsent 方法。

从高层次的角度来看,操作看起来像这样:

if (manager.putIfAbsent(parameters) == null) {
executeOperation();
}

从 putIfAbsent 的实现来看,似乎使用了底层 Jedis 驱动程序的 setNX 操作。

Spring 实现的代码如下所示:

if (!connection.setNX(keyBytes, value)) {
return connection.get(keyBytes);
}
maintainKnownKeys(element, connection);
processKeyExpiration(element, connection);

连接的setNX只是对实际客户端操作的委托(delegate)。关于实现该方法有类似:

JedisConverters.toBoolean(jedis.setnx(key, value));

所以我遇到了两个不同的问题:

  1. 我的executeOperation() 由两个单独的进程同时执行。 (此问题仅出现几次)。

  2. 我遇到的情况是 key 仍然存在且未过期。这意味着代码 processKeyExpiration(element, connection) 未执行。这意味着 setNx 是在该语句之前执行的,因为 key 尚未添加并返回,但实际上 key 已添加。

大多数时候一切正常。关键的序列化器是StringRedisSerializer

我正在使用: spring-data-redis 1.8.23.RELEASE 绝地武士2.9.3

会不会有一些环境问题没有得到正确处理由 Jedis 或类似的东西?有人达到过这样的境界吗?是否可以尝试任何修复,库更新?

最佳答案

所以我对此做了更多分析。而且似乎由于 putIfAbsent 的实现方式,如果在多个进程/线程中使用,很容易出现竞争条件。

这一事实是因为 putIfAbsent 实现的一系列命令(setNX、expire、get)不是事务性的,并且由于适当的条件(持久操作,而不是适当的逐出逻辑),它很容易出现不正确的行为。

关于如何基于Redis setNX操作进行分布式锁定的类似解释可以在这里找到Redis setNX command

putIfAbsent 的实现在用于锁定时很容易出现不正确的行为,其方式与上述文档中描述的类似。

总而言之,使用 putIfAbsent 和 Jedis 驱动程序进行分布式锁定可能不是最好的主意,至少在那个版本的 Spring 上是这样,因为从 2.x.x 开始,我知道实现发生了一些变化。

关于java - Spring-Data-Redis 与 Jedis putIfAbsent 用于分布式锁 - 不正确的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58609065/

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