ジョブを分割して同時に実行する、ジョブを先行/後続関係に基づいて実行する
ジョブを分割して同時に実行する、ジョブを先行/後続関係に基づいて実行する(z/OS V2.2からのJES2の新たなジョブ・スケジューリング機能③)
z/OSでは、IMSやCICSなどのサブシステムを利用したオンライン・トランザクション処理やTSO配下でのISPFによる対話型処理を除けば、アプリケーションやユーティリティー・プログラムはジョブを定義してスケジュール(サブミット)することでバッチ・ジョブとして実行されます。これはバッチ処理と呼ばれる、メインフレーム・コンピューターに於ける最も基本となる処理形態です。ジョブはJCLによって記述され、1つのジョブは、実行するプログラムとそのプログラムが使用するデータを定義したジョブ・ステップで構成され、ジョブ内のジョブ・ステップは定義された順に上から下に向かって1つずつ順番に実行されます。
同時に数多くのジョブが並行して処理されるMVS(z/OS)オペレーティング・システムでは、JES(*1)を併用したジョブ管理が行われるのが基本で、特に日本国内では大多数のz/OSユーザーがJESとしてJES2を利用しています。JES2に於いては、ジョブ内の各ステップは実行順序が保証されますが、各々のジョブ間では実行順序に依存性はなく(*2)、ジョブ・クラスに対応したイニシエーターが空き次第、次から次へと実行されます。JES2は、CPU(プログラムを実行するイニシエーター空間)や印刷出力を行うハードウェア装置としてのプリンターなどのシステム資源に無駄な遊休時間が生じぬよう、ジョブを次から次へと実行し、帳票データとしてのSYSOUTデータセットの内容を次から次へとプリンターから書き出す、というジョブ・スケジューリングを行います。
*1 Job Entry Subsystem:ジョブ入力サブシステムのこと。入力サブシステムとなっているが、実際にはジョブの入力から実行と出力までの一連のジョブ処理サイクルを効率良く管理しスケジュールする。
*2 ジョブAが終わったらジョブBとジョブCを実行する、といった実行順序に基づく依存性の制御はJES2では行えない。
代表的なバッチ処理のジョブ・ステップ構成

上の図のフローで構成されるジョブがあるとします。z/OSにおける典型的なバッチ処理です。最初のステップ-1の出力データは、後続のステップ-2およびステップ-3の入力データになります。ステップ-2とステップ3は、それぞれステップ-1が作成したデータを元に別々の処理を行い、それぞれが処理結果のデータを出力します。ステップ-4は、ステップ-2とステップ3で作成されたデータを入力にして処理を行い、最終的な出力である印刷帳票を出力します。
ジョブ・ステップの並列化(z/OSとJES2の組み合わせでは実現できない…)
先程の例のジョブをよく見ると、先行ステップで作ったデータを後続ステップの入力にするというデータの依存性に影響を受けるのは、ステップ-1の出力を入力にするステップ-2とステップ-3、ステップ-2とステップ-3の出力を入力にするステップ-4です。ところがステップ-2とステップ-3は、互いにデータを依存し合いません。したがって本来ならステップ-2とステップ-3は、ステップ-1が終わってさえいれば並行して実行できるはずです。

しかしながら、z/OSではジョブ・ステップは定義された順に実行される、という大原則があるため、実際には同時に実行できるステップ-2とステップ-3は順番にしか実行できません。同時に実行するためには、ステップ-2かステップ-3のどちらか一方を別のジョブとして切り離さねばなりません。
並列化できるジョブ・ステップを別ジョブに分離(分離したジョブの実行開始タイミングを合わせられない…)
ところが、並行して同時に実行させるために別ジョブに分離してしまうと、分離したジョブの実行開始と分離したジョブの出力データを入力にしている元のジョブのジョブ・ステップの実行開始タイミングを合わせることができません。z/OSとJES2の組み合わせでは、ジョブ-Aのステップ-1の終了を待ってからジョブ-Bを開始させたり、ジョブ-Bのの終了を待ってからジョブ-Aのステップ-4を開始させたり、といった先行/後続関係に基づくジョブやジョブ・ステップの実行制御を行うことができません。

