免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: pacman2000
打印 上一主题 下一主题

一个程序员在AS400银行核心系统开发中的技术总结 [复制链接]

论坛徽章:
5
2015亚冠之阿尔艾因
日期:2015-08-10 02:23:34操作系统版块每日发帖之星
日期:2015-08-13 06:20:002015七夕节徽章
日期:2015-08-21 11:06:1715-16赛季CBA联赛之山西
日期:2016-04-13 02:36:59操作系统版块每日发帖之星
日期:2016-04-14 06:20:00
11 [报告]
发表于 2015-07-03 01:04 |只看该作者
本帖最后由 pacman2000 于 2015-07-03 01:06 编辑

*性能加速之加载内存

对于AS400系统来说,有一个提升性能的利器,利用系统的内存加载技术,将需要的表或者程序,预先加载到内存中,使用的时候,大大提高了操作速度。

具体的使用上,系统提供的一个CL命令,SETOBJACC。以下是IBM官方资料《i5OS Commands》里关于这个命令的用法。
命令描述:
这个命令通过将对象加载到系统的内存池或者从内存池中去除,可以临时性的改变操作对象的速度。如果选择加载到一个有空余空间,并且没有进程关联的内存池,那么对象可以一直在内存池中保留。重复使用这个命令,可以将一系列对象加载到一个内存池中。
参数:
OBJ:必输项,指定需要操作的对象。
OBJTYPE:可选项,可以是*FILE或者*PGM。
POOL:关联的内存池,第一项是内存池名或者子系统名。如果是子系统名,第二项是子系统定义的内存池编号。如果名字为*JOB,表示当前JOB使用的内存池。如果名字为*PURGE,则从所有内存池清除该对象。
MBR:要加载的FILE的MEMBER名,或者*FIRST表示第一个MEMBER。
MBRDATA:MEMBER要加载的内容,可以是数据,访问路径,或者两个都加载。

要了解背后的原理,就得从AS400系统的内存使用模式说起。AS400内存使用机制,和现在linux系统的文件内存缓存机制是差不多的。当用到执行的程序和数据时,先要将文件系统上的对象,加载到内存中,然后才能执行。但是AS400系统的内存是划分若干内存池管理的,系统预设了4个,分别是MACHINE,BASE,INTERACT,SPOOL,另外还可以定义共享内存池SHRPOOL1到60,以及子系统私有内存池,通过CL命令WRKSYSSTS可以看到系统各内存池状况。系统内存池和共享内存池是所有子系统共享使用,私有内存池只供定义的子系统专用。在定义子系统描述时,可以指定子系统可使用的内存池分配方案。而在子系统route定义时,又限定了job将使用的是子系统关联的哪一个内存池。于是,在job执行时,就明确知道是与哪个内存池交互。如果没有SETOBJACC时,执行程序或访问数据文件,操作系统就会先判断job内存池内是否已经加载相应的PGM或MEMBER,没有的话先从硬盘加载到job内存池再使用,有的话直接使用。从而可以发现,job第二次访问文件比第一次要快很多。但是内存池大小是有限的,如果内存池剩余大小不够加载时,就会把旧的对象清理出去,形成换页。
那么,当使用了SETOBJACC时,又会发生什么呢?如果不是*PURGE,系统将对象提前加载进指定的内存池,否则将对象从内存池中清除。猜测系统会登记对象已加载的内存池,当有读取请求时,直接从内存池中读,当有写请求时,内存池和硬盘都会写入。于是,大大加速了读取性能(不用真的从硬盘读入内存池),也稍微加速了写的性能(正常的写,也首先要从硬盘加载进内存池,再更新内存池中的对象,最后从内存池写回硬盘,节省了第一步)。但是,如果SETOBJACC后由于内存池的使用,导致对象被挤出,那么就起不到加速效果了,这对关联了job的内存池很常见。为了解决这个问题,可以用CHGSHRPOOL命令设置专门用于存放数据的共享内存池,不与任何job关联,以保证对象不会挤出。

