网站停止运营通知
分布式
IT面试
1323 ·
0 ·
2023-02-08 16:49:15
最新编辑原因:

分布式锁

非分布式场景下,正常线程进程同步的机制有哪些?
  • 互斥:互斥的机制,保证同一时间只有一个线程可以操作共享资源 synchronized,Lock等

  • 临界值:让多线程串行话去访问资源

  • 事件通知:通过事件的通知去保证大家都有序访问共享资源

  • 信号量:多个任务同时访问,同时限制数量,比如发令枪CDL,Semaphore等

分布式锁实现方式
基于Zookeeper
  • 主要是使用节点唯一的特性来实现,创建失败后丢到队列中去排队

  • 释放锁就是删除节点,删除后然后通知其他人过来创建节点,即加锁

    • 如果机器宕机了,没有删除掉,资源就会一直被占着,怎么处理呢? 创建临时节点就好,客户端断开,节点就自动删除了

  • 使用zk可能会造成的问题

    • 羊群效应,导致占用服务器资源。 处理方法:临时顺序节点,只监听前一个节点,以此类推,只关注自己前后,就不会出现羊群效应

  • 使用zk实现分布式锁的缺点

    • 性能没有缓存服务高。因为每次在创建锁和释放锁的过程中,都要动态创建、销毁瞬时节点来实现锁功能。ZK中创建和删除节点只能通过Leader服务器来执行,然后将数据同步到所有的Follower机器上。

    • 可能带来并发问题。 由于网络抖动,客户端ZK集群的session连接断了,那么zk以为客户端挂了,就会删除临时节点,这时候其他客户端就可以获取到分布式锁了。就可能产生并发问题了。

      这个问题不常见是因为zk有重试机制,一旦zk集群检测不到客户端的心跳,就会重试,Curator客户端支持多种重试策略。
      多次重试之后还不行的话才会删除临时节点。
      Tip:所以,选择一个合适的重试策略也比较重要,要在锁的粒度和并发之间找一个平衡。

基于Redis

关键命令:

  1. setnx : 如果不存在,则 SET

  2. setex: 不存在则set,存在则覆写。 它是一个原子性(atomic)操作,关联值和设置生存时间两个动作会在同一时间内完成

实现:
setnx如果加锁成功,但是没有释放,就会出现死锁;所以使用setex更合理

  • 还有一个px,过期时间,兜底

  • 还遇到一个问题,就是Redis加锁,内部的业务时间超过锁的时间,怎么办?可以使用守护进程来续期。(Redission有相关的实现)

 

基于MySQL实现

这个简单,就是维护DB数据就行

CAP定理

  1. 一致性Consistency

  2. 可用性Availability

  3. 分区容错性Partition tolerance


本作品系原创,采用《署名-非商业性使用-禁止演绎4.0 国际》许可协议.转载请说明出处
本文链接:https://www.upupor.com/u/4mreMqY 复制

无内容

推荐阅读