redisson 应用(一)
redisson 是基于redis的扩展库,使得redis除了应用于缓存以外,还能做队列等数据结构,直接使用的分布式锁,以及人物调度器等。
redisson支持异步API,为了演示方便我这里用同步API。这里初始化一个单机的redis连接
BitSet是一个bit数据集,类似bit数组,和Set接口没啥关系。对于存储一些需要按位操作的数据是很理想的数据结构。对应于Java中 Java.util.BitSet
在redis中,初始化一个Bitset
在分布式系统中,原子性的整形或者浮点的适用性很强,redisson提供了直接的API来操作这类数据。也支持原子性的CAS操作。
这个类的功能类似于AtomicLong,但是LongAdder的高并发时性能会好很多,非常适合高并发时的计数。(DoubleAdder类似)
这个类的目的在于实现一些速度限制实现。但是acquire会阻塞线程,而且不保证公平性。
这个Id生成器生成一般情况下递增的整数值,效率比较高。
参考文档 redisson文档
redisson+springboot 实现分布式锁
在一些场景时,需要保证数据的不重复,以及数据的准确性,特别是特定下,某些数据的准确性显得尤为重要,所以这个时候要保证某个方法同一时刻只能有一个线程执行。在单机情况下可以用jdk的乐观锁进行保证数据的准确性。而在分布式系统中,这种jdk的锁就无法满足这种场景。
所以需要使用redssion实现分布式锁,它不仅可以实现分布式锁,也可以在某些情况下保证不重复提交,保证接口的幂等性。
redisson是基于redis实现的分布式锁,因为redis执行命令操作时是单线程,所以可以保证线程安全。当然还有其他实现分布式锁的方案,例如zk,MongoDB等。
首先,为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件:
模拟200个并发测试
结果:
没有库存变成负数的情况,说明分布式锁已生效
redisson订阅和发布 慢
redisson不会出现订阅和发布慢的情况
redisson订阅简单易使用,没有容错,可靠性机制,所以用的不多,一般都用消息中间件了,不会出现订阅和发布慢的情况。
Redisson实现分布式锁原理
如图所示啊,石杉大佬画的redisson分布式锁原理。
大概总结下,保证我们的key落到一个集群里,并且加锁操作是基于lua脚本的原子性操作,对于锁延迟由watch dog控制。
具体可以看
如果你对某个redis master实例,写入了myLock这种锁key的value,此时会异步复制给对应的master slave实例。但是这个过程中一旦发生redis master宕机,主备切换,redis slave变为了redis master。
接着就会导致,客户端2来尝试加锁的时候,在新的redis master上完成了加锁,而客户端1也以为自己成功加了锁。
此时就会 导致多个客户端对一个分布式锁完成了加锁。
这时系统在业务语义上一定会出现问题,导致各种脏数据的产生。
所以这个就是redis cluster,或者是redis master-slave架构的主从异步复制导致的redis分布式锁的***缺陷:在redis master实例宕机的时候,可能导致多个客户端同时完成加锁。
如果主动结构redis架构模式下,我们想保证完全一致,必须重写加锁的逻辑了, 保证必须mater和slave同时加锁成功,我们整个加锁才是成功的 。
上面的2是对于单个主从结构我们可以这样干,如果假设我们有多个相对独立的master,无slave呢?我们在其中一个master上加了