在核心系统中,我们对系统的数据表做了区分,以C开头的为参数表,这部分会全部加载到共享内存池中。下面是核心系统设置内存池及使用的例子。
CHGSHRPOOL POOL(*SHRPOOL1) SIZE(8388608) ACTLVL(999) TEXT('核心系统内存池')
CHGSHRPOOL POOL(*SHRPOOL2) SIZE(262144) ACTLVL(*DATA) TEXT('参数表加载内存池')
设置2个共享内存池,SHRPOOL1为核心系统job使用,大小8G,同时访问数量为999。SHRPOOL2为参数表加载专用,大小为256M,建立后调用SETOBJACC将所有参数表加载进去。

CRTSBSD SBSD(XXXSYSCRE/XXXONLSBS) POOLS((1 *BASE) (2 *SHRPOOL1)) TEXT('联机子系统描述')
CRTSBSD SBSD(XXXSYSCRE/XXXON2SBS) POOLS((1 *BASE) (2 *SHRPOOL1)) TEXT('联机子系统描述')
CRTSBSD SBSD(XXXSYSCRE/XXXBATSBS) POOLS((1 *BASE) (2 *SHRPOOL1)) TEXT('批量子系统描述')
CRTSBSD SBSD(XXXSYSCRE/XXXAMBSBS) POOLS((1 *BASE) (2 *SHRPOOL1)) TEXT('异步子系统描述')
核心系统的各子系统,可使用的内存池为1-BASE,2-SHRPOOL1。job使用的通过下面指定。这里不能肯定是否要将SHRPOOL2关联编号,才能起效果。有了解的请补充介绍。

ADDRTGE SBSD(XXXSYSCRE/XXXONLSBS) SEQNBR(10) CMPVAL(*ANY) PGM(QSYS/QCMD) CLS(XXXSYSCRE/XXXONLCLS) POOLID(2)
ADDRTGE SBSD(XXXSYSCRE/XXXON2SBS) SEQNBR(10) CMPVAL(*ANY) PGM(QSYS/QCMD) CLS(XXXSYSCRE/XXXON2CLS) POOLID(2)
ADDRTGE SBSD(XXXSYSCRE/XXXBATSBS) SEQNBR(10) CMPVAL(*ANY) PGM(QSYS/QCMD) CLS(XXXSYSCRE/XXXBATCLS) POOLID(2)
ADDRTGE SBSD(XXXSYSCRE/XXXAMBSBS) SEQNBR(10) CMPVAL(*ANY) PGM(QSYS/QCMD) CLS(XXXSYSCRE/XXXAMBCLS) POOLID(2)
定义了各子系统job执行时,都会使用子系统2号内存池,即SHRPOOL1。



下一集介绍性能加速的另一重要写法--激活组。

论坛徽章:
0
12 [报告]
发表于 2015-07-04 13:00 |只看该作者
回复 11# pacman2000

期待楼主持续连载,激活组一直想用一直不清楚啊,大神加油
   

论坛徽章:
0
13 [报告]
发表于 2015-07-17 13:48 |只看该作者
唉,不要伤心了,哈哈哈,IBM自己也不搞了,哈哈哈!!!

论坛徽章:
5
2015亚冠之阿尔艾因
日期:2015-08-10 02:23:34操作系统版块每日发帖之星
日期:2015-08-13 06:20:002015七夕节徽章
日期:2015-08-21 11:06:1715-16赛季CBA联赛之山西
日期:2016-04-13 02:36:59操作系统版块每日发帖之星
日期:2016-04-14 06:20:00
14 [报告]
发表于 2015-07-27 02:51 |只看该作者
本帖最后由 pacman2000 于 2015-07-27 02:58 编辑

*激活组

随着AS400的程序模型从OPM发展到ILE,写法上有了巨大的提升。激活组的引入,作为ILE最重要的变化,影响到整个系统程序的组织和性能。可是目前,仍然有很多系统,沿用着老式的OPM写法和程序组织,没有对激活组做好规划,只是使用缺省激活组管理,从而失去了ILE激活组带来的可控资源管理和性能提升,颇为可惜。因此,我介绍一下在Firebird核心系统中,对ILE激活组的使用方式,作为参考。更详细的信息,可以查看IBM官方手册的《ILE Concepts》文档。

