分布式|随笔(分布式锁的一点思想)

目录
首先先从JVM锁开始
然后到分布式锁
Redis中分布式锁的应用
为什么Redis可以实现分布式锁?
我们来模拟一下分布式锁
场景:但是如果说服务器宕机了怎么办?那么这个try_lock就一直存在在redis中,其他服务就永远获取不到锁了,被try_lock进行占用
场景:如果说超时时间内获取锁的业务还没有执行完怎么办?(锁过期处理)
Redis集群中主节点宕机的不安全情况
然后说到我们基于异步Event实现的 分布式锁


首先先从JVM锁开始
1.多线程操作数据的时候,像synchronized,当其中一个线程拿到锁资源,其中线程中的lockRecord记录会与synchronized中锁的对象中的对象头中Monitor word中的锁记录进行交换,而这个锁锁住的对象来自于堆中(一般单机下我们都是这样玩);
(38条消息) 偏向锁+轻量型锁+重量型锁_Fairy要carry的博客-CSDN博客_偏向锁 轻量锁 重量锁
2.第二种情况,我们可以锁住的mysql或者redis中的数据,这样就不是堆中的对象数据了
分布式|随笔(分布式锁的一点思想)
文章图片

然后到分布式锁
首先我们分布式锁在场景下一般是分为两种,一种是cas,一种是基于异步的Event事件
首先来说下我们为啥用分布式锁
因为单机下我们JVM锁就保证了数据的一致性,是较为安全的,但是多机下如果操作同一个数据如何保证数据一致性?——>利用我们的分布式锁
那么用了分布式锁还需要我们的JVM锁吗?
那肯定是需要的,虽然从分布式锁出来确实也是唯一线程出来操作数据,但是IO太高了,吞吐量较低,我们要提高分布式锁这里效率,就是单机效率高——>所以还是需要JVM锁保证单机出来的线程的唯一性
分布式|随笔(分布式锁的一点思想)
文章图片

Redis中分布式锁的应用
为什么Redis可以实现分布式锁?
因为我们redis是一个单独的非业务服务,那么我们所有业务都可以通过redis发送命令,因为我们redis是单线程——>所以只有一个业务能写入命令成功,也就是说这个写入命令获取到了锁可以进行后续操作,而那些其他命令就进行自旋——>体现出了分布式锁在场景在的其一:基于cas操作实现的锁;
我们的其他命令会在拿到锁的命令在执行的时候进行自旋:setnx(set not if exist)——>判断是否有该key了,不存在该key才会设置值
分布式|随笔(分布式锁的一点思想)
文章图片

我们来模拟一下分布式锁
1.首先是客户端setnx key 1,然后我们客户端2再setnx key 1发现key已经存在所以说啥也干不了锁已经存在了
2.然后客户端1删除锁资源,立即删除了try_lock,然后客户端2进行操作获取到锁
分布式|随笔(分布式锁的一点思想)
文章图片

分布式|随笔(分布式锁的一点思想)
文章图片

场景:但是如果说服务器宕机了怎么办?那么这个try_lock就一直存在在redis中,其他服务就永远获取不到锁了,被try_lock进行占用
避免死锁的解决方式:我们可以增加timeout过期时间,当超过这个时间key自动删除,这样就能获取到锁了
场景:如果说超时时间内获取锁的业务还没有执行完怎么办?(锁过期处理)
我们redis中引入了一个监控线程,当锁的过期时间要到的时候,监控线程会续上去,来保证我们的命令继续执行下去
分布式|随笔(分布式锁的一点思想)
文章图片

分布式|随笔(分布式锁的一点思想)
文章图片

Redis集群中主节点宕机的不安全情况
当一服务请求到redis上,setnx key,然后上锁,此时数据还未同步到从机,然后主节点突然宕机,这样从机顶上去成为新的主机,这样新的主机就会缺少这个上锁key,那么当其他服务过来拿锁就可以拿到从而导致数据不一致的情况
解决:
采用redLock(需要五个以上redis实例,分片集群那种),引入时间戳,master1加锁失败,到master2
(38条消息) Redis实现分布式锁_玄郭郭的博客-CSDN博客_redis分布式锁
分布式|随笔(分布式锁的一点思想)
文章图片

然后说到我们基于异步Event实现的 分布式锁
(38条消息) Zookeeper_Fairy要carry的博客-CSDN博客
我们的Zookeeper分布式锁就是基于异步Event实现的,最明显的就是里面的Watch机制,众所周知zk是基于树一样的节点实现的,比如说我们三个client进行请求——>对数据下创建三个节点,比较最小的——>最小的直接拿到锁——>然后其余节点进行监听,当发现操作完毕,删除锁占用的节点时,开始进行竞争——>再次进行比较,最小的占用锁





【分布式|随笔(分布式锁的一点思想)】

    推荐阅读