バッチ処理を再考する

最近そもそもバッチ処理というものを知らない人達を見ることが多くなりました。某プロジェクトで「いや、ストプロってよくわからないんですよ。最近書いたことないし。」という話をずーっと聞いていたのですが、本人はバッチ処理という意味で話していたことが後から判明した、ということがありました。

ああ、この人はSQLでのバッチ処理しか知らないのですね、とちょっと衝撃ではありました。とうとうそーゆー時代になったかと。

まず、誤解のないようにいうとバッチ処理、という言葉自体はIT固有のものではないです。生産管理や物流や、そういった業務では普通に「バッチ」という言葉をIT以外で使います。ただし意味はある程度同じで、「一定の塊を一度に処理をする」ということです。物流システムの業務要件なんかを詰めているとバッチっていうと、どっちのこと?なんて普通に聞かれたりします。その意味ではバッチの対義語がリアルタイムというのは厳密にいうとちょっとおかしい。正直、厳密に言わなくともかなりおかしい。

いずれにしろ一定の処理を固まりで一気に処理をすると意味では、システムには割と頻繁に見られる「処理のスタイル」がバッチ処理ということになります。

そんなこんなで、バッチでの考え方については自分で一回まとめておきます。リアルタイムがどうかとかdisる前に、そもそもバッチってどう考えてますか?という自分なりのまとめですね。

1.元々の起こり
バッチ処理は実は業務的な必然性はもともと、それほどありません。特にバッチ処理の要請は、汎用機資源が貴重だった時代に、夜間の空いている資源をうまく利用できないか?という視点で考え出された計算資源の有効な利用方法でした。したがって、「今やる必要がない処理は後に回す」という発想がベースにあります。いまでも時々顔も見せる発想ですね。従って経緯から言えば、資源が割といろいろ余り出せば、基本的にバッチ処理にする必要は本来はないですね。

2.リアルタイムという言葉について
バッチの対義語に近い発想が“リアルタイム処理”です。
まず確認しておくと、ハード・リアルタイムが厳密な意味でのReal Time(実時間)であり、これは組み込みやそのためのOSのための用語です。したがって、ちゃんとした日本語を使うのであれば、リアルタイム処理というのは、本来は意図的に区別して使うべきです。とはいえ、一般には、“リアル・タイム”というと「すぐに処理が終わるという意味での“リアルタイム”」という意味が普通の用語になっています。(ここでは一応語弊をなくすために、いわゆる“リアル・タイム”処理はオンライン処理という言い方で代替します。)

Hadoopなんかを使ったり、オープン系の業務系処理で話をしていたりすると、普通に「”リアルタイム”で処理できないのか?」とか「Hadoopで”リアルタイム”処理」という厳密に言うと間違った言葉がどうしても出てきます。ハードウェアなギリギリな組み込み屋界隈で、リアルタイムで!という話をすると「それどっちよ?」って聞かれたりします。「は?リアルタイムって言ったら、リアルタイムですよ。」なんて答えたら、以降、エンジニアとしては取り扱ってもらえなくなることもあるので気をつけましょう。個人的に昔、こういった手合いの頑固おっさん軍団とやり合った経験があるので、やたら滅多ら不用心にリアルタイムという言葉を振り回すのは、ちょっと抵抗があります。

3.バッチ処理vsオンライン処理という政治闘争
さてここから本題ですが、従前のバッチ処理は「古くさい」というイメージもあり、「“リアルタイム”処理やオンライン処理が格好良くて、今風である」という発想がありました。今だと逆にあまりにステレオ・タイプな発想で、それはそれで黴臭い発想ではありますが、未だにこの辺にカブれている40代後半から60代前半の中途半端オープン化世代は厳然と存在します。曰く「バッチは遅くて、リアルタイムがナウでヤングだぜ」・・ (尚、それ以前の世代は汎用機を黎明期からかっちりマスターしていたので、今からみると逆にバランスがとれている感じすらしますが・・)

この延長線上に、「旧来勢力の守旧派抵抗シンボルとして」のバッチ処理と「先進的な革新的なアグレッシブなシンボルとして」のリアルタイム処理という、超絶紋切り型な表現の刷り込みが、しばしば政治的な意図とともに登場することになります。自分も、某プロジェクトでは政治闘争にバリバリに巻き込まれ、よりによって「リアルタイム処理ですから!」とか言い放つ羽目になったこともあります。・・「リアルタイムですから!」とハード・リアルタイムでもないにも関わらず、「声高に」言い放つメッセージがある場合、経験的には大抵はなんらかの意図があります。こうなると、もはやエンジニアリングの話ではないです。本来は「普通に処理が速いです」と言えばいいだけですから。

