簡體   English   中英

我應該在這種情況下使用Drools嗎?

[英]Should I use Drools in this situation?

我將使用大學的圖書館系統來解釋我的用例。 學生在圖書館系統中注冊並提供他們的個人資料:性別,年齡,部門,以前完成的課程,當前注冊的課程,已經借閱的書籍等。圖書館系統中的每本書都將根據學生的個人資料定義一些借閱規則,例如,計算機算法的教科書只能由目前在該課程注冊的學生借用; 另一本教科書只能由數學系的學生借用; 也可能有規則,學生最多只能借2本電腦網絡書。 由於借用規則,當學生在圖書館系統中搜索/瀏覽時,他只會看到可以借用的書籍。 因此,該要求實際上歸結為有效生成學生有資格借閱的書籍清單。

以下是我使用Drools對設計進行設想的方法 - 每本書都有一個規則,對學生檔案有一些字段限制作為LHS,書規則的RHS只是將書籍ID添加到全局結果列表,然后是所有書籍規則被加載到RuleBase中。 當學生搜索/瀏覽圖書館系統時,會從RuleBase創建無狀態會話,並且學生的個人資料被斷言為事實,然后學生可以借用的每本書都會觸發其圖書規則並獲得完整的圖書清單。學生可以在全球結果列表中借閱。

一些假設:圖書館將處理數百萬本書; 我不認為圖書規則太復雜,平均每條規則最多3個簡單的字段限制; 系統需要處理的學生數量在100K范圍內,因此負載相當重。 我的問題是:如果加載了一百萬本圖書規則,Drools會占用多少內存? 所有這些百萬條規則的解雇速度有多快? 如果Drools是合適的,我想聽聽一些有經驗的用戶設計這樣一個系統的最佳實踐。 謝謝。

首先,不要為每本書制定規則。 制定限制規則 - 定義的限制比書籍少得多。 這將對運行時間和內存使用量產生巨大影響。

通過規則引擎運行大量書籍將是昂貴的。 特別是因為您不會向用戶顯示所有結果:每頁只有10-50。 想到的一個想法是使用規則引擎來構建一組查詢條件。 (我實際上不會這樣做 - 見下文。)

這就是我的想法:

rule "Only two books for networking"
when
  Student($checkedOutBooks : checkedOutBooks),
  Book(subjects contains "networking", $book1 : id) from $checkedOutBooks,
  Book(subjects contains "networking", id != $book1) from $checkedOutBooks
then
  criteria.add("subject is not 'networking'", PRIORITY.LOW);
end

rule "Books allowed for course"
when
  $course : Course($textbooks : textbooks),
  Student(enrolledCourses contains $course)

  Book($book : id) from $textbooks,
then
  criteria.add("book_id = " + $book, PRIORITY.HIGH);
end

但我實際上不會這樣做!

這就是我改變問題的方法:不向用戶顯示書籍是一種糟糕的體驗。 用戶可能想要仔細閱讀書籍以查看下次要獲得的書籍。 出示書籍,但不允許結帳限制書籍。 這樣,每個用戶一次只能有1-50本書來運行規則。 這將是非常活潑的。 以上規則將成為:

rule "Allowed for course"
   activation-group "Only one rule is fired"
   salience 10000
when
  // This book is about to be displayed on the page, hence inserted into working memory
  $book : Book(),

  $course : Course(textbooks contains $book),
  Student(enrolledCourses contains $course),
then
  //Do nothing, allow the book
end

rule "Only two books for networking"
   activation-group "Only one rule is fired"
   salience 100
when
  Student($checkedOutBooks : checkedOutBooks),
  Book(subjects contains "networking", $book1 : id) from $checkedOutBooks,
  Book(subjects contains "networking", id != $book1) from $checkedOutBooks,

  // This book is about to be displayed on the page, hence inserted into working memory.
  $book : Book(subjects contains "networking")
then
  disallowedForCheckout.put($book, "Cannot have more than two networking books");
end