そのため、MVSオペレーティング・システムが登場した頃(1970年代)のメインフレーム・コンピューターを利用した業務処理システムでは、オペレーターがジョブ-Aのステップ-1の終了をコンソール・メッセージで確認してからジョブ-Bの実行開始をコマンドで指示する、ステップ-4の実行前にジョブ-Bの終了を待ち合わせるためのプログラムを実行しておき、ジョブ-Bの終了をコンソール・メッセージで確認してから、ジョブ-Aで実行中のステップ-4の実行開始待ち合わせのプログラムにコマンドで応答を返して待ち合わせプログラムのステップを終了させてステップ-4を開始させる、などといったオペレーターによるジョブ実行制御が行われていました。
やがて、業務量やデータ量が増えるにつれてバッチ処理で実行されるジョブの数も増え、オペレーターによるジョブ実行のコントロールでは捌ききれなくなり、ジョブの自動運用ソフトウェアを導入することが一般化しました。ジョブの実行を、先行/後続関係に基づいてスケジュールする要望は40年以上もの昔から多くのユーザーにあったのですが、JES2にはその機能がないためジョブの自動運用の分野はISVによるソフトウェア・パッケージ製品の独壇場でした。
並列化したジョブをグループにまとめる(z/OS V2R2以降で利用できるグループ内ジョブの先行/後続関係に基づく実行制御)
z/OS V2R2のJES2に実装されたジョブ実行制御(JEC:JOB Execution Controls)機能は、複数のジョブをグループにまとめてグループ内のジョブを先行/後続関係でその実行を制御します。従来のジョブ・ステップとジョブの関係に加え、ジョブとジョブ・グループという新たな関係を構築します。順次で実行すべき処理はこれまで通りジョブ・ステップとして定義し、並行して実行可能なステップの前後でジョブに分離して、それらのジョブを先行/後続関係に基づいて実行を行わせることができます。先行/後続関係に基づいて関係づけられたジョブのまとまりが、ジョブ・グループという新しい概念です。ジョブ・グループを定義するため、JCLにも新しいステートメントが追加されました。

先程の例のジョブを、ジョブ・グループにまとめたものです。各ステップは、ジョブとして分割することになります(*3)。各ジョブののJCLは予めJES2にサブミットされていますが、ジョブ-A以外は、先行/後続関係によってホールドされます。
ジョブ-B(ステップ2a)とジョブ-C(ステップ2b)は、ジョブ-A(ステップ-1)の終了を待って実行が開始されます。さらに、ジョブ-D(ステップ-4)は、ジョブ-B(ステップ2a)とジョブ-C(ステップ2b)の両方の終了を待って実行が開始されます。
*3 ジョブ・グループにするからといって全てのステップを単独ステップのジョブにしなければならないわけではない。この例では、元のステップ数が4つしかなく、並行できる中間の2ステップがそれぞれ先行ステップの出力を入力にし、自分の出力を後続がステップが入力にしている関係で、結果として各ステップがジョブとして分離されることになっただけである。
//JOBGRPX JOBGROUP //* //JOBA GJOB //* //JOBB GJOB // AFTER NAME=JOBA //JOBC GJOB // AFTER NAME=JOBA //* //JOBD GJOB // AFTER NAME=(JOBB,JOBC) //* //JOBGRPX ENDGROUP // // //JOBA JOB (acct),CLASS=A,MSGCLASS=B // SCHEDULE JOBGROUP=JOBGRPX //STEP1 EXEC PGM=PROG1 //OUTPUT DD DISP=(,CATLG),DSN=PROG1.OUTPUT,LIKE=PROG1.MODELDS // //JOBB JOB (acct),CLASS=A,MSGCLASS=B // SCHEDULE JOBGROUP=JOBGRPX //STEP2a EXEC PGM=PROG2 //INPUT DD DISP=SHR,DSN=PROG1.OUTPUT //OUTPUT DD DISP=(,CATLG),DSN=PROG2.OUTPUT1,LIKE=PROG2.MODELDS // //JOBC JOB (acct),CLASS=A,MSGCLASS=B // SCHEDULE JOBGROUP=JOBGRPX //STEP2b EXEC PGM=PROG2 //INPUT DD DISP=SHR,DSN=PROG1.OUTPUT //OUTPUT DD DISP=(,CATLG),DSN=PROG2.OUTPUT2,LIKE=PROG2.MODELDS // //JOBD JOB (acct),CLASS=A,MSGCLASS=B // SCHEDULE JOBGROUP=JOBGRPX //STEP4 EXEC PGM=PROG4 //INPUT DD DISP=SHR,DSN=PROG2.OUTPUT1 // DD DISP=SHR,DSN=PROG2.OUTPUT2 //OUTPUT DD DISP=(,CATLG),DSN=PROG4.OUTPUT,LIKE=PROG4.MODELDS // //
最初にジョブ・グループをJCLで定義してサブミットします。ジョブ・グループは、JOBGROUPステートメントで始まりENDGROUPで終わります。続けてこのグループに属する各ジョブを定義します。各ジョブにおいては、JOBステートメントの後に、どのグループに属するかを示すSCHEDULEステートメントを定義します。サンプルでは、ジョブ・グループとグループに属する各ジョブを同じJCLストリーム内に定義していますが、最初にジョブ・グループをサブミットして、次にグループ内の各ジョブをサブミットする、という順序であればそれぞれのJCLはジョブ毎にメンバーを分けてかまいません。
JECの機能を利用すれば、これまでなら並列実行可能なステップがあっても後続ステップの関係で同じジョブ内で順番に実行せざるを得なかった処理や、大量のデータを複数ジョブに分割して実行したいが、そのプログラムの出力を入力にする後続処理があって単純に分割できなかった処理などが、JES2の機能だけでこれまで以上にバッチ処理のスループット(*4)を上げるような運用ができるようになりました。
*4 単位時間あたりの生産性もしくは処理能力のこと。バッチ処理ではスループットが重要視され、反対にオンライン処理では、個々のトランザクション処理のレスポンス・タイムが重要視される。