如何使用Redis实现分布式锁
我是哑巴
嗯,每当我们在本地系统中工作时,一切都像黄油一样工作。这就是为什么我们称“没有比 127.0.0.1 更好的地方了”,但醒来面对现实
生产中的事情并不总是按预期进行。大多数情况下,当您运行应用程序的多个实例时。
?正如您所看到的,如果我们的应用程序的多个实例正在运行,并且假设我们的客户端发出请求,将用户标记为数据库中的付费用户。
- 客户端将请求我们的服务器
- 请求将到达我们的负载均衡器
- 其中一个实例将收到请求并向我们的数据库发出写入查询
看起来还不错吧?到目前为止没问题吧。
嗯,是的,到目前为止没有问题。但是如果我们想编写这样的业务逻辑怎么办:-
- 从数据库中获取用户
- 检查用户是否是免费用户或已付费
- 如果免费,则将其标记为付费并保存在数据库中
- 如果已付款,请在回复中发送“已付款”。
⚡️ 众所周知(假设我们在这里使用 MySQL)MySQL 数据库符合 ACID,这意味着任何查询都将是原子的和隔离的。这意味着 MySQL 查询将以原子方式运行,要么通过,要么失败。但中间不会退出。
?但这里有一个问题。想想,想想……
- 第 1 步:我们正在获取用户(原子事务)
- 第 2 步:在代码中运行一些业务逻辑
- 第3步:如果用户未付款则更新MySQL记录(原子交易)
如果在第 2 步,又有一个取消付款的请求,然后该查询首先运行并将用户标记为免费,然后运行第 3 步并将用户标记为已付费,将会发生什么情况。
??万岁,用户甚至无需付费即可访问我们的产品。
锁定
✅救星Locks来了
?锁是一种结构,一次只允许一个线程进入临界区(不应被多个工作线程访问的代码块)
因此,我们将在操作完成之前获取锁定并在操作完成后释放:-
- 第0步:尝试获取()锁
- 第 1 步:如果获取,我们将获取用户(原子事务)
- 第 2 步:在代码中运行一些业务逻辑
- 第3步:如果用户未付款则更新MySQL记录(原子事务)
- 第四步:release() 锁
?问题
现在,问题来了,如果我们使用一些内存锁数据结构或任何基于内存的锁,它将适合我们的应用程序的一个实例。其他运行相同代码并在数据库中更新的实例怎么样?
分布式锁的概念来了
?分布式锁
这里的锁充当一种集中式服务,如果我们服务的一个实例获取了锁,那么其他实例就无法使用同一个密钥。
支付服务中可以使用什么键?
?对于进行付款的用户,密钥可以是=“PAYMENT_”+ user_id + amount
的组合这对于每个用户来说都是唯一的。并且当用户付款或取消付款时,该密钥将保持不变。因此,当一个操作发生时,其他操作无法继续,因为这两个操作将尝试获取同一键。
? Key、获取锁、释放锁到底是什么?最重要的是,redis 是如何使用的?
?使用Redis实现分布式锁
使用 Redis 的单个实例:-
但是单个 Redis 实例存在以下几个问题:-
- 单个实例可能会失败并且获取的锁可能无法释放
- 如果使用两个实例(主副本),则一个客户端将获取一个实例上的锁
- 主服务器必须与副本进行相同的通信才能同步。这种通信本身就是异步通信
?因此,如果在主服务器上获取了锁,并且在与副本通信时,如果主服务器在与副本同步之前发生故障。副本将成为主服务器,其中同一密钥上的锁将可用于获取之前在主服务器上获取的锁。
即使有两个实例(主副本),我们服务的两个实例也将能够获取 Redis 上的锁。
使用 Redlock 算法:-
获取锁:- 我们将尝试在具有锁过期时间的多个 Redis 实例上获取锁
锁验证:- 如果主要 Redis 实例为客户端获取了锁,则将被视为已获取锁
释放锁:- 释放锁时,所有实例都释放锁
是的,就是这样。
❤️ 感谢您的阅读,并订阅我们的时事通讯以获取更多此类文章:- https://www.serversidedigest.com/
欲了解更多信息:-
- Java 中的 Jedis:- https://redis.io/docs/latest/develop/connect/clients/java/jedis/
- Golang 中的 Redis 客户端:- https://github.com/redis/go-redis
以上是如何使用Redis实现分布式锁的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

公司安全软件导致部分应用无法正常运行的排查与解决方法许多公司为了保障内部网络安全,会部署安全软件。...

将姓名转换为数字以实现排序的解决方案在许多应用场景中,用户可能需要在群组中进行排序,尤其是在一个用...

系统对接中的字段映射处理在进行系统对接时,常常会遇到一个棘手的问题:如何将A系统的接口字段有效地映�...

在使用MyBatis-Plus或其他ORM框架进行数据库操作时,经常需要根据实体类的属性名构造查询条件。如果每次都手动...

在使用IntelliJIDEAUltimate版本启动Spring...

Java对象与数组的转换:深入探讨强制类型转换的风险与正确方法很多Java初学者会遇到将一个对象转换成数组的�...

Redis缓存方案如何实现产品排行榜列表的需求?在开发过程中,我们常常需要处理排行榜的需求,例如展示一个�...

电商平台SKU和SPU表设计详解本文将探讨电商平台中SKU和SPU的数据库设计问题,特别是如何处理用户自定义销售属...
