2010-02-16 2 views
9

Я буду использовать библиотечную систему университета для объяснения моего варианта использования. Студенты регистрируются в библиотечной системе и предоставляют свой профиль: пол, возраст, отдел, ранее пройденные курсы, зарегистрированные в настоящее время курсы, уже заимствованные книги и т. Д. Каждая книга в библиотечной системе определяет некоторые правила заимствования, основанные на профиле студентов, например , учебник для компьютерного алгоритма может быть заимствован только студентами, которые в настоящее время зарегистрированы в этом классе; другой учебник может быть заимствован только студентами математического факультета; также могут быть такие правила, при которых учащиеся могут заимствовать только две компьютерные сетевые книги. В результате правил заимствования, когда ученик ищет/просматривает в библиотечной системе, он будет видеть только книги, которые могут быть заимствованы им. Таким образом, требование действительно сводится к тому, чтобы эффективно генерировать список книг, которые студент имеет право брать взаймы.Должен ли я использовать Drools в этой ситуации?

Вот как я рассматриваю дизайн с помощью Drools - каждая книга будет иметь правило с несколькими ограничениями поля на профиль студента как LHS, RHS правила книги просто добавляет идентификатор книги в глобальный список результатов, затем все правила книги загружаются в RuleBase. Когда ученик ищет/просматривает библиотечную систему, из RuleBase создается сеанс без гражданства, и профиль ученика утверждается как факт, то каждая книга, которую может заимствовать ученик, будет уволить его книжное правило, и вы получите полный список книг, которые студенты могут заимствовать в глобальном списке результатов.

Несколько предположений: библиотека будет обрабатывать миллионы книг; Я не ожидаю, что правило книги будет слишком сложным, 3 простых ограничения полей для каждого правила в среднем не более; количество студентов, которых система должна обрабатывать, находится в диапазоне 100 КБ, поэтому нагрузка довольно тяжелая. Мои вопросы: сколько памяти будет делать Drools, если будет загружено миллионными книжными правилами? Как быстро это будет для всех этих миллионов правил, чтобы стрелять? Если Drools правильно подходит, я хотел бы услышать некоторые рекомендации по разработке такой системы у вас опытных пользователей. Благодарю.

+2

Поскольку ваши ограничения правил фактически будут сидеть в базе данных - почему бы просто не использовать SQL-запросы для получения того, разрешать или не разрешать пользователям получать эти книги. – Jasper

ответ

7

Мой опыт работы с Drools (или движком правил в целом) заключается в том, что он хорош, если важна видимость пользователей в правилах или если быстрое изменение правил без создания проекта кодирования важно или если набор правил очень велик, что затрудняет управление, анализ и анализ кода (поэтому у вас есть деловые люди, которые просят технических людей прочитать код и рассказать им, что происходит в ситуации X).

При этом правила двигателей могут быть узким местом. Они не запускают ничего близкого к производительности кода, поэтому вам нужно управлять этим архивом. В этом конкретном случае, безусловно, есть база данных, и вы можете добавить к проблемам производительности, что база данных будет возвращать запрос намного быстрее, чем вы можете проанализировать весь набор в коде.

Я бы не стал реализовывать это, создав миллион объектов правил, вместо этого я бы сделал тип книги, которому могут быть назначены несколько книг, и запускать правила против типов книг, а затем показывать только книги, которые находятся в разрешенный тип. Таким образом, вы можете загружать типы, передавать их через механизм правил, а затем нажимать разрешенные типы на запрос в конце базы данных, который вытаскивает список книг в разрешенных типах.

Типы немного усложняются тем фактом, что на практике книга может быть двух типов (допускается, если вы принимаете определенный курс или вообще, если вы являетесь частью отдела), но подход должен по-прежнему удерживаться.

-1

Я был бы обеспокоен необходимостью иметь количество правил в зависимости от количества студентов - это действительно могло бы сделать вещи сложными (это звучит как самая большая проблема).

11

Во-первых, не устанавливайте правила для каждой книги. Сделать правила об ограничениях — существует гораздо меньше ограничений, чем книг. Это существенно повлияет на время работы и использование памяти.

