redis分布式锁的原理与实现【分布式】

文章介绍了分布式锁的概念,包括其原理和应用场景,如电商秒杀防止超卖。重点讲解了基于Redis实现分布式锁的方式,通过SETNX命令保证原子性,并讨论了可能出现的死锁、锁不住及删除他人锁的问题。解决方案包括设置锁超时、使用唯一标识以及Redisson的自动续期机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

一、什么是分布式锁

1、原理

分布式锁是指在分布式系统中,为了实现协调和同步访问共享资源,而对分布式环境下的多个进程或线程进行同步的一种机制。它可以保证在分布式环境下各进程访问共享资源的时序一致性和互斥性,避免不同进程之间发生冲突。
常见的分布式锁实现方式有以下几种:

基于数据库的分布式锁:使用数据库的事务机制来实现分布式锁,通过在数据库插入一个唯一的记录来实现锁定,其他进程尝试并发获取锁时会阻塞等待。

基于缓存的分布式锁:利用缓存服务器来实现锁,比如使用 Redis 的 SETNX 或者 RedLock 算法来实现分布式锁,其中 RedLock 是一种多重锁定方式,能够在不同节点之间避免竞争条件。

基于 ZooKeeper 的分布式锁:使用 ZooKeeper 集群节点来实现分布式锁,ZooKeeper 提供了顺序节点以及 watch 机制来帮助实现分布式锁的获取和释放

2、场景

举个例子来说明分布式锁的应用场景:假设某个电商网站的秒杀活动每天只有固定的5000件特价商品,多个用户同时尝试秒杀商品时会引发超卖问题,需要使用分布式锁来解决。在多个用户尝试秒杀特价商品时,他们所在的应用进程都要向 Redis 缓存服务请求获取锁,只有一个请求可以成功获取到锁并执行秒杀操作,其他请求则会被阻塞。在执行完秒杀操作后,该进程会释放锁,使得其他请求可以获取锁并继续秒杀操作,从而避免了超卖问题的发生。这种场景下,分布式锁能够保证秒杀操作的互斥性和时序一致性,保障秒杀活动的公正性。

二、redis实现分布式锁

1、redis实现分布式锁原理

由于 Redis 是单线程的,可以保证 SETNX 命令与 DEL 命令的原子性操作,因此可以通过 Redis 的 SETNX 命令实现分布式锁。在分布式系统中,要保证同一时间只有一个客户端可以访问某个共享资源,因此需要使用分布式锁来协调各个客户端的访问。Redis 分布式锁实现简单、灵活,只需要使用 SETNX 命令设置锁,并设置有效期即可,无需复杂的代码实现。redis 支持的编程语言非常多,比如 Python、Java、Go、PHP 等,这就意味着可以在不同语言的应用程序中使用同样的锁来管理共享资源,从而避免了不同编程语言之间的锁管理差异性问题。

2、Lock函数的实现

通过 Redis 的 SET 命令设置了一个锁。获取 Redis 分布式锁时采用了一个基于协程和 select 的非阻塞性等待方式
具体步骤如下:
1、获取 Redis 连接池中的一个连接 conn。
2、使用 channel ch 和超时通道 timeoutCh 进行非阻塞性等待获取锁。
3、将要获取锁的操作放在一个协程中执行(即 go func(){}()),用于不断地轮询 Redis,尝试获取锁。
4、通过 select 监听 ch 和 timeoutCh 两个 channel 上的数据。
5、如果 ch 上有数据(即成功获取到锁),则返回 true。
6、如果 timeoutCh 上有数据(即超时),则记录日志并返回 false。
在上面获取锁的步骤中:
SET 命令用于设置 Redis 键值对。lockKey 是锁的键名,前缀"lock:"是为了与其他键进行区分。
“1” 是锁的值,可以是任意值,只要保证不与其他进程的值冲突即可。
“NX” 表示只在键不存在时才执行设置操作。
“EX 10” 表示设置键的过期时间为10秒,这样即使持有锁的进程崩溃或异常退出,其它进程也能够及时再次获取锁。
该函数采用了 Redis 的 SET 命令中的 NX(Not eXists)选项,只有当键不存在时才执行设置操作。这样保证了多个进程之间只有一个能够成功地获取到这个锁,即“抢到锁的进程会关闭 锁通道并停止运行,因为已经获得了锁。其余等待的进程会在锁超时或者释放锁的时候后继续执行,并再次尝试获取锁。

// 加锁封装函数
func (m *UserModel) lock(key string, timeout time.Duration) bool<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值