分布式锁

一、什么是分布式锁?

  锁是实现多线程同时访问同一共享资源,保证同一时刻只有一个线程可访问共享资源所做的一种标记。分布式锁是在分布式环境下,系统部署在不同机器、集群,实现多进程争夺共享资源的标记。为了保证多个进程能看到锁,锁被存在公共存储(比如 Redis、Memcache、数据库等三方存储中),以实现多个进程并发访问同一个临界资源,同一时刻只有一个进程可访问共享资源,确保数据的一致性。

二、分布式锁的实现方式

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

  基于数据库实现分布式锁,主要是通过在数据库建立一张锁表,当我们要锁住某个资源时,就在该表中增加一条记录,想要释放锁的时候就删除这条记录。数据库对共享资源做了唯一性约束,如果有多个请求被同时提交到数据库的话,数据库会保证只有一个操作可以成功,操作成功的那个线程就获得了访问共享资源的锁,可以进行操作。

  实现方式:每次请求可以在数据库表中插入一条同样的数据,请求处理完,删除这条记录。同时,在数据库表中添加唯一索引,保证这条记录唯一,如果多条数据同时请求,只有一条成功,其他的会因为唯一键冲突导致插入失败。

总结:

  • 由于每次请求都需要落库,所以性能较差
  • 如果数据库故障,会导致整个系统不可用
  • 死锁问题:如果数据库锁一直未得到释放,未获得锁的进程只能一直等待已获得锁的进程主动释放锁。一旦已获得锁的进程挂掉或者解锁操作失败,会导致锁记录一直存在数据库中,其他进程无法获得锁。

2、基于缓存实现分布式锁

  由于基于数据库实现分布式锁需要频繁的操作数据库,涉及读写磁盘,性能较低,于是就出现了基于缓存的分布式锁。所谓基于缓存,也就是说把数据存放在计算机内存中,不需要写入磁盘,减少了 IO 读写。

  Redis 通常可以使用 setnx(key, value) 函数来实现分布式锁。key 和 value 就是基于缓存的分布式锁的两个属性,其中 key 表示锁 id,value = currentTime + timeOut,表示当前时间 + 超时时间。也就是说,某个进程获得 key 这把锁后,如果在 value 的时间内未释放锁,系统就会主动释放锁。

相对于基于数据库实现分布式锁的方案来说,基于缓存实现的分布式锁的优势表现在以下几个方面:

性能更好。数据被存放在内存,而不是磁盘,避免了频繁的 IO 操作。
避免单点故障。很多缓存可以跨集群部署,避免了单点故障问题。
可设置超时时间。很多缓存服务都提供了可以用来实现分布式锁的方法,比如 Redis 的 setnx 方法等。可以直接设置超时时间来控制锁的释放,因为这些缓存服务器一般支持自动删除过期数据。

  这个方案的不足是,通过超时时间来控制锁的失效时间,并不是十分靠谱,因为一个进程执行时间可能比较长,或受系统进程做内存回收等影响,导致时间超时,从而不正确地释放了锁。

3、基于 ZooKeeper 实现分布式锁

参考引用中博客

引用:极客时间读书笔记
https://blog.csdn.net/crazymakercircle/article/details/85956246

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值