目录
一、redisson简介
Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它是一个基于Redis实现的高级分布式锁客户端。同时Redisson是Redis官网指定的RedlLock使用Java语言的实现。
网络上沿着Redisson的官方文档的介绍已经很多,公平锁、读写锁、信号量、闭锁的用法和源码解析。我这里就不做赘述。本篇博文主要讲使用联锁MultiLock和红锁RedLock的必要场景,以及可能出现的问题
二、联锁MultiLock和红锁RedLock
因为Redis是CAP中AP架构设计,主打的就是牺牲出现可能性比较小的一致性,达到高可用,高性能的目的。RedLock算法的出现就是为了解决redis实现的分布式锁的不能保证强数据一致性的问题,即便如此,RedLock也只是尽量将数据不一致的可能性降到最低,并不能完全解决这个问题。下面就重点探讨RedLock也可能出现的问题。
因为RedissonRedLock是继承自RedissonMultiLock的,只是重写了failedLocksLimit方法,即允许锁获取失败个数,获取锁的等待时间等方法。总体来说还是paxos过半机制那一套。所以先说RedissonMultiLock吧。
所谓联锁,其实就是将多个RLock形成一个锁组合,遍历组合内各个key,分别去获取锁,但是它允许获取失败的锁(Key)为0。具体代码如下:
protected int failedLocksLimit() {
return 0;
}
这种锁适合资源严格互斥的需要分布式锁加持的方法,也就是适合业务中,可能会需要更新数据的每个key,被严格保护,即使是其他的方法中,需要使其中的一个Key,此时也只能互斥的不能获取资源。在我的上一篇博文中举例:场景(1):一个订单中有多种商品,提交订单的时候,每种商品的库存需要被扣除。这种场景就需要用MultiLock,而不是RedLock。但是如果redis是单机模式,主从模式部署,服务器宕机怎么办呢?没有备份实例,或者备份实例不能自动替换,没有灾备方案。
那么就用哨兵或者集群模式部署可以解决吗?这两种模式都具备故障转移的功能,但是在转移的过程中,会出现脑裂的问题。也就是多个key中某一个key映射到的某台实例上的数据在故障转译中丢失了一部分,正好这个key的缓存数据在节点故障恢复后丢失了,对应的锁也不存在了。
RedLock就是为此设计的,即使多个Key中少部分key因为故障,数据丢失,失去了锁,但组合锁总体仍然具备分布式锁功能。具