随着从RPG升级到RPGLE,CL升级到CLLE,当前的程序,已经都是ILE程序了。ILE程序的运行,首先要进行程序的激活。ILE通过激活组来管理程序的运行和静态存储区域。激活组是比job粒度更小的单位,不同job之间互不影响,即使不同job存在同名的激活组,系统也是分开独立管理的。一旦程序加载进激活组激活,静态存储区域就会被初始化(包含F表文件的打开,D表定义的变量INZ初始化,以及执行*INZSR过程)。如果程序没有被激活组清除,并且激活组也没有被删除,那么下次运行程序时,将会直接用已加载的程序和存储区域执行。这时注意三点。一,已加载的程序不受文件系统上的程序目标更改的影响,即改变了程序目标,但执行的仍是老代码。二,F表打开的文件,以及访问的文件位置,均会保留上次执行结束时的状态,这个效果对性能加速非常有用。三,D表的INZ和*INZSR不会再次执行,全局变量会保留上次执行结束时的残留值,因此程序在开始处需要执行RESET(设置成初始化数据),或者CLEAR(根据数据类型清空内容)。在实际使用中,程序不设置INZ和*INZSR,将所有独立变量统一定义在D_VARS结构下,在*ENTRY后,首先执行CLEAR的动作。

ILE程序必须加载到激活组运行,而运行在哪个激活组,是在编译程序时指定的。通过CRTPGM或者CRTSRVPGM命令,包括衍生的CRTBNDRPG,CRTBNDCL,CRTSQLRPGI,可以用DFTACTGRP和ACTGRP参数选择激活组的属性。可以选择的方式有:DFTACTGRP默认为*YES,表示使用系统默认的激活组,系统默认激活组是不会被删除的;DFTACTGRP为*NO,ACTGRP为*CALLER,表示与调用者在同一个激活组;DFTACTGRP为*NO,ACTGRP为*NEW,表示让系统自动新增一个系统命名的激活组,系统保证激活组一定是与已有激活组不同的名字,因此一定是新建立;DFTACTGRP为*NO,ACTGRP为用户自定义名称,表示使用用户命名的激活组,如果激活组不存在则建立,已存在则直接使用。
激活组可以解决一个很特殊的问题。我们知道有一种程序写法叫做递归调用,即程序调用自身执行。缺省情况下,这种调用AS400会报错。这是因为程序调用自身时,激活组内已经存在一份正在运行的程序目标和存储区域,未执行完时必须保留,再调用自身时就产生了冲突。那么如何实现递归呢?我们可以把程序编译成*NEW激活组,这样调用自身也是在另外一份激活组内加载独立的目标和存储区域,不会再报错。
激活组是用来管理程序资源的,激活组删除时程序资源会自动释放。那么,激活组会出现哪些情况呢?RPG程序中的LR资源释放指示器会产生什么影响呢?我们依次进行分析说明。
一,系统默认激活组是从不删除的,一直到job结束,随着job的释放而释放。因此,在默认激活组执行的程序,有两种方式释放资源。第一种是在RPG程序中SETON LR指示器,那么在程序RETURN后就会被清理。第二种是不做SETON LR,加载的程序下次调用仍可使用,直到调用了RCLRSC命令。RCLRSC命令只对缺省激活组有效,调用后,在缺省激活组的已执行结束但未释放的程序,将被清理。
二,用*NEW系统自动建立的激活组,当建立程序执行结束RETURN时,系统自动进行删除激活组,也就自动释放所有组内程序资源,因此不需要程序设置LR。
三,用ACTGRP指定用户自定义名称的激活组,不会自动删除,当组内所有程序均不在运行状态时,使用RCLACTGRP命令,指定名称或者ACTGRP(*ELIGIBLE)删除。删除后,释放所有组内程序资源。既然使用了自定义的激活组,就是为了利用激活组的性能加速,因此我们也不用再设置LR了。

