锁:是一种用来解决多个执行线程访问共享资源错误或数据不一致问题的工具。
- 本质:同一时间只允许一个用户操作
- 场景
- 避免不同节点重复相同的工作
- 避免破坏数据的正确性
- 实现
- 基于 MySQL 中的锁::MySQL 本身有自带的悲观锁 for update关键字,也可以自己实现悲观/乐观锁来达到目的,要关注锁超时、加事务,瓶颈在于数据库;
- 基于 Zookeeper 有序节点:Zookeeper 允许临时创建有序的子节点,这样客户端获取节点列表时,就能够当前子节点列表中的序号判断是否能够获得锁
- 基于 Redis 的单线程:由于 Redis 是单线程,所以命令会以串行的方式执行,并且本身提供了像 SETNX(set if not exists) 这样的指令,本身具有互斥性
- redis锁问题
- 锁超时
- 如果在加锁和释放锁之间的逻辑执行得太长,以至于超出了锁的超时限制
- 解决方案
- Redis 分布式锁不要用于较长时间的任务
- 一般只有少量的情况会发生,通过人工修数便可
- redisson可以使用看门狗,过期时间续期
- redLock(红锁)
- 锁超时
题外话:GC (STW-Stop The World)可能引发锁安全问题,
- zookeeper加锁及获取锁过程(详见zookeeper)
- 创建一个锁节点下的一个接一个的临时顺序节点
- 如果不是第一个节点,就对上一个节点加监听器
- 只要上一个节点释放锁,就排到前面去了,相当于是一个排队机制