软件设计:分布式锁

    作者:马崮蚂蚁哥更新于: 2020-04-15 14:59:00

      分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁。

      为什么需要分布式锁

      应用中需要避免多个线程在同一时间对同一个共享变量做修改

      在单机部署的项目中,为了避免上述现象,需要对变量或代码块做同步

      在分布式部署的项目中,为了避免上述现象,用同步是解决不了的(因为相同的项目部署在了多台服务器,同步只能解决单台服务器的问题),所以就需要分布式锁,保证在分布式部署的应用集群中,同一个方法在同一时间只能被一台机器上的一个线程执行

      分布式锁有几种实现方式

      主流的实现方式有三种

      1、利用数据库实现

      2、利用缓存(Redis)实现

      3、利用zookeeper实现

      简述各种方式及优缺点

      1、利用数据库实现

      优点:简单、易理解

      缺点:高并发时,性能差,增加了数据库开销

      方法一:

      新建一张表,向该表中添加相同主键的一条记录,哪个线程添加成功,即获得了分布式锁,

      然后执行相关逻辑,逻辑执行完之后,删除数据库表中的该数据,删除即代表解锁

      方法二、

      使用forupdate,数据表会在查询的时候添加排它锁,

      多个线程同时来执行时,只有一个会成功加锁,其余的线程都会阻塞,

      加锁成功的线程即获得分布式锁的线程,该线程执行相关逻辑,

      逻辑执行完之后,使用connection.commit解锁,此时阻塞的其他线程中会有一个加锁成功....

      2、使用redis缓存实现

      优点:效率高

      缺点:设置过期时间过长过短都不合适,需要根据实际情况权衡

      大概思路:

      向redis中添加key,并设置过期时间

      如果key已存在,则添加失败

      如果key不存在,则添加成功

      添加成功,即获得了分布式锁

      获得锁的线程执行业务逻辑,执行完之后,删除redis中的key(即解锁)

      3、通过zookeeper实现

      优点:有效的解决单点问题,不可重入问题,非阻塞问题以及锁无法释放的问题。实现起来较为简单

      缺点:因为每次在创建锁和释放锁的过程中,都要动态创建、销毁临时节点来实现锁功能。

      ZK中创建和删除节点只能通过Leader服务器来执行,然后将数据同步到所有的Follower机器上。

      大概思路:

      每一个锁都是zookeeper上的一个znode(普通节点)

      当多个线程来获取锁时,都会在该znode上创建有序临时子节点,每个有序临时子节点都有自己的序号

      只有序号最小的可以拥有锁,然后执行相关逻辑,执行完成之后删除子节点(即解锁),触发监听

      序号如果不是最小的,则没有获得锁,设置监听事件,监听序号比本身小的前一个节点,

      等待事件触发再次比较是否是最小的

      在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,这个时候,便需要使用到分布式锁。

课课家教育

未登录