*性能加速之加载内存

对于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。

08-30 04:06