リアルタイムVSバッチではなく、処理時間に合わせて選択する
バッチ処理とはそもそも悪なのか──。暮林氏のセッションはこの問いかけから始まった。バッチ処理が悪と見なされる風潮があるが、「もう少し広い視野で見直していきたい」と暮林氏は言う。
そのために暮林氏が提案したのは「オーダー」という概念で考えること。オーダーは物理学や工学でしばしば使われる用語で、桁の大きさを把握するために使われる。例えば光の速さは「3.0×10の8乗」などと表すことができる。つまり光の速さのオーダーは「10の8乗」と言える。
コンピュータの処理は種類によって求められるオーダーは異なる。例えばリアルタイム処理はWebやAPIなど即時応答が欲しい場合に用いられるので、1秒や0.1秒で処理が終わることが求められる。オーダーで表すと、「リアルタイム処理は10の-1乗や10のゼロ乗という世界が求められる」と暮林氏は説明する。対してバッチ処理は大量データを一定時間内に処理したい場合に用いられる。しかも夜間バッチなど、サイクルは日で回っていることが多く、動作時間では短いモノで数分単位、長いものだと数十時間に及ぶものあるなど、オーダーとしては非常に大きくなる。「10の3乗、4乗、5乗などのオーダーとなる」(暮林氏)
リアルタイム処理とバッチ処理だけではなく、即時応答が不要で要求が入ってくれば即バッチが動いて結果を返すディレイドバッチ(ディレイドオンラインとも)という方法もある。ディレイドバッチの処理時間は分単位。オーダーとしては10の1乗~3乗で表される。さらにもう一つ、リアルタイム処理に近いが即時応答が不要で、要求受付のみ即時に行う必要があり、処理もなるべく速く行いたい場合に適しているのが、ニアリアルタイム処理である。「ニアリアルタイム処理は速い場合はリアルタイム処理と変わらないこともあるが、オーダーは10の0乗や10の1乗で表される」(暮林氏)
オーダーで見れば分かるように、用途によっては最適な処理種別がある。それにもかかわらず、「リアルタイム処理ができないのならバッチ処理にするという方法論で選んでいたことが問題。そこから脱却し、目指す処理時間のオーダーに合わせて適切な処理形態を選ぶことが大事」と暮林氏は指摘する。
ニアリアルタイム処理を作成する方法
バッチ処理をニアリアルタイム処理に置き換えるにはどうすればよいのか。ニアリアルタイム処理の作成は「データパイプラインを作ることから始まる」と暮林氏は言う。データパイプラインはバッチで作成するジョブフローと見た目は似ているが「違いがある」と暮林氏。ジョブフローが着目しているのはいかにジョブを正確に処理するかであり、「ジョブフローを管理はあくまで処理順序を制御しているだけで、特にデータの中身を見ていない。とにかく戻り値がゼロで返ってくればよく、細かいことをする場合は、アプリケーション側でジョブフローに合わせた処理を書かなければならない」と暮林氏は説明する。一方のデータパイプラインは、データが一つずつバラバラに送られていくので、データの中身を見ることができる。その中身によって分流や合流、待ち合わせという処理制御ができるのだ。「このように、データパイプラインが着目しているのはデータなんです」(暮林氏)
ニアリアルタイム処理を簡単に作成する際にソリューションとしてレッドハットが推奨しているのが、Knativeである。Knativeはサーバレスのクラウドネイティブ・アプリケーションをビルドするためのコンポーネントを、Kubernetesに追加するエンタープライズレベルのオープンソースソリューション。2018年にGoogleによって設立されたプロジェクトで、その後、IBMやRedHat、VMware、SAPなどと緊密に連携して発展し、2022年3月2日にCNCF(Cloud Native Computing Foundation)のプロジェクトとして承認された。
Knativeでできることは「ニアリアルタイム処理だけではない」と暮林氏は続ける。第一に、Kubernetesの拡張なので、CRD(Custom Resource Definition)でシンプルなYAMLにできること。次にサーバレスの仕組みとしてオートスケーリングを利用し、ゼロまでスケールダウン、ゼロまでスケールアウトができること。また、にニーズに合わせたロールアウト戦略もとれること。さらに、SaaSなど多数のソースからのイベントを抽象化してまとめて扱うイベント統合の仕組みもある。加えて、その抽象化したイベントをハンドリングするイベントハンドルの仕組みや、Kubernetes Nativeな拡張性(プラガブル)を有している。
そしてもう一つ、ニアリアルタイム処理を作るためのソリューションとして暮林氏が紹介したのがKnativeで動くサーバレスコンテナプラットフォーム「Camel K」である。「起動時間の速いアプリケーションに向いている」(暮林氏)
Camel Kのプラットフォームでは次のようなことができる。まずは相互接続。「Apache Camelのコンポーネントにより、クラウドネイティブなやり方ですべてを接続できます」(暮林氏)
次にサーバレスなインテグレーション。第三にQuarkusをベースとしたランタイムでの高い効率性。またオーケストレーションも可能。「クラウドネイティブなインテグレーションパターンがすべてできる」(暮林氏)
そのほか、Knativeだけではなく、Kafka、OpenShiftなどのさまざまな環境に自動的に対応できること、開発者フレンドリーであることなどの特徴を持つ。
Camel Kを使うと開発がどのようにシンプルになるのか。それを表したのが次の図である。
最初のステップでは開発者が統合定義を作成。そして第二ステップで開発者がクライアントコマンドを実行して統合を実行する。さらに第三ステップでCamel Kオペレータが新しい統合リソースを認識し、自動的にビルドしてデプロイする、という流れだ。ニアリアルタイム処理がどのぐらいのオーダーなのか、その感覚をつかむため、暮林氏は処理に要する時間を計測する仕組みも入れてデモを実施。リハーサル時のコールド時が14秒(1.4×10の1乗)、ウォーム時は43ミリ秒(4.3×10の-2乗)に対して、デモでの実測値はコールド時がリハーサル時とほぼ同じ14秒。ウォーム時はすべて起動しているときは10の-3乗というオーダーで処理が実施された。ちなみにコールド時が遅いのは、スピンアップに1個あたり5秒弱かかるからである。またCamel Kで分岐や合流のパイプラインも容易に書くことができる。
さらにYAMLを書くツールとして、暮林氏は「Karavan Designer」も紹介。Camel KによるIntegration DSLをグラフィカルにコーディングできるツールで、「Visual Studio Codeのプラグインとして利用するのが最も簡単だが、スタンドアローンで動くモノもある」と暮林氏は言う。
現場で使える! 実践的なニアリアルタイム処理とは
では、ニアリアルタイム処理は現場でどのように使うことが求められるのか。暮林氏は実践的なニアリアルタイム処理の使い方についても紹介してくれた。
例えば画面入力をベースにバッチが夜間に動くケースでは、本来画面を直したいところだが、事情があって手が出せないことで、バッチが処理できないデータがデータベースに入る。それが1件ならよいが、複数あるとバッチのリカバリ回数が増え、突き抜けてしまうことがある。「このような問題は、オンラインとバッチの間にニアリアルタイム処理を挟むことで解決できる」と暮林氏。画面からデータベースに入れるまでは先と同じだが、DebeziumというChange Data Captureを介して、Kafkaに入れるところからがニアリアルタイム処理となる。エラー判定をするマイクロサービスを起動し、エラーと判定されると入力した人に何らかの形で通知をする。またチェックして問題がなかったデータはそのままデータに書き戻し、バッチ処理を進める。実際にこの仕組みのデモを実施したところ、10秒から15秒ぐらいで処理が終了。「画面を直すよりも気軽にマイクロサービスとして実装できるのでお勧めです」(暮林氏)
「ニアリアルタイム処理はリアルタイム処理と勘違いするほどの速度で処理できる」と暮林氏。だがバッチ処理をニアリアルタイム処理に置き換えるにはやはり投資が必要になるので、費用対効果を示す必要がある。「だがIT的な視点だけでは詰まってしまうので、ビジネス的な視点も入れて計算すること」と暮林氏はアドバイスする。
まずはビジネス的な視点での計算は次のように行う。年間あたりの平均損害額は、年間売上×障害発生率(%)×機械損失率(%)と計算式で表される。例えば10億円の売上がある企業で、障害発生率が頻繁(週1)、それにより10%の顧客が離れてしまうケースでは、10億円×14.3%×10%=1430万円という計算式となる。5年でもとをとるなら損益分岐は1430×5=7150万円となる。
IT的な視点の計算式は、年間あたりの平均損害=年間売上×対売上IT投資割合×ブロック率となる。日本情報システムユーザー協会「企業IT動向調査報告書2021」によると、対売上IT投資割合の平均は1%なので、先の企業の場合、10億円×1%×20%=200万円となる。こちらも5年でもとをとるなら損益分岐は200万円×5=1000万円となる。つまり損益分岐は合計8150万円ということだ。「投資対効果という点でも経営層を説得できる要素があるのか。その点も考えて、ニアリアルタイム処理を検討してほしい」(暮林氏)