分布式锁
1. 锁
有限资源的情况下,控制同一时间(段)只有某些线程(用户 / 服务器)能访问到资源。
Java 实现锁:synchronized 关键字、并发包的类
问题:只对单个 JVM 有效
2. 分布式锁
为啥需要分布式锁?
- 有限资源的情况下,控制同一时间( 段)只有某些线程(用户 / 服务器)能访问到资源。
- 单个锁只对单个 JVM 有效
3. 分布式锁实现的关键
抢锁机制:
怎么保证同一时间只有1个服务器能抢到锁?
核心思想:
先来的人先把数据改成自己的标识(服务器 ip),后来的人发现标识已存在,就抢锁失败,继续等待。
等先来的人执行方法结束,把标识清空,其他的人继续抢锁。
MySQL 数据库:select for update 行级锁(最简单)(乐观锁)
✔ Redis 实现:内存数据库,读写速度快 。支持 setnx、lua 脚本,比较方便我们实现分布式锁。
setnx:set if not exists 如果不存在,则设置;只有设置成功才会返回 true,否则返回 false。
4. 使用锁的注意事项
- 用完锁要释放
- 锁一定要加过期时间
- 如果方法执行时间过长,锁提前过期了?
- 连锁效应: 释放掉别人的锁
- 这样还是会存在多个方法同时执行的情况
解决方案: 续期机制!
``
boolean end = false;
new Thread(() -> {
if (!end)}{
续期
})
end = true;
问题:
- 释放锁的时候,可能出现一种情况,先判断出是自己的锁,但这时锁过期了,最后还是释放了别人的锁
- Redis如果是集群,并非单机Redis时候,如果出现分布式锁的数据不同怎么办?(多个redis里面的锁不同怎么办?)
// 原子操作
if(get lock == A) {
// set lock B
del lock
}
Redis + lua 脚本实现
[https://blog.csdn.net/feiying0canglang/article/details/113258494](https://blog.csdn.net/feiying0canglang/article/details/113258494)
标签:end,抢锁,实现,lock,及其,Redis,服务器,分布式
From: https://www.cnblogs.com/techgy/p/17538863.html