分布式锁的实现的几种方案【面试题详解】

今天爱分享给大家带来分布式锁的实现的几种方案【面试题详解】,希望能够帮助到大家。

分布式锁应该是怎么样的?
1)可以保证在分布式部署的应用集群中,同一个方法在同一时间只能被一台机器上的一个线程执行。
2)这锁要是一把可重入锁(避免死锁)
3)这把锁最好是一把阻塞锁(根据业务需求考虑要不要这条)
4)有高可用的获取锁和释放锁功能
5)获取锁和释放锁的性能要好

基于数据库实现分布式锁
1)最简单的方式可能就是直接创建一张锁表
1、这把锁强依赖数据库的可用性,数据库是一个单点,一旦数据库挂掉,会导致业务系统不可用。
2、这把锁没有失效时间,一旦解锁操作失败,就会导致锁记录一直在数据库中,其他线程无法再获得到锁。
3、这把锁只能是非阻塞的,因为数据的insert操作,一旦插入失败就会直接报错。没有获得锁的线程并不会进入排队队列,要想再次获得锁就要再次触发获得锁操作。
4、这把锁是非重入的,同一个线程在没有释放锁之前无法再次获得该锁。因为数据中数据已经存在了。

数据库是单点?搞两个数据库,数据之前双向同步。一旦挂掉快速切换到备库上。
没有失效时间?只要做一个定时任务,每隔一定时间把数据库中的超时数据清理一遍。
非阻塞的?搞一个while循环,直到insert成功再返回成功。
非重入的?在数据库表中加个字段,记录当前获得锁的机器的主机信息和线程信息,那么下次再获取锁的时候先查询数据库,如果当前机器的主机信息和线程信息在数据库可以查到的话,直接把锁分配给他就可以了。

借助数据中自带的锁来实现分布式的锁(select *** for update)
在查询语句后面增加for update,数据库会在查询过程中给数据库表增加排他锁(这里再多提一句,InnoDB引擎在加锁的时候,只有通过索引进行检索的时候才会使用行级锁,否则会使用表级锁。 通过connection.commit()操作来释放锁

基于缓存(redis,memcached,tair)实现分布式锁
基于 REDIS 的 SETNX()、EXPIRE() 方法( 设置过期时间)做分布式锁

基于Zookeeper实现分布式锁

每个客户端对某个方法加锁时,在zookeeper上的与该方法对应的指定节点的目录下,生成一个唯一的瞬时有序节点。 判断是否获取锁的方式很简单,只需要判断有序节点中序号最小的一个。 当释放锁的时候,只需将这个瞬时节点删除即可。同时,其可以避免服务宕机导致的锁无法释放,而产生的死锁问题。

人已赞赏
Java

一个线程运行时发生异常会怎样【面试题详解】

2020-11-6 16:50:31

Java

Hashtable的size()方法为什么要做同步【面试题详解】

2020-11-6 17:22:13

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
'); })();