第22章 DRL 使用時のパフォーマンスチューニングに関する考慮点
以下の主要な概念または推奨のプラクティスを使用すると、DRL ルールとデシジョンエンジンのパフォーマンス最適化に役立ちます。このセクションではこの概念についてまとめており、随時、他のドキュメントを相互参照して詳細を説明します。このセクションは、Red Hat Decision 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 $f:flight() $h:hotel() // Rarely booked
DRL パターンおよび制約の詳細は、「DRL のルール条件 (WHEN)」 を参照してください。
from
句を過剰に使用する、サイズの大きいオブジェクトコレクションで反復を回避する以下の例のように、サイズの大きいオブジェクトコレクションで反復を行う DRL ルールでは
from
要素の使用を回避してください。from
句を使用した条件の例when $c: Company() $e : Employee ( salary > 100000.00) from $c.employees
このような場合には、デシジョンエンジンはルールの条件が評価されるたびにサイズの大きいグラフを反復するので、ルール評価の妨げになります。
他の手段として以下の例のように、サイズの大きいグラフが含まれるオブジェクトを追加してデシジョンエンジンが頻繁に反復作業を行うのではなく、コレクションを KIE セッションに直接追加して、条件内でコレクションを結合します。
from
句なしの条件の例when $c: Company(); Employee (salary > 100000.00, company == $c)
この例では、デシジョンエンジンは 1 回だけリストを反復して、ルールの評価を効率化します。
from
要素または他の DRL 条件要素に関する情報は、「DRL でサポートされるルール条件要素 (キーワード)」 を参照してください。- ロギングのデバッグには、
System.out.println
ステートメントの代わりに、デシジョンエンジンのイベントリスナーをルール内で使用する ルールのデバッグやコンソール出力に、
System.out.println
ステートメントをルールアクションで使用できますが、多数のルールに対してこれを行うと、ルール評価の妨げになります。別の効率的な方法として、できるだけ内蔵のデシジョンエンジンイベントリスナーを使用してください。このイベントリスナーが貴社の要件に満たない場合には、Logback、Apache Commons Logging、Apache Log4j など、デシジョンエンジンがサポートするシステムロギングユーティリティーを使用してください。サポート対象のデシジョンエンジンのイベントリスナーおよびロギングユーティリティーに関する詳細は、Red Hat Decision 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>
drools-metric
を使用してトレースログを有効にする場合は、次の例に示すように、org.drools.metric.util.MetricLogUtils
のロガーを設定します。logback.xml 設定ファイルの例
<configuration> <logger name="org.drools.metric.util.MetricLogUtils" level="trace"/> ... <configuration>
または、
drools-metric
を使用して、Micrometer を使用してデータを公開できます。データを公開するには、次の例に示すように、選択した Micrometer レジストリーを有効にします。Micrometer のプロジェクト依存関係の例
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-jmx</artifactId> <!-- Discover more registries at micrometer.io. --> </dependency>
Micrometer の Java コードの例
Metrics.addRegitry(new JmxMeterRegistry(s -> null, Clock.SYSTEM));
ロギングと 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
この例には、次の主要なパラメーターが含まれています。
-
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 の出力例
[ AccumulateNode(8) ] : [Collect expensive orders combination] ...
-