聊聊分布式锁

一、什么是分布式锁?

  1. 先聊下jvm进程中,多线程环境下, 会使用synchronized等锁,保证同一时刻,只有一个线程访问资源
  2. 但分布式环境下,控制多个jvm 进程之间,访问共享资源。需要使用分布式锁。

二、设计原则?

  1. 互斥。同一时刻,只能一个jvm进程的一个线程获取到锁。

  2. 无死锁。客户端崩溃or分区时,不会一直持有锁。(超时机制等实现)

  3. 高性能、高可用

三、实现方案

基于中间件来实现分布式下对共享资源的控制访问

  1. 基于MySQL
  2. 基于Redis
  3. 基于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

缺点:

  1. 行级锁都是基于索引的,如果一条SQL语句用不到索引是不会使用行级锁的,会使用表级锁把整张表锁住

3.1.3 利用唯一性约束

利用唯一性约束,若MySQL插入同一key 会报错:duplicate key。同一时刻只能一个线程获取到锁,执行完成后,删除key即可。

缺点:

  1. db操作耗时,性能差
  2. MySQL宕机,导致获取锁失败,可用性差
  3. 客户端持有锁机器宕机,导致死锁风险。

3.2 基于Redis

  1. redis set nx pt
  2. redission

https://pdai.tech/md/arch/arch-z-lock.html#基于redlock实现分布式锁

3.3 基于zookeeper

todo

posted @ 2025-03-14 16:49  执大象  阅读(21)  评论(0)    收藏  举报