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.可重入锁

相关推荐
TDengine (老段)8 小时前
TDengine IDMP 重塑智慧水务运营(内附 Step by Step 步骤)
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
西格电力科技9 小时前
分布式光伏 “四可” 装置:“发电孤岛” 到 “电网友好” 的关键跨越
分布式·科技·机器学习·能源
LSL666_11 小时前
1 概述及简单登录(不涉及数据库)
数据库·servlet
q***064714 小时前
MySQL的UPDATE(更新数据)详解
数据库·mysql
8***B14 小时前
MySQL性能
数据库·mysql
q***721915 小时前
oracle使用PLSQL导出表数据
数据库·oracle
数据库生产实战15 小时前
Oracle DG备库日志切换解析,Private strand flush not complete如何理解?(基础知识)
数据库·oracle
百***757415 小时前
从 SQL 语句到数据库操作
数据库·sql·oracle
i***395815 小时前
SQL 注入详解:原理、危害与防范措施
数据库·sql·oracle
m***567216 小时前
Win10下安装 Redis
数据库·redis·缓存