充分使用激活组的功能,对应用系统有着重要的意义。在核心系统中,联机和批处理主控程序运行于*NEW激活组,交易程序运行于CORE激活组,交易调用的各级模块程序均指定为*CALLER,可以由主控控制何时执行RCLACTGRP。
首先,可以用激活组的目标加载,实现应用程序版本更新。程序上线时,更新了新的目标,不会对已经调用过此目标的job产生影响,而只要触发主控的激活组回收,即可实现新目标的运行切换。
其次,保留的程序资源,可以实现极大的性能加速。批处理往往是循环重复调用模块组件访问相同的表,节省了文件的打开关闭动作,加速效果非常显著。联机交易结合同一环境启用多套联机主控子系统的支持,一样能达到很好的效果。银行交易有特殊性,交易量排名前几的交易,往往占比很大,因此考虑对这些交易各自启动专用主控子系统,就可以达到同样的交易程序重复执行最大加速的效果。

曾几何时,RPG程序开发规范上,写着在RETURN前必须SETON LR指示器。而现在,到了抛弃指示器,拥抱ILE新环境的时候了。

论坛徽章:
0
15 [报告]
发表于 2015-08-06 16:05 |只看该作者
“随着国家的自主安全可控号召,AS400系统看来在银行IT逐渐退出了。”   --- AS400要从银行退出了???

论坛徽章:
5
2015亚冠之阿尔艾因
日期:2015-08-10 02:23:34操作系统版块每日发帖之星
日期:2015-08-13 06:20:002015七夕节徽章
日期:2015-08-21 11:06:1715-16赛季CBA联赛之山西
日期:2016-04-13 02:36:59操作系统版块每日发帖之星
日期:2016-04-14 06:20:00
16 [报告]
发表于 2015-08-07 21:49 |只看该作者
iCloud400 发表于 2015-08-06 16:05
“随着国家的自主安全可控号召,AS400系统看来在银行IT逐渐退出了。”   --- AS400要从银行退出了???



差不多,虽然老系统还在用,但换系统的话都在考虑换平台了。

论坛徽章:
5
2015亚冠之阿尔艾因
日期:2015-08-10 02:23:34操作系统版块每日发帖之星
日期:2015-08-13 06:20:002015七夕节徽章
日期:2015-08-21 11:06:1715-16赛季CBA联赛之山西
日期:2016-04-13 02:36:59操作系统版块每日发帖之星
日期:2016-04-14 06:20:00
17 [报告]
发表于 2015-08-10 02:21 |只看该作者
本帖最后由 pacman2000 于 2015-08-10 02:23 编辑

*性能加速之批处理事务提交

在核心系统中,对性能要求最高的,就是批处理程序了。那么,对批处理提升性能,有哪些技术方法呢?下面介绍一下在Firebird系统中的做法。

首先,前面介绍的SETOBJACC加载内存,同样适用于批处理。除了与联机处理一样,加载系统参数表外,还可以新开一个专用SHRPOOL,加载批处理中会重复用到的表,然后在批处理结束后释放这个SHRPOOL。
其次,激活组的加速也能起到很大效果。批处理程序同样由总控调度任务,每个任务再按照分段不分段,启动不同的job执行。每一个job都是多次循环处理相同的程序逻辑,操作相同的表,恰好是激活组最能发挥作用的场景。按照系统的规划,交易程序使用命名激活组CORE,各模块组件使用激活组*CALLER,批处理也遵循这一规则即可,完美达到模块组件重用的效果。
然而本次主要介绍的,是另外一种性能加速的方法。我们知道批处理程序耗时最多的,是在数据表文件的操作和事务日志处理上。由于数据库事务的ACID特性,因此每次事务处理都会落实到磁盘的写JRN日志记录上。如果去翻看关联的JRN文件记录,会发现里面记录的内容非常多,通常包含开始事务,打开关闭文件,读写文件记录数据,事务提交或者回滚等。如果每条日志记录产生时都写磁盘,显然性能就会受到影响。于是,在这方面就有了优化的空间。

