Redis作为分布式锁

为什么需要使用分布式锁?

因为在一个分布式系统中,存在多个进程,多个进程之间也存在访问同一个公共资源的情况,多个进程之间的执行顺序是随机性的,此时就需要通过"锁"来达到互斥控制。

比如买票的时候:

此时我们就可以引入redis作为分布式锁

在redis中设置一个特殊的key-value,完成上述买票操作,再把key-value删除,其他服务器在也想买票的时候,就需要尝试设置key-value,如果发现key-value已经存在,就认定为加锁失败(放弃/等待)。执行完之后再删除对应的key,完成解锁操作。

什么是分布式锁

所谓的分布式锁,也是一个/一组单独的服务器程序,提供"加锁"这样的服务。(redis是一种典型的可以用来实现分布式锁的方案,但不是唯一一种,业界可能也会使用mysql/zookeeper这样的组件来实现分布式锁的效果)。

刚才买票的场景,使用mysql的事务也可以批量执行 查询+修改操作,但是分布式系统中,要访问的共享资源不一定是mysql...也可能是执行一段特定的操作,是通过统一的服务器完成执行动作。

引入过期时间

对于上述的设置key-value的方法,如果服务器在执行del突然服务器宕机了,就会出现无法皆所得情况。此时就可以对用来加锁的key设置过期时间,防止服务器宕机无法解锁。

比如使用 set ex nx 命令

引入校验id

上面设置的key-value,服务器1设置了key之后,其他服务器也可以进行删除,为了解决这个问题,我们引入校验id,比如把value设置为服务器的编号,这样其他服务器在获取到value之后,就可以根据value进行判断是不是自己设置的key。

引出lua脚本

此时虽然看上去没有什么问题,但是此时如果有另外一个服务器,在线程1删除之后设置了key,此时线程2再进行删除,就会导致这个另外的服务器的加锁被错误的解锁。

归根到底还是GET和DEL操作不原子的所引起的。

使用事务,能解决上述的问题(redis的事务虽然弱,但是能保证避免插队)

但是实践中往往使用更好的方案,lua脚本

lua是一个编程语言,作为redis内嵌语言,特别轻量,可以使用lua编写一些逻辑,把这个脚本上传到redis服务器上,然后让客户端来控制redi执行上述脚本,也是原子的,相当于一条命令一样

引出看门狗

在加锁的时候给key设置多久的过期时间比较合适呢?

如果设置的短,就可能在你的业务逻辑还没执行完,就释放锁了。

如果设置的太长,就会导致"锁释放的不及时"的问题

更好的办法是"动态续约"。(往往也需要一个服务器单独的线程负责续约这个事情)

比如:初始条件下,设置一个过期时间(比如设置1s)就提前在还剩下300ms(还剩下一段时间,不一定是300ms)的时候,如果当前任务还没执行完,就把过期时间再续上1s.等到时间又快到了,如果没执行完,再续....

如果服务器中途崩溃了,自然就没人负责续约了,此时,锁也就能够在较短的时间里释放了。

引出Redlock算法

使用redis作为分布式锁,redis自身也是有可能挂的,所以必需要保证redis本身的高可用性

redis可以使用集群(主要是解决内存问题)或者哨兵的方式保证高可用性

但是主节点和从节点之间的数据同步是存在延时的,可能主节点收到set请求之后,还没来得及给从节点同步,主节点就挂了,就会导致这次set的数据丢失。

redlock算法(作者给出的一个解决方案) 通过存放冗余的数据来保证数据不丢失

此处加锁,就是按照一定的顺序,针对这些组redis都进行加锁,如果某个节点挂了,继续给下一个节点加锁即可,如果写入key成功的节点个数超过总数的一半,就视为加锁成功。同时解锁也是相同的操作

上述介绍的只是一个简单的"互斥锁"

redis也是可以实现以下这些锁的

1.读写锁

2.公平锁

3.可重入锁

相关推荐
不剪发的Tony老师12 分钟前
SQL Schema Compare:一款免费开源的数据库结构比较和同步工具
数据库
铁锹少年15 分钟前
当多进程遇上异步:一次 Celery 与 Async SQLAlchemy 的边界冲突
分布式·后端·python·架构·fastapi
寒秋丶23 分钟前
Milvus:集合(Collections)操作详解(三)
数据库·人工智能·python·ai·ai编程·milvus·向量数据库
寒秋丶25 分钟前
Milvus:Schema详解(四)
数据库·人工智能·python·ai·ai编程·milvus·向量数据库
kyle~36 分钟前
CPU调度---协程
java·linux·服务器·数据库·c++20
IDOlaoluo36 分钟前
SQL Server 2017 Developer 中文版安装教程(64位 ISO 文件详细步骤)
服务器·数据库·负载均衡
大千AI助手1 小时前
分布式奇异值分解(SVD)详解
人工智能·分布式·spark·奇异值分解·svd·矩阵分解·分布式svd
明达智控技术1 小时前
MR30分布式IO在自动上料机的应用
分布式·物联网·自动化
亿牛云爬虫专家1 小时前
用 Playwright + 容器化做分布式浏览器栈:调度、会话管理与资源回收
分布式·docker·容器·浏览器·爬虫代理·新闻网站·playwright
yours_Gabriel2 小时前
【分布式事务】Seata分布式解决方案
java·分布式·微服务