随笔:分布式锁的一点思想

目录

首先先从JVM锁开始

然后到分布式锁

 Redis中分布式锁的应用

 为什么Redis可以实现分布式锁?

 我们来模拟一下分布式锁

场景:但是如果说服务器宕机了怎么办?那么这个try_lock就一直存在在redis中,其他服务就永远获取不到锁了,被try_lock进行占用

场景:如果说超时时间内获取锁的业务还没有执行完怎么办?(锁过期处理)

 Redis集群中主节点宕机的不安全情况

然后说到我们基于异步Event实现的 分布式锁


 

首先先从JVM锁开始

1.多线程操作数据的时候,像synchronized,当其中一个线程拿到锁资源,其中线程中的lockRecord记录会与synchronized中锁的对象中的对象头中Monitor word中的锁记录进行交换,而这个锁锁住的对象来自于堆中(一般单机下我们都是这样玩);

(38条消息) 偏向锁+轻量型锁+重量型锁_Fairy要carry的博客-CSDN博客_偏向锁 轻量锁 重量锁

2.第二种情况,我们可以锁住的mysql或者redis中的数据,这样就不是堆中的对象数据了

随笔:分布式锁的一点思想_第1张图片

然后到分布式锁

首先我们分布式锁在场景下一般是分为两种,一种是cas,一种是基于异步的Event事件

首先来说下我们为啥用分布式锁

因为单机下我们JVM锁就保证了数据的一致性,是较为安全的,但是多机下如果操作同一个数据如何保证数据一致性?——>利用我们的分布式锁

那么用了分布式锁还需要我们的JVM锁吗?

那肯定是需要的,虽然从分布式锁出来确实也是唯一线程出来操作数据,但是IO太高了,吞吐量较低,我们要提高分布式锁这里效率,就是单机效率高——>所以还是需要JVM锁保证单机出来的线程的唯一性

随笔:分布式锁的一点思想_第2张图片

 Redis中分布式锁的应用

 为什么Redis可以实现分布式锁?

因为我们redis是一个单独的非业务服务,那么我们所有业务都可以通过redis发送命令,因为我们redis是单线程——>所以只有一个业务能写入命令成功,也就是说这个写入命令获取到了锁可以进行后续操作,而那些其他命令就进行自旋——>体现出了分布式锁在场景在的其一:基于cas操作实现的锁

我们的其他命令会在拿到锁的命令在执行的时候进行自旋:setnx(set not if exist)——>判断是否有该key了,不存在该key才会设置值

随笔:分布式锁的一点思想_第3张图片

 我们来模拟一下分布式锁

1.首先是客户端setnx key 1,然后我们客户端2再setnx key 1发现key已经存在所以说啥也干不了锁已经存在了

2.然后客户端1删除锁资源,立即删除了try_lock,然后客户端2进行操作获取到锁

随笔:分布式锁的一点思想_第4张图片

随笔:分布式锁的一点思想_第5张图片

场景:但是如果说服务器宕机了怎么办?那么这个try_lock就一直存在在redis中,其他服务就永远获取不到锁了,被try_lock进行占用

避免死锁的解决方式:我们可以增加timeout过期时间,当超过这个时间key自动删除,这样就能获取到锁了

场景:如果说超时时间内获取锁的业务还没有执行完怎么办?(锁过期处理)

我们redis中引入了一个监控线程,当锁的过期时间要到的时候,监控线程会续上去,来保证我们的命令继续执行下去

随笔:分布式锁的一点思想_第6张图片

 

 Redis集群中主节点宕机的不安全情况

当一服务请求到redis上,setnx key,然后上锁,此时数据还未同步到从机,然后主节点突然宕机,这样从机顶上去成为新的主机,这样新的主机就会缺少这个上锁key,那么当其他服务过来拿锁就可以拿到从而导致数据不一致的情况

解决:

采用redLock(需要五个以上redis实例,分片集群那种),引入时间戳,master1加锁失败,到master2

(38条消息) Redis实现分布式锁_玄郭郭的博客-CSDN博客_redis分布式锁

随笔:分布式锁的一点思想_第7张图片

然后说到我们基于异步Event实现的 分布式锁

(38条消息) Zookeeper_Fairy要carry的博客-CSDN博客

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

 

 

你可能感兴趣的:(分布式,分布式,jvm,java)