Red Hat Decision Manager でよく聞かれる話 (FAQ) その4

こんにちは。Red Hat Decision Manager ジャック4日目です!

昨日の内容

に引き続き、その4をお送りします。

ルールエンジンでどんなことができるのか?

業務内容と照らし合わせると、ルールエンジンは下記のようなことに適用できます。

f:id:mumeno:20200610203302p:plain

ルールエンジンでできないことは下記になります。

  • 画面や帳票の生成
  • データサービスへの読み書き
  • 他システムとの連携
  • トランザクション処理
  • セッションプール等の管理
  • メールの送信

普通のif-then-elseと何が違うのか?

Java/C言語などでロジックを記述する場合、if文、for文、while文、case文等を駆使して書くのが一般的と思います。例えるならば、通常のロジックは「網の目」を作っていくような感覚です。一方、RETEアルゴリズムをベースとしたPhreakアルゴリズムを搭載するルールエンジンは、when - then のみでelseを記述しません。また、for文 while文等も記載しません。

Red Hat Decision Managerのルールエンジンはパターンマッチングという考え方から来ています。パターンマッチングとは、「神経衰弱ゲーム」を思い浮かべていただくとよいです。1枚めくって、それと同じ絵柄の違う一枚を引き当てると(whenに相当)それを自分の得点とする(thenに相当)ようなゲームです。ゲームではマッチが完了するまで繰り返します。 ルールエンジンでは、whenの「パターン」にマッチするかどうかを判定します。もしマッチすれば、thenを行います。また、繰り返し処理はマッチした分だけルールエンジンが勝手に処理してくれます。

一般的なプログラムでのif-then-else のelseは、条件にマッチしなかった場合の行動になります。ルールエンジンではelseに相当するパターンで何かを行う必要がある場合、else 相当する条件を whenに書き、thenを構成します。 一見するとルールが増えて面倒なことをやっているように思えますが、ルールをwhenとthenだけで構成することで、構造としてはシンプルになります。 whenにマッチすればthenを行う、whenでマッチしなかったらthenは行わない。 この法則を徹底することで得られるメリットは、必要な場合だけルールとして書き、不必要な場合は書かない、もしくは不必要になったら削除する(=メンテナンスが容易になる)ということです。

今までのif-then-else/for/while文形式の場合、ifの中にwhileがあり、elseの中にさらにifがあり... となって、まさに「ロジックのスパゲッティ」が生成されてしまいます。そして、要らなくなったロジックは消していましたでしょうか?殆どの場合、ロジックを消すことによる副作用が見えず、死蔵されてきているのではないかと思います。その使っていないロジックも考慮した上で新しいロジックを追加していくものですから、どんどん複雑化し、切り出すことも不可能になってしまいます。

「ロジックの断捨離ができる」アプリケーションとなっていることで、常に単純化ができるようになります。これが「持続的にメンテナンス可能なシステム」であり、ルールエンジンとスクラッチ開発の大きな違いです。

ちょっと触ってみたいという方向けに、有償ハンズオンの資料部分のみを下記サイトで公開しております。 http://redhat.lookbookhq.com/rhdm_handson2019

ルールエンジンの呼び出し方は?

POJOでの呼出し、RESTでの呼出し方があります。何にせよ、大本になるものは、KieServicesになります。説明することが少々恥ずかしくなりますが、Kieは “Knowledge is Everything” から来ているらしいです。KieServicesはルールエンジンを動かす・支援する機能を生成するためのインターフェースで必ず必要になります。

KieServicesからKieContainer を生成します。KieContainerはまさにルールを動かすためのコンテナであり、KieBaseやKieSessionを生成することができます。 KieBaseはルール本体です。作成したルールはファイルなどからKieBaseに格納されます。KieSessionは実際にFactを投入したりルールを動かすためのセッションであり、ルールエンジンの実体になります。

POJOの場合はこれらのKie APIを組み合わせてルールの実行を行います。 Red Hat Decision ManagerにあるExecution Serverを利用すると、上記のようなKieAPI関連のオブジェクト生成を全て隠蔽して、RESTアクセスで行うことができます。(KieContainerID、KieSessionIDはパラメータとして渡す必要はあります)

