Redis分布式锁
首先我们意识里要知道分布锁有哪些?
分布式锁一般分三种:
基于数据库的乐观锁,
基于redis的分布式锁,
基于zookeper的分布式锁
本文只讲基于reids的分布式锁。
为什么要用分布式锁?
在传统单体应用单机部署的情况下,并发问题可以通过使用Java并发相关的锁如synchronized,但是当规模上升到分布式集群的情况下,要控制共享资源访问,就需要通过分布式锁来实现。
当应用进行了分布式部署,应用有多个服务,这个时候应用服务端就没有一个可提供原子性操作的地方了,Redis性能高,且是单线程,因此可提供一个原子性操作的地方
redis分布式锁的底层原理?
Redis分布式锁可以有多种方式实现但是其核心就是通过以下三个Redis命令组合实现。
-
SETNX SETNX key val 当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。
-
Expire expire key timeout 为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。
-
Delete delete key 删除key
核心思想
-
使用setnx获取锁。如果成功取到锁,则使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁。
-
获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
客户端1和客户端2同时持有了同一个资源的锁,锁不再具有安全性。根本原因是Redis集群不是强?致性的。
那么怎么保证强?致性呢—Redlock算法;
假设客户端1从Master获取了锁。 这时候Master宕机了,存储锁的key还没有来得及同步到Slave上。 Slave升级为Master。
客户端2从新的Master获取到了对应同一个资源的锁;
直白点说,就是采用N(通常是5)个独立的redis节点,同时setnx,如果多数节点成功,就拿到了锁,这样就可以允许少数(2)个节点挂掉了。整个取锁、释放锁的操作和单节点类似。