Запуск тонны книг через механизм правил будет дорогостоящим. Тем более, что вы не будете показывать все результаты пользователю: всего 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 

Где я использую активационный-группу, чтобы убедиться, что только одно правило, обжигают, и выпуклость, чтобы убедиться, что они уволены в порядке, я хочу им быть.

И, наконец, сохранить правила кэширования. Drools разрешает — и предлагает, чтобы — загружал правила только один раз в базу знаний, а затем создавал сеансы из этого. Базы знаний дороги, сеансы дешевы.

+1

+1 для переопределения проблемы. Я согласен с тем, что вам не нужно миллион книг как факты сеанса правила, только те, которые студент ставит в «корзину» на пути к «checkout» –

1

Мои вопросы: сколько памяти будет Drools принять, если загружен миллион книги правил? Как быстро это будет для всех этих миллионов правил для стрельбы?

Как быстро ваш компьютер и сколько у вас памяти? В каком-то смысле вы можете узнать только, построив доказательство концепции и заполнив ее нужным количеством (случайно генерируемых) тестовых данных. Мой опыт в том, что Drools быстрее, чем вы ожидаете, и что у вас должно быть очень хорошее знание того, что находится под капотом, чтобы иметь возможность предсказать, что будет замедлять работу.

Обратите внимание, что вы говорите о миллионах фактов о правилах ведения дел (т. Е. Книжных объектов), а не о миллионах правил. Есть только несколько правил, которые не заставят себя долго ждать. Потенциально медленная часть - это вставка миллиона объектов, потому что Drools должен решить, какие правила включать в повестку дня для каждого нового факта.

Жаль, что никто из нас не имеет ответа на конкретную настройку с миллионами фактов.

Что касается реализации, то мой подход состоял бы в том, чтобы вставить объект Book для каждой книги, который студент хочет проверить, отменить те, которые не разрешены, и запрос на получение оставшихся (разрешенных) объектов книги, и еще один запрос, чтобы получить список причин. Кроме того, используйте объекты RequestedBook, которые имеют дополнительные boolean allowed и String reasonDisallowed свойства, которые вы можете установить в своих правилах.

+0

Я предпочитаю ваше решение, а не изменение заявление о проблеме, предложенное Майклом Дорддейффом. Как ваше решение будет выглядеть, когда пользователь перейдет на последнюю страницу. Вы ожидаете, что все миллионы фактов войдут в рабочую память? –

1

Каждый раз, когда мы смотрим на большие наборы данных (о которых идет речь ... независимо от того, подходит ли Drools в большом наборе данных), подумайте вне коробки (ниже). Каждый раз, когда мы говорим о «миллионах объектов» или подобных проблемах типа log-N, я не думаю, что они подвержены сомнению, это проблема.Так что да, можно использовать Drools (или JBoss Rules), но это будет иметь смысл только в определенном контексте ...

Когда у вас есть log-N всего (перекрестные ссылки на большие наборы данных на входы), я бы рекомендуем использовать более новые подходы, такие как Bloom Filters с поддержкой базы данных. Они могут быть реализованы как объекты Java и указаны Drools для поиска фактов (там, однако, имеется некоторая специальная кодировка).

Поскольку Bloom Filters представляют собой крошечные структуры памяти с базовыми функциями insert()/contains(), у них есть недостаток ... около 1% ложноположительной скорости. Таким образом, это будет служить в качестве основного кеша. Если в качестве ответа на вопрос Drools будет задан вопрос «НЕТ», то поиск структуры таблицы фактов с поддержкой Bloom Filter будет молниеносно и с небольшим объемом памяти (около 1,1 байт на запись в моей реализации), поэтому 1 МБ ОЗУ для Это дело. Затем в случае «содержит» (который может быть ложноположительным), используйте таблицу фактов, поддерживаемую базой данных, чтобы уточнить. Опять же, если в 80% случаев поиск будет ложным, тогда Bloom Filter будет огромной экономией в памяти и времени. В противном случае, чистые (что-то - факты Drools, база данных и т. Д.) 1M записи будут очень дорогими каждый раз (в памяти и скорости).

 Смежные вопросы

  • Нет связанных вопросов^_^