Redis 分布式锁的实现原理

分布式锁相信大家一定不会陌生, 想要用好或者自己写一个却没那么简单

想要达到上述的条件, 一定要 掌握分布式锁的应用场景, 以及分布式锁的不同实现, 不同实现之间有什么区别

二、分布式锁场景

如果想真正了解分布式锁, 需要结合一定场景; 举个例子, 某夕夕上抢购 AirPods Pro 的 100 元优惠券

Redis 分布式锁的实现原理

如果使用下面这段代码当作抢购优惠券的后台程序, 我们一起看一下, 可能存在什么样的问题

Redis 分布式锁的实现原理

很明显的就是这段流程在并发场景下并不安全, 会导致优惠券发放超过预期, 类似电商抢购超卖问题。分布式情况下只能通过分布式锁 来解决多个服务资源共享的问题了

三、分布式锁

分布式锁的定义:

  保证同一时间只能有一个客户端对共享资源进行操作

另外有几点要求也是必须要满足的:

1、不会发生死锁。 即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁

2、具有容错性。 只要大部分的Redis节点正常运行,客户端就可以加锁和解锁

3、解铃还须系铃人。 加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了

分布式锁实现大致分为三种, Redis、Zookeeper、数据库, 文章以 Redis 展开分布式锁的讨论。

四、分布式锁演进史

先来构思下分布式锁实现思路

要求:

首先我们必须保证同一时间只有一个客户端(部署的优惠券服务)操作数量加减。

其次本次客户端操作完成后, 需要让 其它客户端继续执行。

实现:

1、客户端一存放一个标志位, 如果添加成功, 操作减优惠券数量操作

2、客户端二添加标志位失败, 本次减库存操作失败(或继续尝试获取等)

3、客户端一优惠券操作完成后, 需要将标志位释放, 以便其余客户端对库存进行操作

4.1 第一版 setnx

向 Redis 中添加一个 lockKey 锁标志位, 如果添加成功则能够继续向下执行扣减优惠券数量操作, 最后再释放此标志位

Redis 分布式锁的实现原理

由于使用的是 Spring 提供的 Redis 封装的 Start 包, 所有有些命令与 Redis 原生命令不相符

1 setIfAbsent(key, val) -> setnx(key, val)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgwgsy.html