分布式锁概念
解决分布式服务下,多线程环境对同一份资源竞争的数据安全性,分布式锁是用于确保整个集群内的多线程并发线程安全性的一种手法
分布式锁特征
高性能、可重入、防死锁和互斥性
-
高性能:最求高QPS
-
可重入:当一次请求的代码中包括两个锁时,并且递归调用两个锁时,要确保可重入,否则会呈现死锁 ,重入几次就要开释几次
public synchronized void test1() {
// 堵塞卡死了
test2();
}
public synchronized void test2() {
test1()
}
-
防死锁 除上面的情况下,假如加锁后服务器宕机,锁不开释也会发生死锁
-
互斥性
完成分布式锁的方法
- Mysql 性能低下,经过insert时的仅有索引完成
- redis 可以经过setNx办法完成,这个是最简略的分布式锁,比如履行一个办法时,加一个锁,且不设置过期时刻,或许设置一个很大的过期时刻,可是有弊端,关于业务量不高也可以运用 另外一种就是运用redission结构,这个安全性更高
- zookeeper 该锁最安全,可是本钱有点大,由于还要引入zookeeper
运用场景
- 确保接口的幂等,防止重复提交,这个时很高频的运用
- 分布式的使命调度,分布式的体系或许多个履行器履行定时使命,防止使命重复履行,运用分布式锁,这个在我履行完成的使命调度中也运用过
- 防止超卖的情况 这个实践工作中我也遇到过,做过抢单业务都会遇到此种情况
运用redis完成分布式锁特性
- 原子性 由于redis的设置分布式锁,需要两个指令
- 设置key value
- 设置过期时刻 即便运用setNx办法,底层也是两个指令 setNX item-4 111 set item-4 111 EX 20 假如第一个指令履行成功了,第二个失利了,那么就没有了过期时刻,照成死锁,就不具备原子性,要么都成功,要么都失利,所以要经过运用lua脚本来解决
-
过期时刻 上面说了,没有过期时刻或许会呈现死锁的情况
-
锁续期 假如一个业务锁到了过期时刻可是业务没有履行完,就会形成锁失效,没有锁住,这部分的解决方案就是经过watchdog来完成
-
正确开释锁 A上的锁被B开释了,这样就会形成过错开释锁,原因是A与B的key值是相同的,所以要注意key值
运用redis完成分布式锁的部署方法
- 单机 简略,可是风险大
- 哨兵 主从 假如mater挂掉,又没同步到slave会导致,锁丢失
- 集群 虽然是集群可是,也是部署在集群中其中一台机器上,挂掉就没了
- 红锁 全都是master,可是性能低,本钱高
redission完成分布式锁
加锁
watchdog锁续期