我们先看看STRJRNPF的参数能调整什么。STRJRNPF有几个选项,一个是IMAGES,如果是*AFTER,则在记录变更时只在JRN中登记变更后数据,如果是*BOTH,那么变更时会登记BEFORE和AFTER两条数据。另一个是OMTJRNE,如果是*OPNCLO,表示省略掉打开关闭文件的记录不登记。通过这两个选项,在把PF加进事务处理,可以稍微省一点事务日志产生的数量。然后我们再看看CRTJRN或者CHGJRN的一个选项,JRNCACHE选择*YES。这个选项可以让事务日志累积在内存CACHE中,再成批写进磁盘。但是值得注意的是,IBM官方文档没有说明,这个CACHE仍然需要保证数据库事务的ACID性质,因此只能对事务缓存到COMMIT或者ROLLBACK为止。对于批处理循环每笔COMMIT来说,其实并没有想象中那么好的提升效果。那有没有其他办法呢?有,而且是一个有争议的大招,叫做soft commit。具体做法是,设置环境变量,ADDENVVAR ENVVAR(QIBM_TN_COMMIT_DURABLE) VALUE(*NO)。当这个环境变量与JRNCACHE同时使用时,事务日志的CACHE将不顾COMMIT和ROLLBACK一直缓存,直到缓存满后才一次性写入磁盘。用这样的方法,大大减少了写磁盘的次数。但是这是有争议的,即要承受风险,如果系统崩溃或者断电导致缓存丢失,那么未写入磁盘的已完成事务将永久丢失,造成数据丢失的严重后果。以银行系统来说,恐怕这种风险是很难接受的。

操作系统提供的技术方法,没有找到其他手段了。但是,作为应用系统,可以调整应用程序的设计,达到既能加速,又不会丢失数据的效果。既然通过JRNCACHE缓存一笔COMMIT事务还是比较有保障的,那批处理程序可以循环若干条再做一次COMMIT提交,使CACHE的日志数量尽可能接近填满CACHE大小。可是这种批量方式有一个缺陷,当一批若干条中有一条出现错误导致事务需要回滚,那么同一批内其他成功记录都会受影响被回滚。这必须得想办法克服。考虑过每一笔设置SAVEPOINT,发生错误回滚到上个SAVEPOINT,但SAVEPOINT性能损失的代价很大,小概率才会发生的错误导致所有正常处理也要付出代价,得不偿失。思考良久之后,最终通过调整批处理程序的写法达到效果。
批处理程序的机制先要支持断点续跑。即每段事务中,都记录目前已处理到的位置。这样当发生错误ROLLBACK,主控重新调起任务时,程序会定位到上次成功的位置后开始接着执行。这个不难实现,大多数现有系统也都支持。单笔事务处理的程序没有问题,但为了性能使用多笔一次事务提交时,就需要改变写法了。程序开始时处于多笔模式,记录好起始位置和一批数量,先按多笔方式正常处理。当某一批中出现错误时,整批事务回滚,并切换成单笔模式,从本批开始的位置重新执行,当本批数量的记录处理完需要进入下一批时,重新切回多笔模式正常执行。即出现错误的这一小段单笔执行,过了这一段又多笔执行,从而达到性能加速和控制错误粒度的完美结合。

通过最近几篇介绍的方法,Firebird系统性能相对现有系统,不论是联机交易还是批处理交易,都有好几倍的提升,效果十分显著。性能部分就告一段落了,再下来会介绍程序上用到的新写法,敬请期待。

论坛徽章:
0
18 [报告]
发表于 2015-08-12 16:49 |只看该作者
开放平台和分布式总归是趋势的,过去的经历总是难忘,能与400结缘或是命中注定,正所谓英雄不提当年之勇,往前看吧

论坛徽章:
5
2015亚冠之阿尔艾因
日期:2015-08-10 02:23:34操作系统版块每日发帖之星
日期:2015-08-13 06:20:002015七夕节徽章
日期:2015-08-21 11:06:1715-16赛季CBA联赛之山西
日期:2016-04-13 02:36:59操作系统版块每日发帖之星
日期:2016-04-14 06:20:00
19 [报告]
发表于 2015-08-13 08:23 来自手机 |只看该作者
且行且珍惜,哈哈

论坛徽章:
1
操作系统版块每日发帖之星
日期:2016-02-18 06:20:00
20 [报告]
发表于 2015-08-19 17:45 |只看该作者
然并卵……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP