分布式锁的几种实现方式

基于数据库实现分布式锁

基于数据库表:创建一张锁表,当我们要给某个方法(资源)加锁,可以在表中增加一条记录,想要释放锁的时候就删除这条记录。

弊端:
1:这把锁比较依赖数据库,一旦数据库挂掉,会导致业务系统不可用。
2:这把锁没有失效时间,一旦解锁操作失败,就会导致锁记录一直存在数据库,其他线程无法再获得该锁。
3:这把锁是非阻塞的,因为数据的insert操作,一旦插入失败就会直接报错,没有获得锁的线程并不会进入排队队列,要想再次获得锁就要再次触发获得锁操作。
4:这把锁是非重入的,同一个线程在没有释放锁之前无法再次获得该锁,因为数据中数据已经存在了。

基于数据库排他锁
基于MySQL的InnoDB引擎,可以使用数据库自带的锁来实现分布式锁-直接在查询语句后面增加for update(InnoDB引擎在加锁的时候,只有通过索引进行检索的时候才会使用行级锁,否则会使用表锁)

优势
1:阻塞锁:for update语句会在执行成功后立即返回,在执行失败时一直处于阻塞状态,直到成功。
2:锁定之后服务宕机,无法释放,服务宕机之后数据库会自己把锁释放掉。
弊端:
1:无法直接解决数据库单点和可重入问题。
2:排他锁长时间不提交,会占用数据库连接,一旦类似的连接变得多了,可能把数据库连接池撑爆

基于缓存(redis)实现分布式锁

是集群部署,可以解决单点问题。如Redis,memcached。

原理:
1:多进程可见:多进程可见,否则就无法实现分布式效果;
2:互斥(排它):同一时刻,只能有一个进程获得锁,执行任务后释放锁;
3:可重入(可选):同一个任务再次回去改锁不会被死锁(嵌套锁);
4:阻塞锁(可选):效率高,应对高并发场景;
5:高可用(可选):避免锁服务宕机或处理好宕机的补救措施;

弊端
1:这把锁没有失效时间,一旦解锁失败,会导致所记录一直存在表中,其他线程无法获得该锁。
2:这把锁是非阻塞的,无论失败还是成功都直接返回。
3:这把锁是非重入的,一个线程获得锁之后,在释放锁之前,无法再次获得该锁。

基于zookeeper实现分布式锁
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值