【数据结构和算法】之资源分片算法
一、平均分片算法
应用场景:分布式调度系统,对任务和资源进行匹配和分配的算法。
例如:服务有10台机器资源,任务量是20,将任务量分配给这10台机器,进行任务量处理。
public class SplitTask { /** * 打印结果: * * 分片总数:20 * 资源=[ip2] 的分片数=[[1, 6, 11, 16]] * 资源=[ip1] 的分片数=[[0, 5, 10, 15]] * 资源=[ip4] 的分片数=[[3, 8, 13, 18]] * 资源=[ip3] 的分片数=[[2, 7, 12, 17]] * 资源=[ip5] 的分片数=[[4, 9, 14, 19]] * @param args */ public static void main(String[] args) { List<String> sources = Arrays.asList("ip1", "ip2", "ip3", "ip4", "ip5"); SplitResult splitResult = split(sources, 20); System.out.println("分片总数:" + splitResult.getSplitCount()); for (String key : splitResult.getSplitInfo().keySet()) { System.out.println("资源=[" + key + "] 的分片数=[" + splitResult.getSplitInfo().get(key) + "]"); } } /** * 任务分配 * * @param sources 机器资源 * @param splitCount 任务量 * @return */ public static SplitResult split(List<String> sources, Integer splitCount) { SplitResult splitResult = new SplitResult(); splitResult.setSplitCount(splitCount); Map<String, List<Integer>> splitInfo = new HashMap<>(); int sourcesSize = sources.size(); int sourcesIndex = 0; for (int i = 0; i < splitCount; i++) { sourcesIndex = i % sourcesSize; String source = sources.get(sourcesIndex); List<Integer> split = splitInfo.get(source); if (split == null) { splitInfo.put(source, split = Lists.newArrayList()); } split.add(i); } splitResult.setSplitInfo(splitInfo); return splitResult; } } /** * 任务分配结果 */ class SplitResult { /** * 任务量 */ private int splitCount; /** * 任务分配结果 * key:机器资源标识 * value:任务量的标识集合 */ private Map<String, List<Integer>> splitInfo; public int getSplitCount() { return splitCount; } public void setSplitCount(int splitCount) { this.splitCount = splitCount; } public Map<String, List<Integer>> getSplitInfo() { return splitInfo; } public void setSplitInfo(Map<String, List<Integer>> splitInfo) { this.splitInfo = splitInfo; } }
二、任务分片算法迭代版
应用场景:分布式调度系统,对任务和资源进行匹配和分配的算法。
例如:服务有10台机器资源,分片是20,这10台机器处理那些分片。
依赖方系统总共有1000页数据,10台机器如何通过分片处理这1000页数据。
/** * [1, 2, 11, 12, 21, 22, 31, 32, 41, 42, 51, 52, 61, * 62, 71, 72, 81, 82, 91, 92, 101, 102, 111, 112, 121, * 122, 131, 132, 141, 142, 151, 152, 161, 162, 171, 172, * 181, 182, 191, 192, 201, 202, 211, 212, 221, 222, 231, * 232, 241, 242, 251, 252, 261, 262, 271, 272, 281, 282, * 291,292, 301, 302, 311, 312, 321, 322, 331, 332, 341, * 342, 351, 352, 361, 362, 371, 372, 381, 382, 391, 392, * 401, 402, 411, 412, 421, 422, 431, 432, 441, 442, 451, * 452, 461, 462, 471, 472, 481, 482, 491, 492, 501, 502, * 511, 512, 521, 522, 531, 532, 541, 542, 551, 552, 561, 562, * 571, 572, 581, 582, 591, 592, 601, 602, 611, 612, 621, 622, * 631, 632, 641, 642, 651, 652, 661, 662, 671, 672, 681, 682, * 691, 692, 701, 702, 711, 712, 721, 722, 731, 732, 741, 742, * 751, 752, 761, 762, 771, 772, 781, 782, 791, 792, 801, 802, * 811, 812, 821, 822, 831, 832, 841, 842, 851, 852, 861, 862, * 871, 872, 881, 882, 891, 892, 901, 902, 911, 912, 921, 922, * 931, 932, 941, 942, 951, 952, 961, 962, 971, 972, 981, 982, * 991, 992, 1001, 1002, 1011, 1012, 1021, 1022, 1031, 1032, * 1041, 1042, 1051, 1052, 1061, 1062, 1071, 1072, 1081, 1082, * 1091, 1092, 1101, 1102, 1111, 1112, 1121, 1122, 1131, 1132, * 1141, 1142, 1151, 1152, 1161, 1162, 1171, 1172, 1181, 1182, 1191, 1192] */ public static void dealZone(){ //依赖方系统总共有1000页数据 Integer batchSize=1200; //预计的机器分片总数量 Integer count=10; //当前机器获得的分片是【1,2】 List<Integer> currentHostZones=Arrays.asList(1,2); //当前机器要执行的分片 List<Integer> currentHostDealTask= new ArrayList<>(); for(int i=1;i<=batchSize;i++){ if(currentHostZones.contains(i%count)){ currentHostDealTask.add(i); } } //当前机器的分片数 System.out.println(Arrays.toString(currentHostDealTask.toArray())); }
三、hash一致性分片算法