そういった流れにあるリアルタイム処理万歳主義は、(ま、実は自分も以前はそうだったのですが、・・というか汎用機がキライでしたね。偉そうなおっさんが蘊蓄たれるシステムで、出来る事が限られている割には、コストが高かった、という印象です。)かなりバッチを目の敵にします。

・・・・・んで、残念ながら玉砕します。問題はここです。

理由は簡単です。実務上は「システム的に非同期な、業務的な同期処理」が厳然と存在するからです。特にバックエンドで。・・・なので、どうやってもなくならないのですよ。残念ながら。「まとめて処理をしないと業務上意味が無い」データや処理があるということです。

4.バッチ処理の背景にあるものは何か?
まず業務的な要請に入る前に、バッチ処理の要請を二つに分けておきます。一つは業務的な要請ですね。もう一つはシステム的な要請。まず簡単な後者のほうから整理します。

4-1.システム的な要請でのバッチ処理要するにパフォーマンスがバッチ処理の方が出る、というケースです。オンライン処理でひとつひとつ処理をしていたらとても間に合わない、という場合にバッチ処理をおこなってバルクで捌く、という例です。原則として、これはシステム側の「都合」です。従って本来的には、オンライン処理とバッチ処理は透過的に扱えなければならない。べき論で言えば、全部ミドルウェア(またはハードウェア)で吸収すべきです。同じ設計・同じ実装で、実行時にオンラインかバッチかは、実行基盤側が判断し最適化すべきです。個別に来たらそのまま処理しろ、大量にまとめてきたら間に合わないのでバルクに切り替えろ、という流れですね。

残念ながらハードウェアのローレベルな処理ならばともかく、上位層になるほど複雑さが増すため、そうそう簡単にはいきません。とはいえ、より処理の効率化を考えるのであれば、普通に挑戦されるところではあります。このコンテクストでのバッチ処理vsオンライン処理は、純粋に技術的な勝負になるので、存分にやりあうべきでしょう。適材適所論の前に、技術やコストを見ながら考える問題です。尚、資源パワーの制約がないのであれば、個人的に全部オンラインにすべきだと思っています。効率性の重視や、一定の制約があるであればバッチ処理とのコンビネーションになるか、または、溜めておいてのフルバッチ処理ですね。

4-2.業務要請としてのバッチ処理もう一つの要請は業務的な要請です。個人的にはバッチ処理の「本質」はこちらです。何をどうやろうとオンライン処理は「論理的に困難」というものです。

詳しく説明します。まず、経済主体の実体的なエンティティは、なんにしろ観測・測定の問題が必ず発生するので、一定の「区切り」で実務的な同期処理を行うことが必要です。受発注・物流・販売・決済・コスト計算・・・すべてにおいてです。人の動きやもの動きのタイム・フレームは、個々に違います。その情報は一定の間隔やタイミングで同期処理を行うことが必要です。これはリアルタイム処理ではありません。「せーのでタイミング」を計って処理することが必要です。そうでなければ、「会話」ができません。時間軸を整える必要があります。要は「だらだら業務データを渡されても処理はできませんよ。こっちにはこっちの都合があるので、そこに合わせてください」という話です。

この時間軸の調整が業務要請から来るバッチ処理の主たる目的であり、それ以外の処理は極論を言えば、オンラインで処理が可能です。大事なのでもう一度いいますが、時間軸の調整以外の処理は、原則としてオンラインで処理できます。また、するべきだと個人的には考えています。やはりバッチ処理は業務上のコストが高い。後述するように運用コストが確実にあがります。

また逆に、タイム・フレームの処理をバッチ処理でなく、オンライン処理で行うというのは筋が違います。無理にやると破綻します。やって不可能ではないですが、かなり高度な業務設計を必要とします。例えば、速度の違う飛行機を並べて飛ばして、飛行機間に伸縮自在なはしごを渡して、無事にもののやり取りをするようなものです。

