从UNIX到IBM主机系统的程序移植探讨
摘 要:本文介绍了unix平台与ibm主机系统平台之间的差异,并对跨平台移植过程中应考虑的主要问题和解决方法进行了探讨。
关键词:ibm主机系统;移植;作业控制语言;初始化器
1 引言
ibm主机系统,又称ibm大型机,是20世纪60年代发展起来的计算机系统,在全世界各大国家中肩负着银行、保险、证券、通讯等行业的数据与信息处理工作,因为其独具的高安全性、高稳定性和强大的数据处理能力,迄今无可替代。
近几年来,主机系统的前景不断看好。从1994年起,ibm开始对大型机进行深入的技术改造,采用了新的cmos技术,极大地缩小了大型机的系统体积,降低了能耗和散热成本,提高了性能价格比。另一方面,分布式计算开始变得庞杂起来,许多公司的管理费用激增,而且由于数据分散,在数据的互访和集中管理方面,安全和准确性都不够高,许多企业开始转向使用大型机。大型机在总体拥有成本上已经比分布计算廉价,制造业、保险、航空、运输及大型零售企业的大量事务处理对大型机的要求越来越高,这是大型机重新被人们认可的原因之一。
2 分布式与大型机
分布式计算在短期内给企业带来了高效,但随着时间的延续,企业系统扩大,数据分散存放在上百台服务器上,数据的查询成为问题,数据的互访和对大量数据的开采利用变得困难起来,一个新的趋势——再集中开始出现。如何将分布处理和集中计算结合起来,成为许多企业考虑的问题。WWw.lw881.com大型机的系统完整性和大存储量的优势显示出来,开始承担用户再集中需求的任务。
在总体拥有成本上,随着时间的推移,小型机系统渐渐显现出极高的使用成本。或许人们在使用一年unix后,会说unix性价比高,但随着业务的增加,系统变得分散庞杂起来,维护费用增加。大型机挺过了关键的10年暗淡期,终于峰回路转。因此,越来越多的企业开始关注ibm主机系统,将自己的系统移植到主机系统上来。
3 移植平台间的差异
3.1 主机操作系统z/os与unix
目前ibm主机的主流操作系统z/os是使用最广泛的基于64位z体系结构大型机操作系统,它给在大型机上的应用程序员提供了稳定、安全和可持续运行的环境。
从本质上来说,unix是一个计算密集型的操作系统, cpu利用率较高,更适用于需要大量计算的环境;而主机操作系统z/os依赖于其强大的硬件后盾,除了强大的计算能力之外,更突出的是它强大的i/o处理能力,依托硬件上的ficon、escon等光纤通道,可同时应对大规模的并发用户,因此它是一个i/o密集型的操作系统。两种系统在很多内容上有着不同但又类似之处。
3.2 进程与地址空间
在unix下,一个程序的执行通常称为一个进程,操作系统为每个进程分配一定的cpu、内存资源,使其运行,进程与进程之间可以通过信号量机制协同工作实现并发;而在z/os下没有进程的概念,与之对应的是地址空间(address space)的概念,任何用户的登录、程序的执行、作业的提交,系统都会为其生成一个地址空间。地址空间之间在批处理方式下一般没有通信,而通过联机交易处理方式实现程序间通信。
在unix下通常会有守护进程(daemon)的概念,在主机环境中通常是一个长时间运行的作业的提交,可以从控制台为这个守护作业提供输入输出对象处理。
3.3 文件的组织与编辑方式
从文件和数据格式上来说,unix系统是树状的目录结构,数据的组织以文件夹与文件的方式保存、管理;而在主机上,数据都保存在数据集里,数据集分顺序数据集、分区数据集与vsam数据集,其组织方式没有多层树状结构,分区数据集下可包含称为member的顺序数据集,顺序数据集或vsam数据集存储实际的数据。
数据的格式在unix下是面向字节,而在z/os下是面向记录的。数据的编辑在unix下通常是用vi;而在z/os下用的是ispf编辑器。
3.4 交互系统的区别
unix下用户登录并在shell环境下执行shell会话,可以通过发送远程登录rlogin命令或者远程登录telnet命令连接系统,一个用户可以同时打开多个用户会话。在主机环境下,用户通过tso/e和它的菜单驱动接口ispf登录系统,一个用户一次只能有一个活动的会话。
在unix系统中,用户可以通过后缀shell命令观察处理进程和线程,可通过kill命令结束一个任务。在主机环境中,用户通过作业处理子系统提供的sdsf查看他们提交作业的执行情况,并可以终止作业任务的执行。
4 移植实例
下面以一个实际项目实例来阐述一套移植过程中要考虑的具体问题。项目以一个在unix平台上实际应用的后台结息系统为移植对象,考虑系统处理的各种运行机制和平台差异,最终将整个系统移植到z/os下。
原系统的操作系统为aix5.0,数据库为informix 10x,开发语言为c语言,移植后的操作系统为z/os 1.5,数据库为db2版本8,开发语言为c语言。
4.1 针对多进程考虑
在原系统中有一个主控程序设计,主控程序是一个主调度程序,主要负责控制并发的进程数量及状态,系统支持的并发数量由主控程序的参数设置,通常设置为30。主控程序控制的每一个并发进程代表一个部门结息流程。假设一次性有1000个部门运行结息过程,主控程序负责调度,它轮寻所有进程,当一个进程结束时启动下一个进程,直到所有部门完成。
在z/os上没有进程的概念,针对这种后台批处理的结息方式,我们通过作业的方式实现,方案是为每个部门的结息准备一个jcl作业。所谓jcl(job control language)是作业控制语言,通过它写一段作业脚本提交给系统,可以让系统执行相应的程序或进行相关的工作。为每个部门结息准备一个jcl作业,再准备一个主jcl作业,这个主jcl的任务就是去提交所有部门的jcl作业。
把结息过程定义为作业的好处是,在z/os里控制作业的并发数量以及作业调度的任务都可以由系统里的作业处理子系统jes2自动完成。在jes2里,有多个被称为initiator的地址空间,每个initiator都相当于unix下的一个守护进程,专门处理提交的作业。
z/os中的intiator是一个自动调度和处理提交的多个作业的地址空间,它主要负责处理如下任务:
(1) 确保同时运行的各项作业不会产生数据集使用上的冲突;
(2) 为作业分配必要的硬件设备,如磁带等;
(3) 从库中找到每个作业需要调用的可执行程序;
(4) 当一个作业运行完毕之后,在作业队列中清除该作业并要求处理下一个作业。
每个initiator在同一时刻可以处理一个作业,而多个intiator可以并发处理多个作业,各个initiator并发处理各个作业都是在保证不出现死锁的前提下进行的。initiator的数量可以在系统中设置,这样一来就自动实现了并发数的控制。比如我希望将并发数控制为50,我们在系统中设置50个initiator,然后提交主jcl作业,主jcl作业再一次性提交1000个部门的作业,这些作业由jes自动调度给50个initiator,并实现负载的均衡。
4.2 makefile的替代
在unix平台上,通常会在准备好源代码之后使用make工具进行编译,在执行make之前,需要一个命名为makefile的特殊文件来告诉make需要做什么,该怎么做。通常make工具主要被用来进行工程编译和程序链接。
当使用make工具进行编译时,以下几种文件在执行make时将会被编译或重新编译:
(1) 所有的源文件没有被编译过,则对各个c源文件进行编译并进行链接,生成最后的可执行程序;
(2) 每一个在上次执行make之后修改过的c源代码文件在本次执行make时将会被重新编译;
(3) 头文件在上一次执行make之后被修改,则所有包含此头文件的c源文件在本次执行make时将会被重新编译。
makefile文件是一个非常有效的文件,而在z/os平台中,没有类似的文件可用,通常的编译都是通过使用一个jcl作业去调用系统相关的针对编程语言的编译器去执行。
考虑到makefile文件的对应参数、编译流程、依赖关系与jcl作业有很多相似点,我们的方案是还是使用jcl作业去编译程序,但将相关的源程序写在同一个jcl作业中。在z/os环境下一个jcl作业可以有多个作业步,每个作业步可以指定进行不同的操作或调用不同的程序,一个作业最多可以有255个作业步。因此,我们可以将相关联的源程序或者头文件放到同一个作业的不同作业步中,用于编译、链接,当有程序做了修改需要重新编译链接时,还是提交同一个编译作业就可完成。
4.3 信号量机制的考虑
在实际结息流程中,通常每个进程都需要从数据库表里申请一个唯一的编号作为结息流程的流水号,最终保存到数据库。流水号是一个递增数列,无论进程执行是否成功,此流水号都必须唯一且不可让其他进程使用,即使进程执行失败,此流水号也必须作废而不可给后续进程使用。
在unix平台下,允许进程间通信,信号量机制就是用来解决进程同步与互斥问题的。通过p、v操作,保证并发进程互斥地访问数据库里的流水号资源。
而在z/os平台下,特别针对后台批处理方式下,用户的程序之间,作业与作业之间一般不允许相互通信,资源的互斥使用是通过initiator调度实现的。
考虑到进程使用的流水号最终需要保存到数据库,而且流水号要求是递增数列,我们针对db2数据库直接操作,db2里面有个sequence object,它是一个递增数列,其递增幅度与初始值都可以在建立的时候设定。我们可以针对不同类型的流水号建立一个或多个sequence object,之后在任何需要用到流水号的地方,通过调用sequence object的next value取其当前值的下一个值,这样不管多少进程并发,在同一时刻其next value永远不可能重复,保证流水号的唯一性。
4.4 程序的准备
移植初期首先需要将程序与数据导入到z/os环境下。
程序的导入可以通过ftp上传或3270终端直接上传的方式。首先需要在主机上针对不同属性的文件建立不同属性的数据集。由于主机上不是树状文件系统结构,所以要建立几个分区数据集,将相关文件保存成为相关数据集的member。如源文件可以建立一个数据集,名为,库文件可以建立为等,数据集的大小根据实际情况指定,我们的项目考虑可扩展性,建立的每个分区数据集以m为分配单位,初次分配量为300,再次分配量为100,目录空间大小为100。
将文件保存成文本格式上传,如果上传后都成了顺序数据集,可以写一个简单的jcl,使用iebgener将其拷贝到分区数据集里。
4.5 数据的导入
对于数据库的导出导入,我们的方案是先将数据库创建脚本导入到数据集,使用主机上的spufi运行脚本创建好数据库、表空间和相关表、索引等。将原infomix数据库的数据以文本方式导出,再导入到主机,最后导入到数据库。
在db2里,数据库的导入有import和load两种方法。import以sql为基础,会写日志,可以对视图操作,表上定义的各种约束都将被检查,可以在目标表不存在的情况下通过ixf格式的文件创建表,不能在import过程中搜集统计信息。import成功后表就可以使用。
load操作属于偏底层的操作,不写日志,不可以对视图操作,除了唯一性约束之外的各种约束都不在load过程中被检查,不可以在目标表不存在的情况下创建表,可以在load过程中搜集统计信息。load过程成功后也有可能将表空间置于pending等的特殊状态,管理相对比较复杂。
总的来说,由于load操作底层,因此速度很快,适合用于大量数据的导入;import速度慢但管理简单,适用于少量数据导入。
由于我们的数据量非常大,因此选择使用load导入数据。我们将导出的数据保存到主机的数据集里,通过写一个load作业,从相关数据集导入需要的数据。在load过程中,可能会因为参数或数据出错导致表空间置于reorganize pending状态,或者将某个表的index置于rebuild pending状态,这时只需要将相应的表空间做一个reorg或者对相应的index做一个rebuild就可以解决。
5 总结
在决定对一套应用软件进行移植前,首先要明确移植的目的,选用适当的平台和语言,然后充分地分析移植前后软件运行环境的异同,决定要采取的技术和需要进行的结构调整,这样就可以系统而有序地完成大中型软件的移植工作,并可有效地提高软件质量,延长软件生命期。通过几个月的实践,我们的方案在可行性上得到了验证,作为实际的应用,还有很多地方有待我们进一步探讨。
abstract: this paper first introduces the main differences between uinx and ibm mainframe platforms,and then discusses the main problems and the solutions on the program migration from unix to ibm mainframe.
key words: ibm mainframe;migration;job control language;initiator