バッチ処理に使えるのか?

Red Hat Decision Managerは、オンラインの処理にもバッチ処理にも利用可能です。ルールエンジンに投入するデータ(FACT)の形として、1件でも複数件でも同じように扱えるようなルールを記述しておくと、オンラインとバッチで同じルールを利用することが可能です。

しかしながら、バッチ処理といっても数千万件のデータを一度に扱おうとすると、ルールとデータ間での組み合わせ数が爆発的に増えてしまい、メモリの枯渇や性能が出ない場合があります。データとデータの相関関係がない範囲で、一度に投入するFACTの数に制限を設けて実行することをお勧めしております。(ルールを呼び出す側でデータを分割してルールを繰り返し実行する、データは一度Queueに入れて、Publish/Subscribeのような仕組みを利用してルールエンジンを多重化するなど)

ルールの数や投入するデータの量、項目数などに依存するため、何件ずつ処理を行うのが良いのかは一概に申し上げられません。是非、1件、2件、5件、10件、20件、50件、100件... のように数を増やしながら、許容できるTurn Around Timeとメモリ使用量となるような件数を見つけ出して、最適な件数を決めることをお勧めします。

DRLとかが独自言語で、他社との可搬性とかあるのか?

DRL(Drools Rule Language)はUpStreamコミュニティであるDrools.orgにて制定した形式になっており、そのままRETEアルゴリズムを利用している他社のルールエンジンで利用することはできません。しかしながら、例えば同じRETEアルゴリズムを搭載するIBM社のOperational Decision Manager製品で使用されているIRL(ILOG Rule Language)は、DRLと言語としての構造はかなり似通っております。その他の会社製品では書き方は異なるものの、ルールの考え方は同一であり、呼出し方なども含めたアーキテクチャとしては同じなので、原理原則に基づき正しく実装されたルールにおいては、乗換えを行う場合もゼロから作り変えるほどの労力は必要無いと思われます。

最適化は同じデータであれば同じ結果となるのか?

Red Hat Decision Managerの一つの機能として、Business Optimizerという、組合せ最適化のための機能があります。ルールエンジンを使って、沢山ある組み合わせの中からより良い組み合わせを探索することができて、いままで担当者が気づかなかったような、より良い組み合わせをITの力を使って高速に見つけることができます。

組み合わせ問題を解く際には、どの組合せから始めるかによって最適解が出るまでの時間が変わります。これは与えるデータを変えるという意味もありますし、最初のマッチングを作る時にランダムに行うという意味もあります。ですが、ランダムでしか行えないとすると、探索手順の妥当性などが検証できなくなります。

Business Optimizerでは、解の求め方をSolverConfig.xmlで定義しています。Solverの実行モードは、この中にある タグで設定をします。DefaultではREPRODUCIBLE となっており、特殊な設定をしない限り再現性はあります。開発時はREPRODUCIBLEで行うことでバグの発見がしやすくなります。 一方、本番環境ではPRODUCTIONとすることをお勧めします。組み合わせの作成をランダムにすることで、より良い解をより高速に求められる確率を高める設定となります。

ルールのアクションでは何ができるのか?

ルールエンジンはディシジョンサービスとも定義できます。サービスとは、要求を投げたら期待する答えが返却される形の概念です。ルールエンジンはアプリケーションから呼ばれて、アプリケーションに答えを返すだけが仕事になります。

従って、ルールエンジンのアクション部分(thenの部分)において、他のWebサービスを呼び出す、メールを送信する、DBやQueueにデータを書き込む等のアクションを行うのは適切ではありません。Javaのコード自体は書けてしまうので技術的には出来てしまいますが、アーキテクチャとして制限を設けて、閉じた世界に徹することをお勧めします。サービスの概念を遵守し、ディシジョンサービスは答えを返すのみのアクションとしましょう。データサービスやメッセージサービスを利用する場合は、ルールの呼び出し元(各サービスを連携するアプリケーション)にて適切なサービスにデータを渡す形とします。

いかがでしたでしょうか。 一旦はこちらで終了とさせていただきますが、皆様からのリクエストやお客様からのご質問が増えてきたらその5〜を書きたいと思います。

Chief Technologist 梅野

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。