分布式锁三种实现方式及对比

 更新时间:2020年04月15日 09:36:38   作者:cool小伙  
这篇文章主要介绍了分布式锁三种实现方式及对比,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

分布式锁三种实现方式:

1. 基于数据库实现分布式锁;

2. 基于缓存(Redis等)实现分布式锁;

3. 基于Zookeeper实现分布式锁;

一, 基于数据库实现分布式锁

1. 悲观锁

利用select … where … for update 排他锁

注意: 其他附加功能与实现一基本一致,这里需要注意的是“where name=lock ”,name字段必须要走索引,否则会锁表。有些情况下,比如表不大,mysql优化器会不走这个索引,导致锁表问题。

2. 乐观锁

所谓乐观锁与前边最大区别在于基于CAS思想,是不具有互斥性,不会产生锁等待而消耗资源,操作过程中认为不存在并发冲突,只有update version失败后才能觉察到。我们的抢购、秒杀就是用了这种实现以防止超卖。

通过增加递增的版本号字段实现乐观锁

二, 基于缓存(Redis等)实现分布式锁

1. 使用命令介绍:

(1)SETNX

SETNX key val:当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。

(2)expire

expire key timeout:为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。

(3)delete

delete key:删除key

在使用Redis实现分布式锁的时候,主要就会使用到这三个命令。

2. 实现思想:

(1)获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。

(2)获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。

(3)释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。

三, 基于Zookeeper实现分布式锁

ZooKeeper是一个为分布式应用提供一致性服务的开源组件,它内部是一个分层的文件系统目录树结构,规定同一个目录下只能有一个唯一文件名。基于ZooKeeper实现分布式锁的步骤如下:

(1)创建一个目录mylock;
(2)线程A想获取锁就在mylock目录下创建临时顺序节点;
(3)获取mylock目录下所有的子节点,然后获取比自己小的兄弟节点,如果不存在,则说明当前线程顺序号最小,获得锁;
(4)线程B获取所有节点,判断自己不是最小节点,设置监听比自己次小的节点;
(5)线程A处理完,删除自己的节点,线程B监听到变更事件,判断自己是不是最小的节点,如果是则获得锁。

这里推荐一个Apache的开源库Curator,它是一个ZooKeeper客户端,Curator提供的InterProcessMutex是分布式锁的实现,acquire方法用于获取锁,release方法用于释放锁。

优点:具备高可用、可重入、阻塞锁特性,可解决失效死锁问题。

缺点:因为需要频繁的创建和删除节点,性能上不如Redis方式。

四,对比

数据库分布式锁实现

缺点:

1.db操作性能较差,并且有锁表的风险

2.非阻塞操作失败后,需要轮询,占用cpu资源;

3.长时间不commit或者长时间轮询,可能会占用较多连接资源

Redis(缓存)分布式锁实现

缺点:

1.锁删除失败 过期时间不好控制

2.非阻塞,操作失败后,需要轮询,占用cpu资源;

ZK分布式锁实现

缺点:性能不如redis实现,主要原因是写操作(获取锁释放锁)都需要在Leader上执行,然后同步到follower。

总之:ZooKeeper有较好的性能和可靠性。

从理解的难易程度角度(从低到高)数据库 > 缓存 > Zookeeper

从实现的复杂性角度(从低到高)Zookeeper >= 缓存 > 数据库

从性能角度(从高到低)缓存 > Zookeeper >= 数据库

从可靠性角度(从高到低)Zookeeper > 缓存 > 数据库

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • muduo源码分析之TcpServer模块详细介绍

    muduo源码分析之TcpServer模块详细介绍

    这篇文章主要介绍了muduo源码分析之TcpServer模块,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • 浅谈Redis中bind的坑

    浅谈Redis中bind的坑

    本文主要介绍了浅谈Redis中bind的坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • redis zrange 与 zrangebyscore的区别解析

    redis zrange 与 zrangebyscore的区别解析

    这篇文章主要介绍了redis zrange与zrangebyscore的区别,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • Redis之常用数据结构哈希表

    Redis之常用数据结构哈希表

    这篇文章主要介绍了Redis常用的数据结构哈希表,哈希表是一种保存键值对的数据结构,具有一定的参考价值,需要的朋友可以参考阅读
    2023-04-04
  • 分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了

    分布式锁为什么要选择Zookeeper而不是Redis?看完这篇你就明白了

    Zookeeper的机制可以保证分布式锁实现业务代码简单,成本低,Redis如果要解决分布式锁的问题,对于一些复杂的情况,很难解决,成本较高,这篇文章重点给大家介绍分布式锁选择Zookeeper 而不是Redis的理由,一起看看吧
    2021-05-05
  • Windows环境下查看、添加、修改redis数据库的密码两种方式

    Windows环境下查看、添加、修改redis数据库的密码两种方式

    在Windows系统上设置Redis密码的过程与Linux系统类似,但需注意几个关键步骤以确保正确配置,这篇文章主要给大家介绍了关于Windows环境下查看、添加、修改redis数据库的密码两种方式,需要的朋友可以参考下
    2024-07-07
  • 基于redis集群设置密码的实例

    基于redis集群设置密码的实例

    今天小编就为大家分享一篇基于redis集群设置密码的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • 关于Redis网络模型的源码详析

    关于Redis网络模型的源码详析

    这篇文章主要给大家介绍了关于Redis网络模型的源码,文中通过示例代码介绍的非常详细,对大家的学习或者使用Redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-07-07
  • 详解Redis开启远程登录连接

    详解Redis开启远程登录连接

    本篇文章主要介绍了Redis开启远程登录连接,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • Redis中set类型实现交集并集差集

    Redis中set类型实现交集并集差集

    本文主要介绍了Redis中set类型实现交集并集差集,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06

最新评论