私たちはソリューションの一部として Drools を使用し、500,000 以上のワーキング メモリ オブジェクトに対して最大 100 のルールを実行する、非常に集中的な処理アプリケーションで一種のフィルターとして機能させました。非常に遅いことがわかります。バッチ型処理アプリケーションで Drools を使用した経験のある人はいますか?
9 に答える
種類はルールに依存します-十分なメモリがあれば500Kオブジェクトが合理的です(メモリにRETEネットワークを設定する必要があるため、メモリ使用量は500Kオブジェクトの倍数です-つまり、オブジェクトのスペース+ネットワーク構造、インデックスなどのスペース)-その非常に遅いディスクにページングしている可能性があります。
もちろん、同じタイプのファクトの組み合わせに一致するルールがある場合、試行する組み合わせが爆発的に増える可能性があります。これは、ルールが 1 つであっても非常に遅くなります。あなたが行っている分析についてさらに情報があれば、それはおそらく可能な解決策に役立つでしょう.
私は、1M を超えるファクトを含むステートフルなワーキング メモリを備えた Drools を使用しました。ルールと基盤となる JVM の両方をある程度調整することで、最初の起動から数分後にパフォーマンスが非常に向上する可能性があります。詳細が必要な場合はお知らせください。
私は自分でよだれを学んでいるだけなので、何かが足りないかもしれませんが、なぜ50万個のオブジェクトのバッチ全体が一度に作業メモリーに追加されるのでしょうか。私が考えることができる唯一の理由は、バッチ内の2つ以上のアイテムが関連している場合にのみ開始するルールがあるということです。
そうでない場合は、ステートレスセッションを使用して、一度に1つのオブジェクトをアサートできます。その場合、ルールは500k倍速く実行されると思います。
その場合でも、すべてのルールがすべての500kオブジェクトにアクセスする必要がありますか?アイテムごとのルールを一度に1つずつ適用し、処理の第2フェーズで、別のルールベースと作業メモリーを使用してバッチレベルのルールを適用することで、処理を高速化できますか?これによってデータの量が変わることはありませんが、単純なルールが削除されているため、RETEネットワークは小さくなります。
別のアプローチは、オブジェクトの関連グループを識別し、第2フェーズでオブジェクトをグループにアサートして、作業メモリー内のデータ量をさらに削減し、RETEネットワークを分割することです。
Drools の最新バージョンを使用したことはありませんが (最後に使用したのは約 1 年前です)、当時の高負荷ベンチマークでは、Drools が非常に遅いことが証明されました。私たちのアーキテクチャの多くをそれに基づいていた後、大きな失望。
drools について少なくとも私が覚えている良い点は、彼らの開発チームが IRC で利用可能であり、非常に役に立ったことです。
ステートレス セッションを使用して、一度に 1 つずつオブジェクトを追加しますか?
Drools は、実際には膨大な数のオブジェクトで実行するようには設計されていません。いくつかのオブジェクトで複雑なルールを実行するために最適化されています。
追加オブジェクトごとのワーキング メモリの初期化が遅すぎるため、キャッシング戦略はワーキング メモリ オブジェクトごとに機能するように設計されています。
数千のオブジェクトを解析した後、OutOfMemory エラーの問題が発生しました。別のデフォルトのオプティマイザーを設定すると、問題が解決しました。
OptimizerFactory.setDefaultOptimizer(OptimizerFactory.SAFE_REFLECTIVE);
よだれも見ていましたが、オブジェクトの数が少ないので問題ありません。メモリ使用量をより考慮し、同じアルゴリズムに基づいていながら速度を最適化する、同じアルゴリズムの代替バージョンがあることを読んだことを覚えています。ただし、それらのいずれかが実際に使用可能なライブラリになったかどうかはわかりません。
このオプティマイザは、パラメータ -Dmvel2.disable.jit=true を使用して設定することもできます