お手軽バッチ・パフォーマンス改善 – VIII
データセットのI/O効率を上げる(続き)
VSAMデータセットのバッファリング方法を変更する
KSDSのランダム・アクセスにおいては単にBUFNIでINDEXバッファー数を増やしても、INDEXコンポーネント自体へのI/Oは避けられません。同じランダム・アクセスでもRRDSと違い直接DATAコンポーネントをアクセスするのではなく、キーに対応したレコードを探すためにINDEXコンポーネントをアクセスする必要があり、どうしてもI/Oそのものが増えてしまいます。
そこでINDEXコンポーネントをメモリーに上げてしまい、メモリー内で索引を探すことでパフォーマンスを上げる方法がいくつかあります。INDEXはDATAコンポーネントに比べれば格納データ量が小さいため、メモリーに上げてしまっても数十から数百KB程度で収まることが多いので、極端にページングが増えることもありません。細かなI/Oを小刻みに出し続けるよりはるかにオーバーヘッドは少ないです。
拡張フォーマットのVSAMに変換する(z/OSのみ)
VSAMデータセットを拡張フォーマットVSAM データ・セットとして作成することができます。拡張フォーマットにすることでデータの圧縮やストライピング、4GBを超える大容量サイズなどのオプションも利用可能になりますが、必ずしもそれらの機能を必須で使う必要はありません。ここではその目的をSMBによるデータセット・アクセスを行うためとします。
SMB(システム管理バッファリング)はDFSMSdfpの機能でより効率のよいバッファリング制御によってI/Oパフォーマンスを向上させます。特にランダム・アクセスにおいては、CIアクセスのバッファー管理方式をLSR(ローカル共用リソース)方式に自動的に変更します。このため複数ブロックを単にまとめて先読みなどをするのではなく、バッファをキャッシュ・メモリーのように扱うことができます。これによってINDEXコンポーネントをメモリー上に常駐させるような制御ができます。
LSRは古くからVSAMの機能として提供されていましたが、使用するにはアセンブラー言語によるプログラミングが必要でした。SMBはDFSMSによって実装された機能で、対象となるVSAMデータセットをSMS管理データセットとして作成する必要がありますが、COBOLなど言語仕様でLSRを利用できないプログラムでも、プログラムを直すことなくLSR方式でバッファリング制御ができるようになります。
グラフはSMSの拡張フォーマット・データセットとして作成したVSAM/KSDSのランダム・アクセスにおける実行時間および発行されたI/O回数を示しています。左側はCIサイズをAMSデフォルトにしたもの、右側はINDEXは2KB、DATAは4KBのCIサイズにしたもので、それぞれJCLのDDステートメントでAMPパラメーターによるバッファー数を変更したものの実行結果です。バッファー数0はVSAMのデフォルト値を示します。拡張フォーマットであっても従来通りのバッファー制御ではパフォーマンス面でもさして違いはありませんが、ランダム・アクセスに適したSMBバッファリングを指定するとI/O回数は激減し、実行時間もそれに応じて短縮されています。CIサイズやINDEXレベルでの違いはありますが、概ね実行時間で約1/3に、I/O回数で1/5から1/3に短縮されています。
SMS拡張フォーマット・データセットであっても、ランダム・アクセスであればDATAコンポーネントは小さめのCIサイズの方が、パフォーマンス面では有利ではあります。しかしSMBを使用した場合はデフォルトCIサイズ(DATAコンポーネントは大きめ)のままでも十分なパフォーマンスが得られています。こうしてみると昔のようにいろいろ考え試行錯誤しながら最適なCIサイズを見つける、などということをしなくてもシステムに任せてしまう方が得策です。z/OSに関して言えば、VSAMはSMS拡張フォーマットに移行して、適切なSMBバッファリング方法を選択する、のがVSAMアクセスのパフォーマンス・チューニングの早道となるようです。
拡張フォーマットVSAM データ・セットはAMSのDEFINE CLUSTERでDSNTYPEにEXT属性を定義したDATAクラスを指定すれば割り振ることができます。
//ALLOCATE EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=* //SYSIN DD * DEFINE CLUSTER - (NAME(dsname) - DATACLAS(EXTVSM) - STORCLAS(SGRP1) - RECORDS(100000) - RECORDSIZE(500 500) - KEYS(10 0) - REUSE INDEXED) //
作成後にAMSのREPROでローディングすれば、そのままVSAMデータセットとして使用できます。あるいは次のようにICEGENERユーティリティーで既存のVSAMデータセットから直接コピーして作成してもかまいません。z/OS V1R7以降であれば、DDステートメントのDATACLASに代えてDSNTYPE=EXTREQを指定して割り振ることもできます。
//GENEXTVS EXEC PGM=ICEGENER //SYSPRINT DD SYSOUT=* //SYSUT1 DD DISP=SHR,DSN=UAP5.GRK7200.MASTER //SYSUT2 DD DISP=(,CATLG),DSN=UAP5.GRK7200.MASTER.EXTEND, // SPACE=(TRK,(1000,100),RLSE), // RECORG=KS,LRECL=500,KEYOFF=0,KEYLEN=10, // STORCLAS=SGRP1,DATACLAS=EXTVSM //SYSIN DD DUMMY //
SMBを使用するには、DDステートメントにAMPパラメーターでACCBIASを指定します。DOはランダム・アクセスを最適化することを示します。シーケンシャル・アクセスの最適化であればSOです。ACCBIASパラメーターはDATAクラスでRecord Access Bias=SYSTEMを定義していれば不要ですが、プログラムがACBのMACRFでDIRとSEQの両方を指定していると順次アクセスも考慮されたバッファリング制御となってしまいます。MACRFがDIRになっていればACCBIAS=DOと同じになります。ACBのMACRFはCOBOLであればFILE-CONTROLのACCESS ISがDYNAMICかRANDOMかの違いで決まります。ACCESS IS RANDOMでなければACCBIAS=DOを指定した方がランダム・アクセスの処理では実行速度がより向上します。
//SYSUT1 DD DISP=SHR,DSN=UAP5.GRK7200.MASTER.EXTEND,AMP='ACCBIAS=DO'
なおACCBIASがDOの場合、アクセスするデータセットの大きさにもよりますが、数MBから数十MBもの仮想メモリーを必要とします。ここに紹介したサンプルでは約10MBの拡張リージョンが追加で使われました。しかしメモリー量に見合うだけの効果はあると言えるでしょう。