在 Apache DolphinScheduler 中,当 Master 节点启动时,会从数据库中获取待处理的 Command(工作流命令),并基于 Slot(分片) 策略进行负载分配。该设计旨在提升数据库查询性能,同时支持分布式场景下的高吞吐和低延迟。本文将探讨这种设计的基本逻辑,并重点分析以下两个问题:
- 顺序扫描与间隔扫描的区别,以及由此带来的 Page 分页问题
- Master 数量过多时对查询性能的影响
1. Slot 分片的基本逻辑
1.1 Slot 的定义
- totalSlot:集群中 Master 节点的总数。
- currentSlotIndex:当前 Master 节点对应的分片编号(从
0开始)。
1.2 Command 分配规则
每个 Command 的唯一标识(id)会依据如下公式被分配到特定的 Slot:
分配的 Slot = id % totalSlot
也就是说,每个 Master 节点只处理满足 id % totalSlot == currentSlotIndex 的 Command,从而实现各节点之间的均衡分工和分布式调度。
2. Slot分片带来的数据库查询性能优化
使用Slot主要带来两方面的性能优化,具体如下。
2.1 顺序扫描与间隔扫描的区别及 Page 分页问题
-
聚簇索引与顺序 I/O 优势:
InnoDB 存储引擎采用聚簇索引将数据按照主键(如id)有序存储。对于类似id BETWEEN 1000 AND 2000的连续查询,数据库能够利用顺序 I/O,快速定位起始位置,并连续扫描数据页,从而减少磁盘寻道次数。 -
间隔扫描的随机 I/O 问题:
如果直接使用条件id % totalSlot == currentSlotIndex,则符合条件的 ID 在物理存储上呈间隔分布。例如,在totalSlot=3时,Master 0 需要处理的 ID 为0, 3, 6, 9, …。这种分布会导致:- 随机 I/O:
虽然逻辑上能筛选出正确的记录,但这些记录在磁盘上可能分布在多个不连续的 Page 中,造成多次跨 Page 读取。 - Page 分页问题:
连续扫描时可以充分利用数据页内的顺序结构,而间隔扫描则容易导致每次只读取一条或少量记录,增加了磁盘 I/O 次数和延迟。
- 随机 I/O:
-
优化策略——转换为连续区间查询:
为了克服间隔扫描带来的性能问题,DolphinScheduler 引入了一个查询步长(idStep),将间隔条件转换为一系列连续区间查询:id >= {start_id} AND id < {start_id + idStep} AND id % totalSlot == currentSlotIndex这样,虽然筛选条件依然保留,但每次查询锁定的是一个连续的 ID 范围,数据库可以在物理上顺序扫描数据页,从而降低随机 I/O 的开销。
2.2 Master 数量过多时,Slot分布的优势
- 跨 Page 读取加剧:
当集群中的 Master 数量(即totalSlot)增大时,每个 Master 处理的 ID 间隔也会随之加大。例如,当totalSlot=100时,某个 Master 处理的 ID 可能为0, 100, 200, 300, …。这会使得满足条件的记录更加分散。数据间隔扩大。 由于每个 Page 中通常存储多个连续的记录,较大的 ID 间隔意味着同一 Master 需要从更多的 Page 中提取数据。因此在这种情况下,通过idStep限定连续查询区间更有优势。
3. 总结
DolphinScheduler 采用 Slot 分片设计的核心在于将原本可能导致随机 I/O 的间隔查询,通过引入 idStep 转换为连续区间查询,从而充分利用 InnoDB 聚簇索引的顺序 I/O 优势,减少 Page 分页问题。