我在使用activation-group來確保只觸發一個規則,以及確保按照我希望的順序觸發它們的突出性。

最后, 保持緩存規則 Drools允許 - 並建議您 - 只將規則加載到知識庫中一次,然后從中創建會話。 知識庫昂貴,會話便宜。

我對Drools(或一般規則引擎)的體驗是,如果用戶對規則的可見性很重要,或者如果對規則進行快速更改而不使其成為編碼項目很重要,或者如果規則集合如此非常大,因此難以管理,思考和分析代碼(所以你會讓商界人士要求技術人員去閱讀代碼並告訴他們在情況X中會發生什么)。

話雖這么說,規則引擎可能是一個瓶頸。 它們不會運行任何接近代碼性能的東西,因此您需要在架構上預先管理它。 在這個特定的情況下,肯定有一個數據庫,你可以添加到性能問題,數據庫將返回一個查詢比你在代碼中分析整個集合快得多。

我絕對不會通過制作一百萬個規則對象來實現它,而是我會制作一個可以分配多本書的書籍類型,並針對書籍類型運行規則,然后只顯示允許類型的書籍。 這樣,您可以加載類型,通過規則引擎傳遞它們,然后將允許的類型推送到數據庫端的查詢,該查詢將提取允許類型的書籍列表。

類型變得有點復雜,因為在實踐中,一本書可能有兩種類型(如果你正在學習某門課程,或者一般來說,如果你是該部門的一部分,則允許),但這種方法應該仍然適用。

每當我們查看大型數據集時(這個問題是關於...... Drools是否適合大型數據集),請在框外思考(如下)。 每當我們談論“數百萬個對象”或類似的log-N類型問題時,我認為他們所討論的工具不一定是問題所在。 所以是的,可以使用Drools(或JBoss Rules),但只能在某種情況下才有意義......

當你有任何log-N(交叉引用大數據集與輸入)時,我建議使用更新穎的方法,如數據庫支持的Bloom Filters。 這些可以實現為Java對象,並由Drools引用以進行事實查找(但是,在那里進行自定義編碼)。

由於Bloom Filters是微小的內存結構,只有基本的insert()/ contains()函數,它們確實有一個缺點......大約1%的誤報率。 所以這將作為主緩存。 如果構建Drools問題通常是“NO”作為答案,Bloom Filter支持的事實表構造查找將是閃電般快速並且具有微小的內存占用(在我的實現中每條記錄大約1.1字節)所以1 MB的RAM用於這個案例。 然后在“包含”的情況下(可能是誤報),使用數據庫支持的事實表來澄清。 同樣,如果在80%的情況下,查找都是錯誤的,那么Bloom Filter將大大節省內存和時間。 否則,純(任何東西 - Drools事實,數據庫等)1M記錄查找每次都會非常昂貴(內存和速度)。

我的問題是:如果加載了一百萬本圖書規則,Drools會占用多少內存? 所有這些百萬條規則的解雇速度有多快?

你的電腦有多快,你有多少記憶? 從某種意義上說,您只能通過構建概念證明並用適當數量的(隨機生成的)測試數據填充它來找到答案。 我的經驗是,Drools比你想象的要快,並且你必須非常了解底層的東西,以便能夠預測什么會讓它變慢。

請注意,您正在談論一百萬個規則會話事實 (即Book對象),而不是一百萬個規則。 只有少數規則,不會花很長時間。 可能很慢的部分是插入百萬個對象,因為Drools需要決定將哪些規則放在議程中以用於每個新事實。

令人遺憾的是,我們沒有人能夠通過一百萬個事實得到某些特定設置的答案。

至於實現,我的方法是為學生想要簽出的每本書插入一個Book對象,收回不允許的書,以及查詢以獲取剩余(允許的)Book對象,以及另一個查詢到得到原因列表。 或者,使用RequestedBook對象,這些對象具有可在規則中設置的其他boolean allowedString reasonDisallowed屬性。

我擔心需要將規則數量作為學生數量的函數 - 這可能會讓事情變得棘手(這聽起來像是最大的問題)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM