第22章 DRL 使用時のパフォーマンスチューニングに関する考慮点
以下の主要な概念または推奨のプラクティスを使用すると、DRL ルールとデシジョンエンジンのパフォーマンス最適化に役立ちます。このセクションではこの概念をまとめており、随時、他のドキュメントを相互参照して詳細を説明します。このセクションは、Red Hat Process Automation Manager の新しいリリースで、必要に応じて拡張または変更します。
- パターンの制約のプロパティーおよび値は左から右方向に定義する
- DRL パターンの制約では、ファクトプロパティー名は演算子の左側に、値 (定数または変数) は右側に配置されるようにします。プロパティー名は常に、インデックスの値ではなく、キーでなければなりません。たとえば、 - Person( "John" == firstName )ではなく- Person( firstName == "John" )のように指定します。制約のプロパティーと値を右から左に定義すると、デシジョンエンジンのパフォーマンスが低下する可能性があります。- DRL パターンおよび制約の詳細は、「DRL のルール条件 (WHEN)」 を参照してください。 
- パターン制約では他の演算子よりも等価演算子タイプをできるだけ使用する
- 
							デシジョンエンジンは、ビジネスルールロジックの定義に使用可能な DRL 演算子タイプを多数サポートしていますが、等価演算子 ==の評価を最も効率的に実行します。実用的な場合には、他の演算子ではなく、この演算子を使用してください。たとえば、パターン (Person( firstName == "John" )) はPerson( firstName != "OtherName" )よりも効率的に評価されます。等価演算子だけを使用すると実用的ではない場合があるため、DRL 演算子を使用するときはビジネスロジックの要件とオプションをすべて検討してください。
- 最も制限の厳しいルールの条件を先にリストする
- ルールに複数の条件がある場合には最も制限の厳しい条件から順にリストしてください。こうすることで、最も制限の厳しい条件が満たされていない場合は、デシジョンエンジンがすべての条件セットを評価せずに済むようになります。 - たとえば、以下の条件は、航空券とホテルをあわせて予約した旅行者には割引を適用する旅行予約ルールの一部です。このシナリオでは、ホテルを予約するお客様がこの割引を受けるために航空券をあわせて予約することはほぼないため、ホテルの条件はほぼ満たされず、このルールは実行されません。そのため、必要のない航空券の条件を頻繁に評価しないため、1 つ目の条件の順番のほうがより効率的です。これは、1 つ目の条件では、ホテルの条件が満たされていない場合に不要かつ頻繁に、航空券の条件をデシジョンエンジンが評価せずに済むためです。 - 優先条件の順番: ホテルと航空券 - when $h:hotel() // Rarely booked $f:flight() - when $h:hotel() // Rarely booked $f:flight()- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 効率の悪い条件の順番: 航空券とホテル - when $f:flight() $h:hotel() // Rarely booked - when $f:flight() $h:hotel() // Rarely booked- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - DRL パターンおよび制約の詳細は、「DRL のルール条件 (WHEN)」 を参照してください。 
- from句を過剰に使用する、サイズの大きいオブジェクトコレクションで反復を回避する
- 以下の例のように、サイズの大きいオブジェクトコレクションで反復を行う DRL ルールでは - from要素の使用を回避してください。- from句を使用した条件の例- when $c: Company() $e : Employee ( salary > 100000.00) from $c.employees - when $c: Company() $e : Employee ( salary > 100000.00) from $c.employees- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - このような場合には、デシジョンエンジンはルールの条件が評価されるたびにサイズの大きいグラフを反復するので、ルール評価の妨げになります。 - 他の手段として以下の例のように、サイズの大きいグラフが含まれるオブジェクトを追加してデシジョンエンジンが頻繁に反復作業を行うのではなく、コレクションを KIE セッションに直接追加して、条件内でコレクションを結合します。 - from句なしの条件の例- when $c: Company(); Employee (salary > 100000.00, company == $c) - when $c: Company(); Employee (salary > 100000.00, company == $c)- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - この例では、デシジョンエンジンは 1 回だけリストを反復して、ルールの評価を効率化します。 - from要素または他の DRL 条件要素に関する情報は、「DRL でサポートされるルール条件要素 (キーワード)」 を参照してください。
- ロギングのデバッグには、System.out.printlnステートメントの代わりに、デシジョンエンジンのイベントリスナーをルール内で使用する
- ルールのデバッグやコンソール出力に、 - System.out.printlnステートメントをルールアクションで使用できますが、多数のルールに対してこれを行うと、ルール評価の妨げになります。別の効率的な方法として、できるだけ内蔵のデシジョンエンジンイベントリスナーを使用してください。このイベントリスナーが貴社の要件に満たない場合には、Logback、Apache Commons Logging、Apache Log4j など、デシジョンエンジンがサポートするシステムロギングユーティリティーを使用してください。- サポート対象のデシジョンエンジンのイベントリスナーおよびロギングユーティリティーに関する詳細は、Red Hat Process Automation Manager のデシジョンエンジン を参照してください。 
- drools-metricモジュールを使用して、ルール内の障害物を特定する
- drools-metricモジュールを使用すると、特に多くのルールを処理する場合に、遅いルールを特定できます。- drools-metricモジュールは、デシジョンエンジンのパフォーマンスの分析にも役立ちます。- drools-metricモジュールは、実稼働環境で使用するためのものではないことに注意してください。ただし、テスト環境で分析を実行することはできます。- drools-metricを使用して意思決定エンジンのパフォーマンスを分析するには、最初に- drools-metricをプロジェクトの依存関係に追加します。- drools-metricのプロジェクト依存関係の例- <dependency> <groupId>org.drools</groupId> <artifactId>drools-metric</artifactId> </dependency> - <dependency> <groupId>org.drools</groupId> <artifactId>drools-metric</artifactId> </dependency>- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - drools-metricを使用してトレースログを有効にする場合は、次の例に示すように、- org.drools.metric.util.MetricLogUtilsのロガーを設定します。- logback.xml 設定ファイルの例 - <configuration> <logger name="org.drools.metric.util.MetricLogUtils" level="trace"/> ... <configuration> - <configuration> <logger name="org.drools.metric.util.MetricLogUtils" level="trace"/> ... <configuration>- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - または、 - drools-metricを使用して、Micrometer を使用してデータを公開できます。データを公開するには、次の例に示すように、選択した Micrometer レジストリーを有効にします。- Micrometer のプロジェクト依存関係の例 - <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-jmx</artifactId> <!-- Discover more registries at micrometer.io. --> </dependency> - <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-jmx</artifactId> <!-- Discover more registries at micrometer.io. --> </dependency>- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - Micrometer の Java コードの例 - Metrics.addRegitry(new JmxMeterRegistry(s -> null, Clock.SYSTEM)); - Metrics.addRegitry(new JmxMeterRegistry(s -> null, Clock.SYSTEM));- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - ロギングと Micrometer のどちらを使用するかに関係なく、システムプロパティー - drools.metric.logger.enabledを- trueに設定して- MetricLogUtilsを有効にする必要があります。オプションで、- drools.metric.logger.thresholdシステムプロパティーを設定することで、メトリクスレポートのマイクロ秒単位のしきい値を変更できます。注記- しきい値を超えるノード実行のみが報告されます。デフォルト値は - 500です。- ロギングを使用するように - drools-metricを設定した後、ルールを実行すると、次の例に示すようにログが生成されます。- ルール実行出力の例 - TRACE [JoinNode(6) - [ClassObjectType class=com.sample.Order]], evalCount:1000, elapsedMicro:5962 TRACE [JoinNode(7) - [ClassObjectType class=com.sample.Order]], evalCount:100000, elapsedMicro:95553 TRACE [ AccumulateNode(8) ], evalCount:4999500, elapsedMicro:2172836 TRACE [EvalConditionNode(9)]: cond=com.sample.Rule_Collect_expensive_orders_combination930932360Eval1Invoker@ee2a6922], evalCount:49500, elapsedMicro:18787 - TRACE [JoinNode(6) - [ClassObjectType class=com.sample.Order]], evalCount:1000, elapsedMicro:5962 TRACE [JoinNode(7) - [ClassObjectType class=com.sample.Order]], evalCount:100000, elapsedMicro:95553 TRACE [ AccumulateNode(8) ], evalCount:4999500, elapsedMicro:2172836 TRACE [EvalConditionNode(9)]: cond=com.sample.Rule_Collect_expensive_orders_combination930932360Eval1Invoker@ee2a6922], evalCount:49500, elapsedMicro:18787- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - この例には、次の主要なパラメーターが含まれています。 - 
									evalCountは、ノードの実行中に挿入されたファクトに対する制約評価の数です。Micrometer でevalCountを使用する場合、データを含むカウンターはorg.drools.metric.evaluation.countと呼ばれます。
- 
									elapsedMicroは、ノード実行の経過時間 (マイクロ秒単位) です。elapsedMicroを Micrometer で使用する場合は、org.drools.metric.elapsed.timeというタイマーを探します。
 - 未処理の - evalCountまたは- elapsedMicroログが見つかった場合は、ノード名を- ReteDumper.dumpAssociatedRulesRete()出力と関連付けて、ノードに関連付けられているルールを識別します。- ReteDumper の使用例 - ReteDumper.dumpAssociatedRulesRete(kbase); - ReteDumper.dumpAssociatedRulesRete(kbase);- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - ReteDumper の出力例 - [ AccumulateNode(8) ] : [Collect expensive orders combination] ... - [ AccumulateNode(8) ] : [Collect expensive orders combination] ...- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
-