Appearance
分布式锁、ID 与任务调度
分布式系统里,很多问题不会直接以“大理论”的形式出现,而是会在工程里变成很具体的问号:
- 多个节点同时执行同一个任务怎么办
- 多个服务生成 ID 会不会冲突
- 定时任务在集群里会不会重复跑
这些问题看起来分散,但本质上都属于:多个节点同时存在时,如何控制执行权和全局唯一性。
这篇文章重点讲:
- 分布式锁在解决什么问题
- 全局唯一 ID 为什么是分布式问题
- 集群任务调度为什么会重复执行
- 常见方案各有什么优缺点
- 工程上最容易踩的坑是什么
1. 为什么单机里不是问题,到了分布式就变成问题
在单机应用里,很多事情默认就成立:
- 同一进程里加一把锁就够了
- 自增主键天然唯一
- 定时任务只会跑一份
但到了分布式系统,这些前提都没了:
- 有多个进程
- 有多个节点
- 没有天然共享内存
所以原本的本地锁、本地计数器、本地定时任务模型,都会失效。
2. 分布式锁到底在解决什么问题
分布式锁最核心解决的是:在多个节点同时运行时,某个关键动作同一时刻只能由一个节点执行。
例如:
- 只有一个节点执行结算任务
- 只有一个节点修改某个共享状态
- 只有一个请求能抢到某个资源
所以它不是“高级版 synchronized”,而是:跨进程、跨节点的执行权控制。
3. 一个最直观的分布式锁场景
假设有一个“每日对账”任务,系统部署了 4 个实例。
如果每个实例都跑这段逻辑,就会出现:
- 对账任务被重复执行
- 数据重复写入
- 下游接口被重复调用
这时就需要一层机制保证:同一时刻只有一个实例能拿到执行权。
4. 常见分布式锁实现思路有哪些
比较常见的思路包括:
- 基于数据库
- 基于 Redis
- 基于协调服务
4.1 基于数据库
例如利用唯一约束或状态字段控制抢占。
优点是:
- 简单
- 依赖少
缺点是:
- 性能一般
- 扩展性有限
4.2 基于 Redis
这是企业里非常常见的方案。
核心思路通常是:用原子命令抢锁,并设置过期时间。
例如:
java
RLock lock = redissonClient.getLock("settlement:task");
if (lock.tryLock()) {
try {
runSettlement();
} finally {
lock.unlock();
}
}4.3 基于协调服务
例如依赖专门的协调组件来控制节点执行权。
这类方案通常更偏:治理能力更强,但使用和运维也更重。
5. 分布式锁最容易被误解的地方是什么
最容易被误解的是:拿到锁就万事大吉。
实际上要注意的是:
- 锁会不会提前过期
- 解锁会不会误删别人的锁
- 业务执行时间超过锁有效期怎么办
- 锁失败时业务怎么降级
所以分布式锁真正难的,从来不是“加锁成功”,而是:边界条件和失败恢复。
6. 全局唯一 ID 为什么属于分布式问题
因为多个节点同时写数据时,本地自增 ID 通常不再适合作为全局唯一标识。
系统往往会需要:
- 全局唯一
- 尽量趋势递增
- 生成速度快
- 不强依赖单点
这时就会引出全局 ID 方案。
7. 常见全局 ID 方案有哪些
7.1 数据库自增
最简单,但更偏单点能力。
7.2 UUID
优点是生成简单、冲突概率低。
缺点是:
- 太长
- 不利于索引局部性
- 可读性差
7.3 雪花算法
这是企业里很常见的一类方案。
核心思路通常是:把时间、机器标识和序列号拼成一个全局唯一 ID。
它的优点是:
- 生成快
- 趋势递增
- 适合高并发生成
8. 任务调度为什么也会变成分布式问题
单机里的定时任务很简单:到时间就执行。
但在集群里,如果每个节点都按同一时间触发,就会出现:
- 同一任务被重复执行
- 重复发消息
- 重复写库
所以分布式任务调度真正要解决的是:谁来执行、什么时候执行、失败后怎么补偿。
9. 常见分布式任务调度思路有哪些
9.1 抢锁执行
多个节点同时竞争执行权,抢到锁的节点执行。
9.2 中心化调度平台
由一个专门调度平台统一分发任务。
9.3 分片调度
任务本身被拆成多个片段,由多个节点协同处理。
这几类方案的核心差别在于:到底是只需要“避免重复执行”,还是需要“统一调度和任务编排”。
10. 工程里常见的代码示意
例如一个简单的集群定时任务,可以这样表达执行权控制思路:
java
@Scheduled(cron = "0 0/5 * * * ?")
public void syncData() {
if (!tryAcquireTaskLock()) {
return;
}
try {
doSync();
} finally {
releaseTaskLock();
}
}这个示意最重要的点不是具体 API,而是:集群任务不能只看定时表达式,还要看执行权控制。
11. 分布式锁、ID 和调度为什么适合放在一起讲
因为这三类能力最终都在处理类似的问题:
- 多节点并发存在
- 需要全局控制
- 需要避免冲突或重复
也就是说,它们共同回答的是:当系统不再是单机时,执行权、唯一性和调度秩序怎么建立。
12. 工程上最容易踩的几个坑
12.1 误区一:本地锁搬到分布式里就还是锁
不是。
本地锁只在同一进程内有效。
12.2 误区二:有过期时间的锁就一定安全
不一定。
业务时间过长、时钟问题、误删锁等都可能出问题。
12.3 误区三:任务只要定时触发就不会重复
集群里如果没有执行权控制,重复执行几乎是默认结果。
12.4 误区四:全局唯一 ID 只要不重复就行
实际还要考虑长度、趋势递增、索引友好性和高并发生成性能。
13. 一句话总结
分布式锁、全局 ID 和任务调度这条线,本质上是在为多节点系统建立执行权控制、全局唯一性和调度秩序;而工程里真正的难点,不是“找到一种实现”,而是把过期、重试、幂等、补偿和性能边界一起考虑进去。