这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
任务调度
分布式调度挑战
在分布式环境下,多个调度器如何协调工作?
核心问题
分布式调度的核心问题:
1. 任务如何分配?
├─ 按任务 ID 分片
├─ 按队列分片
└─ 按消费者分片
2. 如何避免重复执行?
├─ 分布式锁
├─ Lua 脚本原子操作
└─ 数据库悲观锁
3. 如何处理故障?
├─ 心跳检测
├─ 主备切换
└─ 任务迁移调度策略
策略 1:分片调度
最直接的做法,是把任务按某个稳定维度切开。比如按任务 ID 取模,或者按业务队列划分。每个调度器只负责自己的分片,这样大家不会扫描同一批任务。
分片调度的好处是简单、可预测。调度器数量固定时,任务归属也很稳定。但它也有代价:如果某个分片任务特别多,其他分片很空,系统就会出现局部热点。
当前架构
分布式调度
多台调度器同时工作时,重点是分片、互斥、故障接管和重复执行控制。
调度集群
分片规则
领导者选举
心跳
互斥控制
任务锁
租约
幂等键
故障恢复
超时释放
任务迁移
补偿扫描
策略 2:动态分片
动态分片解决的是负载不均的问题。调度器定期上报心跳和处理能力,系统根据当前任务量重新分配分片。任务多的分片可以拆给更多调度器,任务少的分片可以合并。
这种方案更灵活,但需要额外维护“谁负责哪一段任务”的元数据。只要分配表出错,就可能出现无人调度或重复调度。因此动态分片一定要配合租约、版本号和心跳过期机制。
策略 3:主调度器 + 工作调度器
还有一种折中方案:由一个主调度器负责分配任务范围,多个工作调度器负责实际扫描和投递。主调度器不处理业务,只管理分工;工作调度器不争全局,只处理自己拿到的范围。
这个方案适合中等规模系统。它比静态分片更灵活,又比完全动态分片更容易理解。风险在于主调度器本身要高可用,所以必须支持主备切换。
读者要记住什么
分布式调度不是为了显得复杂,而是为了让系统在多台机器上仍然保持三件事:任务有人处理、任务不会被多人同时处理、某台机器挂了以后任务还能继续走。只要这三件事没有被证明,调度方案就还不完整。