基于 redis 的分布式锁初体验

本贴最后更新于 2266 天前,其中的信息可能已经水流花落

背景

项目中只使用了一个外部持久化组件 redis。

目前需要实现全局的并发数控制,因此调研了一下怎么使用 redis 来实现。

还好已经有了成熟的解决方案,于是直接拿来用用。

本文最终选择了 redisson 的 RPermitExpirableSemaphore 来实现。

client 选取

redis 官方推荐的 java 客户端 有 jedis,lettuce 和 redisson。

其中 jedis 对应于 redis 的原生方法,lettuce 在 jedis 的基础上,优化的 redis 的连接池。

而 redisson 在 lettuce 的基础上,又封装了很多非常实用的数据结构。

初体验

话不多说,还是上一个例子吧。

pom 依赖

<dependencies> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.10.0</version> </dependency> </dependencies>

使用

import java.util.concurrent.TimeUnit; import org.redisson.Redisson; import org.redisson.api.RPermitExpirableSemaphore; import org.redisson.api.RedissonClient; public class MainRedisClient { public static void main(String[] args) throws InterruptedException { RedissonClient redisson = Redisson.create(); // set permits; RPermitExpirableSemaphore semaphore = redisson.getPermitExpirableSemaphore("note.abeffect"); System.out.println(semaphore.trySetPermits(5)); // true; 如果已经存在了,那就是false. // available permits System.out.println(semaphore.availablePermits()); // 5 // add permits semaphore.addPermits(1); System.out.println(semaphore.availablePermits()); // 6 // acquire String permitId = semaphore.tryAcquire(120, 120, TimeUnit.SECONDS); System.out.println(semaphore.availablePermits()); // 5 String permitId2 = semaphore.tryAcquire(120, 120, TimeUnit.SECONDS); System.out.println(semaphore.availablePermits()); // 4 // print used permits count String timeoutName = RedissonObject.suffixName(semaphore.getName(), "timeout"); System.out.println(redisson.getScoredSortedSet(timeoutName).size()); // release semaphore.release(permitId); System.out.println(semaphore.availablePermits()); // 5 semaphore.release(permitId2); System.out.println(semaphore.availablePermits()); // 6 // shutdown redisson.shutdown(); } }

实现

观察下 redis 中的值的变化。

当前可用值存储在 keystring 中;
已经在用的值,存储有 {key}:timeoutzset

初始时

127.0.0.1:6379> keys * (empty list or set)

初始化后

127.0.0.1:6379> keys * 1) "note.abeffect" 127.0.0.1:6379> type note.abeffect string 127.0.0.1:6379> get note.abeffect "5"

add 后

127.0.0.1:6379> get note.abeffect "6"

acquire 后

127.0.0.1:6379> keys * 1) "note.abeffect" 2) "{note.abeffect}:timeout" 127.0.0.1:6379> type "{note.abeffect}:timeout" zset 127.0.0.1:6379> zrange "{note.abeffect}:timeout" 0 100 withscores 1) "7536b157d06591398faa711b1861e4a7" 2) "1547109745958" 3) "5e2ff2b25e7cc90c296540f66ef5318b" 4) "1547109747182" 127.0.0.1:6379> get note.abeffect "4"

其中的时间戳是过期时间。

释放后

127.0.0.1:6379> keys * 1) "note.abeffect" 127.0.0.1:6379> get note.abeffect "6"

参考

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3194 引用 • 8214 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...