聊聊分布式锁
一、什么是分布式锁?
- 先聊下jvm进程中,多线程环境下, 会使用synchronized等锁,保证同一时刻,只有一个线程访问资源
- 但分布式环境下,控制多个jvm 进程之间,访问共享资源。需要使用分布式锁。
二、设计原则?
-
互斥。同一时刻,只能一个jvm进程的一个线程获取到锁。
-
无死锁。客户端崩溃or分区时,不会一直持有锁。(超时机制等实现)
-
高性能、高可用
三、实现方案
基于中间件来实现分布式下对共享资源的控制访问
- 基于MySQL
- 基于Redis
- 基于zookeeper
3.1 基于MySQL
- 乐观锁(基于版本号)
- 悲观锁(基于排它锁)
- 利用唯一性约束
3.1.1 乐观锁(基于版本号)
若更新失败,回滚整个事务
实现举例:
1.查询出商品信息
select (status,status,version) from t_goods where id=#{id}
2.根据商品信息生成订单
3.修改商品status为2
update t_goods
set status=2,version=version+1
where id=#{id} and version=#{version};
3.1.2 悲观锁(基于排它锁)
利用MySQL中事务提交时,才会释放行锁的特性。
select…for update
缺点:
- 行级锁都是基于索引的,如果一条SQL语句用不到索引是不会使用行级锁的,会使用表级锁把整张表锁住
3.1.3 利用唯一性约束
利用唯一性约束,若MySQL插入同一key 会报错:duplicate key。同一时刻只能一个线程获取到锁,执行完成后,删除key即可。
缺点:
- db操作耗时,性能差
- MySQL宕机,导致获取锁失败,可用性差
- 客户端持有锁机器宕机,导致死锁风险。
3.2 基于Redis
- redis set nx pt
- redission
https://pdai.tech/md/arch/arch-z-lock.html#基于redlock实现分布式锁
3.3 基于zookeeper
todo
本文来自博客园,作者:执大象,转载请注明原文链接:https://www.cnblogs.com/li-junjie/articles/18772398

浙公网安备 33010602011771号