大規模なデータを日中システムに影響しないよう処理するためには、主にバッチ処理が用いられます。
汎用コンピュータが登場した1960年代からこの傾向は変わっておらず、現在もなお多くの企業でバッチ処理が活用されているのです。
そんな中、これまでまったく経験がなかったエンジニアが「君、明日からバッチ処理のシステム構築よろしく」なんてアクシデントに近い事態が発生することが往々にしてあります。(しつこいようですが本当にあります)
本稿では、そんなときのために必要なバッチ処理設計の基本からコツ、そして注意点までを解説していきます。
いきなりバッチ処理担当に任命されたエンジニアや、バッチ処理について予備知識を付けたいという方は是非参考にしてください。
バッチ処理設計の基本
バッチ処理のお決まり工程
バッチ処理は一見して複雑そうに見えますが、ほとんどは定型処理によるものでその内容はいたってシンプルです。
このように、バッチ処理設計では大まかに入力>加工>出力と3つの工程に分類することができます。
まず入力工程で必要なデータをファイルやDB(データベース)から取得し、それを加工工程にて必要なデータだけに絞り込みます。
同工程でデータをまとめたら、最後に出力工程でファイルやDBにデータを保管し完了です。
バッチ処理設計が複雑化するのはリカバリーポイントの増加やプログラムの属人化が原因で肥大化したシステムにあり、バッチ処理事態が複雑なプロセスではないのです。
この大まかな入力・加工・出力について詳細を以下にまとめます。
起動タイミング
バッチ処理は一般的に日中システムが稼働していない夜間や休日などに実行されます。
つまり起動タイミングを設計する必要があるのですが、主に“トリガー起動”と“定時起動”の2つに分類されます。
トリガー起動
データの閾値を超えた
APIへのリクエスト
定時起動
毎日A時起動
毎週B時起動
毎月C時起動
このように扱うデータの種類や、現状の処理環境に応じて起動タイミングを設定していきます。
データ入力
データ入力関しては、主に以下のようなファイルからデータを取得します。
- RDBMS(Relational Data Base Management System)
- CSVファイル
- 画像ファイル
- ログファイル
- Webサービス
データ加工
データ加工に関しては、主に以下のような方法で加工されます。
- 変換
- 集計
- マージ
- クリーニング
- べリファイ
データ出力
加工・集計されたデータは出力する必要があり、主に以下のような出力先が挙げられます。
- RDBMS
- CSVファイル
- メッセージ
- Webサービス
バッチ処理設計のコツ
バッチ処理はシンプルながらも設計のコツが数多くあり、ここではそのいくつかを解説していきます。
並列処理可能なポイント
大規模なデータを一括処理するという目的から、バッチ処理とは時間がかかるのが大前提です。
だからこそ日中業務に支障をきたさないために夜間や休日に行うわけですね。
しかし、ただ夜間・休日にバッチ処理を行うだけでは問題解決になっていません。
絶対的に避けなくてはならないのが、バッチ処理が翌朝や休日空けまで完了せず日中システムに影響を与えてしまう事です。
ちなみにこういった現象を“突き抜け”と言います。
つい数年前では某メガバンクによるバッチ処理突き抜けで、2日間システムダウンしたなんて事例もあります。
そこで重要となるのが並列処理可能なポイントを見つけ、処理時間の短縮化を図ることです。
処理フェーズごとに影響範囲が重なっていないポイントなどでは直列処理にするのではなく、並列処理にすることで時間短縮につながります。
ただし、並列処理にすると少なからず負荷がかかるので、システムリソースとの兼ね合いを見て設計しなければ結局突き抜けを起こす原因にもなります。
バッチ処理時刻を記録
バッチ処理には必ずと言っていいほどパフォーマンスの低下や問題が発生し、常に迅速な対応が求められます。
このような場合、まずはバッチ処理開始時刻や終了時刻の計算から始めるのでは初動がかなり遅れてしまいますね。
そこでバッチ処理開始時刻と終了時刻は必ず、ログやテーブルなどに記録されるように設定しておきましょう。
また、処理にかかった時間もログに記録しておくことでパフォーマンスの指標として確認することができます。
実行ログを記録
如何なるシステムにおいても実行ログの管理は重要であり、バッチ処理に関しても例外ではありません。
特にバックグラウンドで稼働されることの多いバッチ処理では、実行ログを記録していないとフィードバックが得られない状態となります。
つまり、実行ログがブラックボックス化してしまい障害の原因究明が困難になるのです。
障害対応のためにも実行ログの記録は必須事項と言えます。
データのライフサイクルを定義
バッチ処理によって生成された中間ファイルやテーブルといった副産物は、放置しておくとストレージを圧迫する原因となります。
こういったストレージの圧迫によりパフォーマンスが低下することも少なくありません。
データとしては既に価値はないが保管されているというデータに関しては、自動的に削除するよう設計しておくことを忘れないでください。
ただしここで注意する必要があるのはデータのライフサイクルであり、法律的な関係で一定期間保持しなければならないデータなども存在します。(主に経費データなど)
反対に、即時破棄すべきデータなども存在しますね。(マイナンバーデータなど個人情報に関わるデータなど)
データの種類によって適切なライフサイクルが異なるので難しいところですが、パフォーマンスの維持とコンプライアンスのためにもきちんと定義していきましょう。
オンライン処理との兼ね合いに注意
昨今ではビッグデータ活用に注目が集まっていることからも、ストリームデータ処理(ストリームデータ処理とは?リアルタイムデータ処理で広がるビジネスモデル)といったオンライン処理へのシフトが求められています。
そこで重要になるのが、オンライン処理を起点に連携処理方式を検討していくことです。
つまり、オンラインで必要最低限の処理を行いレスポンスし、残りのデータに関してはディレードやバッチ処理で対応するといった設計の必要性が高まります。
以上がここで解説するバッチ処理設計のコツですが、他にも様々なコツがあるのでトライ&エラーを繰り返していくなかでしっかりと学んでいくことが重要です。
バッチ処理設計の注意点
必要に応じたスケールアウトやスケールアップ
前述しましたが、バッチ処理は基本的にシステムリソースに余裕のある時間帯に行われるのがベターです。(夜間や休日)
そして最も注意すべきは突き抜けであることも解説しました。
そこで大切なのが、データの種類・量・性質などに応じてシステムリソースのスケールアウトやスケールアップを行うことです。
そのためにはクラウド環境でのバッチ処理設計などが理想的です。
例えばインテリジェントモデルが提供する大規模バッチシステム「ODIP(オーディップ)」では、IBMが提供するパブリッククラウドサービスSoftLayer上で起動させることができます。
フレキシブルに利用できるIBM SoftLayerではシステムリソースのスケールアウトやスケールアップなどを簡易的に行えるため、突き抜けなどのトラブル対策になります。
こうしたクラウド上で稼働するソリューションを採用することも、バッチ処理設計における注意点の一つでしょう。
メモリ使用量
システムリソースのスケールアウトやスケールアップが現実的でない場合、注意すべきはメモリの使用量です。
例えばバッチ処理とオンライン処理のリソースを別々に用意しているケースでも、十分に注意する必要があります。
バッチ処理のデータ量が増加するにつれメモリ使用率が増加するようなアルゴリズムを組んでいることも少なくないので、複数のバッチ処理を並行した場合メモリが不足する可能性があります。
まとめ
それでは最後に、今回のポイントを以下にまとめていきます。
- バッチ処理の基本工程は入力>加工>出力の3つに大別される
- データ入力・加工・出力を行うプラットフォームやフォーマットはある程度限定されている
- 並列処理できるポイントを把握して、可能な限り処理時間を短縮する
- 処理時刻や実行時間を記録することでパフォーマンスの評価や問題への対処に活かす
- 実行ログを記録することで障害原因のブラックボックス化を避ける
- データの種類に応じてライフサイクルを定義し、ストレージの圧迫を防止する
- バッチ処理とオンライン処理を並行させる場合は、オンライン処理起点で設計する
- データの種類・量・性質に応じてスケールアウトやスケールアップで対応する
- 常にメモリ使用量に注意を向け、効率化を心掛ける
いかがでしょうか?今回ざっくりではありますがバッチ処理設計の基本からコツ、注意点までを紹介しました。
現代のバッチ処理と言えばプログラムの属人化やシステムの肥大化により複雑さが増す一方であり、これからバッチ処理に関わる方からすれば難しい領域に感じることもあると思います。
しかし本質的にはシンプルなシステム設計であり、効率化の鍵はいかにコツを押さえて設計していくかにかかっています。
また、突き抜けの防止やスピーディな障害対応のためにも、注意点を常に留意しておくとが大切です。
これからバッチ処理に関わるエンジニアの方々にとって、本稿が設計を深く考えるきっかけになれば幸いです。