一、基于数据库实现分布式锁
就悲观锁,for update行锁
乐观锁,性能更好,再更新时间才会校验版本号/时间戳之类的
二、说到redis分布式锁,我们就想到setNx+lua脚本,意思就是在高并发情况下,大量请求肯定不能让他同时操作业务,保证接口幂等性等原因,我们需要先获取锁才能执行业务,setNx就是先看key存在不,存在就拿不到锁,不存在就插入获取到就是,然后我就能执行业务,其它的到队列中等待
重要是要设置过期时间,以及执行业务完成要解锁,否则如果进程挂了,你锁还一直锁着
三、zookeeper的能做到分布式锁,本来是用于服务发现和注册中心,类似redis一样,利用注册信息不能重复的特点,也可以做到分布式锁,性能没有redis好,业务写操作都要在主结点上执行,然后同步到从结点,主从架构,所以用的少。
四、但是上面这个redis分布式锁他其实只是单实例的分布式锁,正常我们redis都是多实例集群的
redis主从复制的架构,即使有哨兵模式,如果a线程向redis主结点获取锁,拿到后,主结点会向从节点同步数据,但是主节点不知名原因宕机了,导致从节点没有锁数据,我们哨兵模式会从多个从节点中选举一个作为主,好,b线程来了,他居然拿到锁了。
我们高并发架构要求的不就是能在99.9999%后面的情况下都能正常使用才叫高可用嘛
所以又有了一个新的redis分布式锁的算法,红锁,redlock
实现步骤和思想是这样:
1、假设有N个redis的主节点,这些节点互相不是主从架构,也没有集群协从机制,假设n=5,然后要向5个节点都请求加锁
2、我们锁超时时间=30秒,如果其中有N/2+1=3个节点都加锁成功,每个都要1s,如果>=3个节点都加锁成功,并且加起来的加锁时间3s要小于超时时间30s,那我们就算加锁成功了,这个时候实际超时时间只有30-3=27s了
3、如果加锁<3或者超过了过期时间,那就算加锁,我们需要将所有结点的锁都删除。
第一次知道这个redlock的机制,让我感觉很惊讶,因为我有点高可用架构师什么意思,就是大多数情况都考虑到99.99%,这是正常的,但是高可用要让我们考虑到后面的小数点的情况。