分布式锁
2021-09-17 09:07:18 8 举报
简单的分布式锁描述
作者其他创作
大纲/内容
分布式锁的几种实现方案:1. 基于mysql 的互斥性。 基本做法,新建数据库一张lock表,在开始具体业务前,往lock表中插入一条数据。如果插入成功,则表示获取锁成功,插入失败则获取失败。在进行具体的业务操作完成后,将lock表中的数据删除。(可能出现死锁问题)2. redis 一般是使用 set key value nx expire expire time 来实现分布式锁,如果set 值成功,则表示已经获取锁。失败则没有获取锁。 3. zookeeper 利用zookeeper 临时节点的特性。 创建节点成功则表示获取锁,失败则没有获取锁。业务逻辑完成后删除该节点。
https://juejin.cn/post/7005487404500910116/
3.验证库存是否充足
2.查询库存还有30
通过观察上面的流程图,我们发现,在并发执行的情况下,就可能出现数据不一致的情况。如上图所示,client2在进行查询操作时,查询到了未更新的DB旧值。如果此时库存服务二根据DB旧值去进行更新,那么就导致了数据的错误。
库存服务一
可能出现的问题。 1. 性能问题。 因为使用了锁技术,导致所有的服务必须进行线性的等待,必须等锁释放后才能尝试去获取锁。2.如果采用redis 做分布式锁,如果业务还没有执行完毕,key的过期时间到了。此时就会释放锁。导致另一个服务也获取到了锁。3.同样是采用redis,如果redis 的master获取到锁后,未来得及同步到slave时就已经挂了,而新选举出来的master则无法感知到旧master的状态。也就导致了锁丢失的问题。
否,提示用户库存不足
2.查询库存
是,更新数据库库存进行-20操作此时数据库库存剩余10
client-2
key过期解决方案在redis 的redisson中,使用了一种名为watchdog 的技术方案具体思路如下。 在使用某个key 进行分布式锁时,会重新另外开启一个线程。扫描key 是否快要过期。如果快要过期。就给这个key进行延时操作。
库存服务2
master宕机导致的数据不一致解决方案redlock: 思路: 1.客户端先获取「当前时间戳 T1」2.客户端依次向这 5 个 Redis 实例发起加锁请求(用前面讲到的 SET 命令),并设置超时时间(毫秒级),如果某一个实例加锁失败(包括网络超时、锁被其它人持有等各种异常情况),就立即向下一个 Redis 实例申请加锁3.如果客户端从 >=3 个(大多数)以上 Redis 实例加锁成功,则再次获取「当前时间戳 T2」,如果锁的租期 > T2 - T1 ,此时,认为客户端加锁成功,否则认为加锁失败4.加锁成功,去操作共享资源5.加锁失败或操作结束,向「全部节点」发起释放锁请求(前面讲到的 Lua 脚本释放锁)
1.发起购买20个商品请求
为了避免这种情况的发生,我们往往需要将库存服务一中,查询库存和验证库存两个动作都进行锁定,保证在服务一进行操作的同时,库存服务二不会进行操作。这样就保障服务二不会出现查询到脏数据的问题。由于这是两个单独的服务,互不干扰,因此我们就需要借助第三方来进行锁定操作。也就是分布式锁。
DB
redis 分布式锁和zookeeper分布式锁的区别?redis 性能好 zookeeper 由于采用CAP采用强一致性,需要向所有节点发送创建和删除信息。导致性能远远不如redis.
client-1
性能问题解决方案可以采用锁分段的方法,可以参考java中的concurrentHashMap。 思路: 例如库存为1000,那么我们可以将库存划分为200库存为一把锁。那么此时性能理论上就可以提高为原来的5倍了。 注意点:如果获取了当前锁,发现库存不够。那么必须去获取下一把锁。直到获取到所有锁。 (可能出现死锁的)。因此需要超时机制。
0 条评论
下一页