elasticjob 分片策略

本文详细介绍了Elasticjob的三种分片策略:AverageAllocationJobShardingStrategy、OdevitySortByNameJobShardingStrategy和RotateServerByNameJobShardingStrategy。首先,基础策略AverageAllocationJobShardingStrategy通过平均分配任务到各个节点上实现分片,考虑到了除不尽的情况,确保了公平性。其次,OdevitySortByNameJobShardingStrategy在此基础上增加了根据任务名称哈希值的奇偶性决定是否逆序节点组的特性。最后,RotateServerByNameJobShardingStrategy则通过任务哈希值与节点数量取模,重新排序节点,进一步提高了分片策略的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Elasticjob的分片策略实现了三种。

AverageAllocationJobShardingStrategy是最基础的分片策略。

private Map<JobInstance, List<Integer>> shardingAliquot(final List<JobInstance> shardingUnits, final int shardingTotalCount) {
    Map<JobInstance, List<Integer>> result = new LinkedHashMap<>(shardingTotalCount, 1);
    int itemCountPerSharding = shardingTotalCount / shardingUnits.size();
    int count = 0;
    for (JobInstance each : shardingUnits) {
        List<Integer> shardingItems = new ArrayList<>(itemCountPerSharding + 1);
        for (int i = count * itemCountPerSharding; i < (count + 1) * itemCountPerSharding; i++) {
            shardingItems.add(i);
        }
        result.put(each, shardingItems);
        count++;
    }
    return result;
}

private void addAliquant(final List<JobInstance> shardingUnits, final int shardingTotalCount, final Map<JobInstance, List<Integer>> shardingResults) {
    int aliquant = shardingTotalCount % shardingUnits.size();
    int count = 0;
    for (Map.Entry<JobInstance, List<Integer>> entry : shardingResults.entrySet()) {
        if (count < aliquant) {
            entry.getValue().add(shardingTotalCount / shardingUnits.size() * shardingUnits.size() + count);
        }
        count++;
    }
}

在最基础的分片策略下,以分片总量除以工作的节点总量为每个分片的平均数量。

存在可能除不尽的情况,所以排序较前的节点可能分担多一个分片的情况,由此会为每个节点对应的分片数组多申请一个空间。

之后按照整除的方式分别按照平均数量一次分给每个节点。

再分配完毕之后再把剩下的余数分片依次按照顺序给前面的几个分片。

 

OdevitySortByNameJobShardingStrategy在AverageAllocationJobShardingStrategy的基础上,根据任务名称的哈希值是否能被2整除来选择在执行AverageAllocationJobShardingStrategy分片前,是否将节点组逆序。

@Override
public Map<JobInstance, List<Integer>> sharding(final List<JobInstance> jobInstances, final String jobName, final int shardingTotalCount) {
    long jobNameHash = jobName.hashCode();
    if (0 == jobNameHash % 2) {
        Collections.reverse(jobInstances);
    }
    return averageAllocationJobShardingStrategy.sharding(jobInstances, jobName, shardingTotalCount);
}

同样,RotateServerByNameJobShardingStrategy在执行AverageAllocationJobShardingStrategy的分片之前,根据任务的哈希值与节点数量取模,将之前取模的结果依次加一的结果与节点数量重新取模对节点进行重新排序,再执行AverageAllocationJobShardingStrategy的分片。

@Override
public Map<JobInstance, List<Integer>> sharding(final List<JobInstance> jobInstances, final String jobName, final int shardingTotalCount) {
    return averageAllocationJobShardingStrategy.sharding(rotateServerList(jobInstances, jobName), jobName, shardingTotalCount);
}

private List<JobInstance> rotateServerList(final List<JobInstance> shardingUnits, final String jobName) {
    int shardingUnitsSize = shardingUnits.size();
    int offset = Math.abs(jobName.hashCode()) % shardingUnitsSize;
    if (0 == offset) {
        return shardingUnits;
    }
    List<JobInstance> result = new ArrayList<>(shardingUnitsSize);
    for (int i = 0; i < shardingUnitsSize; i++) {
        int index = (i + offset) % shardingUnitsSize;
        result.add(shardingUnits.get(index));
    }
    return result;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值