Chinaunix首页 | 论坛 | 博客
  • 博客访问: 302187
  • 博文数量: 40
  • 博客积分: 1
  • 博客等级: 民兵
  • 技术积分: 670
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-31 11:19
个人简介

从事银行核心系统设计开发的程序猿

文章存档

2019年(1)

2018年(4)

2017年(11)

2016年(6)

2015年(18)

分类: 信息化

2015-08-10 02:26:16

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


在核心系统中,对性能要求最高的,就是批处理程序了。那么,对批处理提升性能,有哪些技术方法呢?下面介绍一下在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系统性能相对现有系统,不论是联机交易还是批处理交易,都有好几倍的提升,效果十分显著。性能部分就告一段落了,再下来会介绍程序上用到的新写法,敬请期待。


阅读(3578) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~