Loading

[05] Redis 分布式锁

1. Redis 分布式锁

Redis 分布式锁实现:使用 Lua 脚本结合使用 SETNX 和 EXPIRE 这两个命令。

1.1 锁续期

业务超时锁释放导致「错误解锁」:

业务超时锁释放导致「业务并发执行」:

Redis 实现分布式锁如何合理的控制锁的有效时长? =>【锁续期/锁续命】

  • 给拿到锁的线程创建一个守护线程 WatchDog(看门狗),守护线程定时/延迟判断拿到锁的线程是否还继续持有锁,如果持有则为其续期。
  • WatchDog 会给持有锁的线程续期(默认是每隔 10s 续期一次)。

1.2 锁重入

如何支持可重入?更换数据类型,采用 hash 类型来实现。

1.3 阻塞锁

如何做一个阻塞锁呢?获取不到就等待锁的释放,直到获取到锁或者等待超时。

  1. 基于客户端轮询的方案
  2. 基于 Redis 的发布/订阅方案

1.4 主从一致性

redisson 实现的分布式锁能解决主从一致性的问题吗?

这个是不能的,比如,当线程1加锁成功后,master 节点数据会异步复制到 slave 节点,此时当前持有 Redis 锁的 master 节点宕机,slave 节点被提升为新的 master 节点,假如现在来了一个线程2,再次加锁,会在新的 master 节点上加锁成功,这个时候就会出现两个节点同时持有一把锁的问题。

我们可以利用 redisson 提供的「红锁」来解决这个问题,它的主要作用是,不能只在一个 Redis 实例上创建锁,应该是在多个 Redis 实例上创建锁,并且要求在大多数 Redis 节点上都成功创建锁,红锁中要求是 Redis 的节点数量要过半。这样就能避免线程1加锁成功后 master 节点宕机导致线程2成功加锁到新的 master 节点上的问题了。

但如果使用了红锁,会因为需要同时在多个节点上都添加锁,性能变的很低,并且运维维护成本也非常高。所以,我们一般在项目中也不会直接使用红锁,并且官方也暂时废弃了这个红锁。

posted @ 2020-09-04 12:47  tree6x7  阅读(111)  评论(0编辑  收藏  举报