原則論としては、仮にシステム制約がない場合、バッチ処理にするか、オンライン処理にするかどうかは、システム要請ではなく、業務要請によるべきです。そして、当たり前ですが、現実には、システム制約がない、ということはありえないので、業務要請とシステム要請が混在します。ポイントは、この要請は分けて考えるべきであり、その上でバッチ処理なのか?オンライン処理なのか?と判断すべきです。これが出来ていないと、大抵の場合はシステム開発後に手戻りや修正が発生します。また、簡単に政治ネタになります。・・ところが、これが意外に難しいですね。業務要請がしっかり見えてないと判断を間違えます。

5.超高速なバッチ処理はリアルタイム処理と同じか?
さて問題は、バッチ処理をしている「時間」の問題です。この処理の時間の中では「バッチ処理をしている時間と、その同期を取るべき実時間は切り離されている」ということになります。一定の時間断面のスナップショットをとって、その瞬間での同期をとるのであれば、その同期処理の間に、もうその同期対象は動きだしています。同期を取るためには非同期な空間をつくらなければならないという一種のパラドキシカルな処理がバッチ処理になります。業務要請でのバッチ処理で面白いポイントはこの逆説的な状況に、業務例外が割り込んでくるという点です。取り扱いが非常に面倒になりますが、逆にいうと腕の見せ所になりますね。業務例外が発生した段階で、もう一度同期を取り直す必要が発生することが当然発生します。その場合のコストを最小限にする仕組みが必要になります。

ところが、厳密な意味でのリアルタイム処理は、先読みをしながら、その同期対象と同一の時間空間で処理を行うので、そうではありません。処理の対象の処理時間と、対象の持っている時間それ自体は同期が取れています。処理が完了した段階では、完了した時制に基づいての結果になっている、ということになります。リアルタイム処理とバッチ処理の違いは本来は、論理的な時間軸の捕まえ方の違いです。いわゆる超高速バッチとリアルタイム処理が「違う」ということはわかると思います。実際上の効果はそれほど大きくはないでしょう。ただし意味がまるで違います。処理が終わったときの時制が過去なのか現在なのかという違いです。

6. それでもバッチ処理は速い方がよいわけで。
とはいえ、バッチは処理が速い方が圧倒的に運用上は有利です。業務運用上は、より正確(実時間空間に近い)なデータがあった方がデータの取り回しや「情報の鮮度」がよいので、バッチの処理時間は短ければ、短い方ほど何かと都合が良い、ということにもなります。先ほど、指摘した業務例外の割り込みについての手当もコストが安くつきます。

翻って考えると、夜間バッチ処理は、そもそものことの起こりとは別に、逆説的ですが、この要請を別の側面から調整してきたとも言えます。すなわち夜間は業務が停止するので、バッチ処理の時間の最中は、事実上「実時間がとまったかのように」考える事できる=出来上がったデータのユーザビリティが向上するということになります。夜間バッチは「バッチのスピードを上げるというよりも、実時間の流れが止まっている(夜間は営業していない)ので、データの維持コストが低い」という、ある意味ではバッチ処理のスピードを上げるということと同じ効果が「結果として」得られているということです。・・・ということは、「眠らない世界」になってくるとバッチのコストは逆に高くつくことになるということになります。

7. まとめ
こんな感じです。自分の拙い経験ですら、このレベルの深さが簡単に出てしまうのが、バッチ処理とオンライン処理(または“リアルタイム”処理)の現実です。安易なマーケティングや政治ネタでのバッチだ、リアルだ、という言葉遊びは、百害あって一利なしです。

また、バッチとオンラインの使い分けは「時間」をどう制御するか、という一種の魔術的な発想が必要です。業務系のプロ(または守護神とか)と言われる人たち、これはいわゆるhackerとはちょっと違う人種なのですが、まずこの「時間」の操作が抜群にうまい。業務系の実時間は実は絶対時間ではないのです。業務の時間は一様ではない。これは、同様にシステムでの時間も絶対時間ではない。これもまた同じです。業務系の時間の操作とシステム系の処理の時間を操作することで、「どう考えても、この業務は回る訳がないのだが・・・」ということをやるし、また特に障害発生時に、普通に見ると絶望的に不可能なリカバリータイムを、圧倒的な段取りとスケジューリングで圧縮・カバーアップしていきます。

オンライン処理とバッチ処理は、自在に使いこなすべき道具立てです。変なマーケティングワードや、因習的な政治用語に踊りを踊るのではなく、なぜ?どう使うのか?という点に注力すべきです。私の個人的な意見はともかく、各自がそれぞれにポリシーを持つに値する「技術」だと思います。