目录
一、引言
本篇文章将介绍Redis的最后最后一个章节,分布式锁的介绍。
二、介绍
分布式锁主要用于锁进程,而非线程。所谓分布式锁也就是一个/一组单独的服务器程序,给其他的服务器提供“加锁”这样的服务,实现方式有多种,这里主要介绍Redis。
1.如何进行加锁
往redis上设置一个特殊的key-value,完成指定的操作之后,再把这个key-value给删除掉。每次要进行插入这个key的时候就去判断是否存在,不存在就插入,存在就插入失败(阻塞还是放弃取决于具体业务)。
使用setnx这个命令(不存在就插入,存在就不插入)加锁。
使用del这个命令(将这个键值对也删除掉)解锁。
存在问题:如果加锁之后,服务器崩溃了导致没有解锁,该如何处理
2.引入过期时间
给这个key设置一个过期时间 set ex nx这样的命令完成设置(ex指定超时时间),就能够自动地释放这个锁。
3.引入服务器编号
出现异常:一个服务器加锁,另外一个服务器进行了解锁
1.给服务器编号,每个服务器有自己的身份标识
2.进行加锁的时候,设置key-value。key对应着要针对哪个资源加锁,value标识存储的服务器编号
后续解锁的时候,就可以进行校验了,解锁的时候先查询锁对应的服务器编号,判定这个编号是否就是当前执行解锁的服务器编号。如果是才能真正执行del,如果不是就失败
4.引入lua脚本
解锁的时候先查询,再del(不是原子性操作,可能会出现问题),所以引入lua脚本
lua是一个编程语言,作为redis的内嵌脚本。lua语言特别轻量,实现一个lua解释器,消耗的体积是非常小的。redis执行lua脚本的过程是原子的,相当于一条命令,实际上lua脚本内部写了多个命令。
5.引入看门狗
过期时间的续约问题:如果设置的短就可能在你的业务逻辑还没执行完就释放了锁,设置得太长,导致锁释放不及时
更好地方式:动态续约
初始情况下,设置一个过期时间(例如:1s),提前在还剩300ms的时候,如果任务还没执行完,就给过期时间续上1s,等到时间又剩300ms,就继续去检查,然后无限续费。
如果服务器中途崩溃,也没有续约了,锁就会在较短的时间内自动释放。
负责干这个事情的线程就是看门狗。
6.redlock算法
保证redis的高可用,保证任何一个节点挂了都有补救的方法。
存在多组redis,都写入这个key(加锁),如果写入key成功的个数超过总数的一半就视为加锁成功!解锁也是同理,对各组redis都进行解锁
三、总结
redis的学习就到这里结束了,之后博主可能会出关于redis的八股训练,大家尽情期待,感谢观看!