Mainframe DFSORT实现N文件均衡拆分:同学生号不跨文件
基于JCL实现按学号分组的近似负载均衡文件拆分方案
需求概述
- 输入文件:已按**学号(2位字符+6位数字)**排序的记录文件
- 拆分目标:将文件拆分为N个(示例为5个)输出文件,实现近似负载均衡
- 核心约束:同一学号的所有记录必须保留在同一个输出文件中,不得分散
- 特殊情况:若学号记录分布倾斜,无法做到完全均衡;允许输出文件出现空文件
示例输入(按学号排序)
Stud nbr Data Rec Seq Number AA000001 DATA1 1 AA000001 DATA2 2 AA000001 DATA3 3 AA000001 DATA4 4 AA000002 DATA5 5 AA000002 DATA6 6 AA000002 DATA7 7 AA000002 DATA8 8 AA000002 DATA9 9 AA000002 DATA10 10 AA000002 DATA11 11 AA000002 DATA12 12 AA000003 DATA13 13 AA000004 DATA14 14 AA000005 DATA15 15 AA000006 DATA16 16 AA000007 DATA17 17 AA000007 DATA18 18 AA000007 DATA19 19 AA000007 DATA20 20 AA000007 DATA21 21 AA000007 DATA22 22 AA000007 DATA23 23 AA000007 DATA24 24 AA000007 DATA25 25 AA000008 DATA26 26
示例输出(拆分为5个文件)
File 1 : AA000001 DATA1 1 AA000001 DATA2 2 AA000001 DATA3 3 AA000001 DATA4 4 File 2 : AA000002 DATA5 5 AA000002 DATA6 6 AA000002 DATA7 7 AA000002 DATA8 8 AA000002 DATA9 9 AA000002 DATA10 10 AA000002 DATA11 11 AA000002 DATA12 12 File 3 : AA000003 DATA13 13 AA000004 DATA14 14 AA000005 DATA15 15 AA000006 DATA16 16 File 4 : AA000007 DATA17 17 AA000007 DATA18 18 AA000007 DATA19 19 AA000007 DATA20 20 AA000007 DATA21 21 AA000007 DATA22 22 AA000007 DATA23 23 AA000007 DATA24 24 AA000007 DATA25 25 File 5 : AA000008 DATA26 26
JCL实现方案
该需求可通过JCL结合**DFSORT(或SYNCSORT)**工具实现,核心逻辑是先统计每个学号的记录数,再根据总记录数计算单文件目标负载,最后按学号组分配到对应输出文件,确保同一学号不拆分。
步骤1:统计每个学号的记录数
先用DFSORT生成包含学号及对应记录数的中间文件,JCL示例如下:
//STEP1 EXEC PGM=SORT //SYSOUT DD SYSOUT=* //SORTIN DD DSN=YOUR.INPUT.FILE,DISP=SHR //SORTOUT DD DSN=YOUR.TEMP.COUNT.FILE,DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(1,1),RLSE) //SYSIN DD * SORT FIELDS=(1,8,CH,A) // 输入已排序可省略,保留以确保稳定性 INREC FIELDS=(1,80,ZD,1) // 添加虚拟计数字段(若已有Seq Number可替换) SUM FIELDS=(81,1,ZD) // 统计每个学号的记录数 OUTREC FIELDS=(1,8, // 学号字段 81,1) // 该学号的记录数 /*
步骤2:按负载分配拆分文件
通过DFSORT的JOINKEYS合并原始记录与计数信息,再用OUTFIL将不同学号组分配到对应输出文件。JCL示例(拆分为5个文件):
//STEP2 EXEC PGM=SORT //SYSOUT DD SYSOUT=* //SORTIN DD DSN=YOUR.INPUT.FILE,DISP=SHR //COUNTIN DD DSN=YOUR.TEMP.COUNT.FILE,DISP=SHR //OUT1 DD DSN=YOUR.OUTPUT.FILE1,DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(5,5),RLSE) //OUT2 DD DSN=YOUR.OUTPUT.FILE2,DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(5,5),RLSE) //OUT3 DD DSN=YOUR.OUTPUT.FILE3,DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(5,5),RLSE) //OUT4 DD DSN=YOUR.OUTPUT.FILE4,DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(5,5),RLSE) //OUT5 DD DSN=YOUR.OUTPUT.FILE5,DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(5,5),RLSE) //SYSIN DD * JOINKEYS F1=SORTIN,FIELDS=(1,8,A) JOINKEYS F2=COUNTIN,FIELDS=(1,8,A) JOIN UNPAIRED,F1 REFORMAT FIELDS=(F1:1,80,F2:9,1) // 合并原始记录与对应学号的记录数 SORT FIELDS=COPY // 按预计算的负载分配规则,将学号组定向到对应文件 OUTFIL FNAMES=OUT1,INCLUDE=(1,8,CH,EQ,C'AA000001'),BUILD=(1,80) OUTFIL FNAMES=OUT2,INCLUDE=(1,8,CH,EQ,C'AA000002'),BUILD=(1,80) OUTFIL FNAMES=OUT3,INCLUDE=(1,8,CH,GE,C'AA000003',AND,1,8,CH,LE,C'AA000006'),BUILD=(1,80) OUTFIL FNAMES=OUT4,INCLUDE=(1,8,CH,EQ,C'AA000007'),BUILD=(1,80) OUTFIL FNAMES=OUT5,INCLUDE=(1,8,CH,EQ,C'AA000008'),BUILD=(1,80) /*
注:实际使用时需根据总记录数和单学号记录数,计算每个文件应包含的学号组。例如总记录26条,拆分为5个文件时,目标单文件负载约5-6条,依次累加学号记录数,达到目标值则切换到下一个文件。
自动化适配N个文件的方式
若需动态适配任意N值,可结合REXX脚本实现:
- 用REXX读取计数文件,计算每个文件应分配的学号组
- 自动生成包含
OUTFIL规则的SYSIN控制卡 - 调用DFSORT执行拆分
关键注意事项
- 输入文件必须严格按学号排序,否则JOINKEYS或分组逻辑会出错
- 若某个学号的记录数远大于单文件目标负载,该学号会独占一个文件,此为符合需求的预期情况
- 当N大于不同学号的数量时,会出现空输出文件,符合需求允许范围
内容的提问来源于stack exchange,提问作者mayank
相关产品推荐
相关产品推荐

