背景
在其他开发语言中,实现多进程是很简单,尤其是GO语言只需要一行代码就能开启routine实现Concurrency(注意,Concurrency Is Not Parallelism)。但在ABAP中,好像只能将需要并行处理的逻辑封装成RFC函数,异步并行调用的方式曲线实现多进程并行执行,以充分利用ABAP服务器的Dialog进程数,缩短数据的处理时间。
需求
有一张数据条数非常多的内表,需要循环所有数据执行一段非常复杂的逻辑对内表的数据做处理,如果串行处理每一条数据,需要运行三个多小时,完全无法满足业务需求。
分析
通过分析,数据模型及程序逻辑均无问题,复杂运算的程序逻辑已经优化到极致,但由于存在递归运算且要频繁调用大型CDS,处理时间的线性增加无可避免。
内表中的每一条数据均是独立的,不同sy-tabix的数据之间不存在交叉运算的情况。
服务器的Dialog进程非常充足,HANA数据库资源配置也完全足够。那么,是不是可以考虑并行执行,使内表中不同行的数据同时分别去跑复杂运算逻辑,使总体处理实现线性减少呢?
答案是可以的!但是需要将每行数据都会运行的复杂逻辑封装成RFC函数,然后在LOOP循环内并发调用函数即可。
测试案例说明
取出SBOOK表,传入主键,使用随机数乘以订票价格之后返回结果,SBOOK表中有9万多条数据。
服务器的rdisp/rfc_max_queue参数配置
RZ11检查参数rdisp/rfc_max_queue的设定值,待会并行执行的进行数不能超过这个设定值,注意这个值是一个百分比值。我理解是基于Dialog进程数的百分比,例如有10个Dialog进行,那么如下设置为80标识最多允许8个进程用于RFC队列,如果程序中并行的进程数超过这个值,则可能RFC函数返回的数据会存在丢失的情况(即运行结果随机莫名其妙的不准)。
这块涉及的参数非常多,根据实践经验,建议设置为Dialog进程的。例如一共有10台应用服务器,每台有50个Dialog进程,如果所有服务器上的这个参数都设置为10,则总可用于RFC并行执行的进程数为50*10*0.1=50,即同一个内表可以同时起50个进行进行数据处理,如果硬件资源跟得上的话理论上处理速度会快五十倍。
备注:以上描述可能不准确,因为涉及的知识和参数很多,只是大概了解了下,实际开发中请RZ11调整参数多验证几遍,以免速度倒是快了但是数据不准了哦。
备注:以上参数也可以直接在RZ12的RFC服务器组中进行修改,重启后会失效,要永久有效需要在RZ10中进行修改并重启应用服务器。
测试用的RFC函数
RFC服务器组设置
说到服务器组,有两个不同的概念:登录组和RFC服务器组。
RFC服务器组通过RZ12配置,SAP GUI登录组通过SMLG进行配置。
登录组
登录组,就是将多台SAP应用服务器按组进行划分,这样SAP GUI设置的时候就可以设置组登录,ASCS服务器会根据不同应用服务器的忙碌情况动态分布较为空闲的服务器给用户进行登录,起到负载均衡的作用。
例如,我们可以给财务部单独分配几台服务器用于开票,那么给财务同事设置SAP GUI的时候就统一设置这个组,其他人都不设置这个组,这样相当于这几台服务器就只是几个人独享了。
RFC服务器组
RFC函数并行执行的时候,也需要指定一个RFC服务器组,也就是并行的进程可以分布到哪些服务器上。
我只有一台应用服务器,因此我创建一个登录组,名字根据情况命名,例如我命名为ZRFC_GRP。
ABAP并行执行测试
代码见附件:
启动调试:
数据抽样:
并行执行:
抽样数据运行结果:
如果并行运算结果有的值是空的,或者规律性出现结果都变成一样了之类的情况,请检查参数设置、以及代码中发起的并行数是否合理。
本文作者: GavinDong
版权属于: GavinDong博客
文章链接: https://gavindong.com/7849.html
如果使用过程中遇到问题,可 **点击此处** 交流沟通。
版权所有,转载时必须以链接形式注明作者和原始出处及本声明。