2016-09-01 3 views
0

Существует служба REST, которая выполняет поиск и обновление данных, поддерживаемых Hibernate и HS. Индекс Lucene имеет более 1,5 млн. Документов и растет.Асинхронное индексирование по Hibernate Search (HS) после совершения транзакции

Проблема: когда служба сохраняет обновленные данные в базе данных (session.commit()) - одновременно HS выполняет индексацию данных, в результате транзакция фиксируется с задержкой (2-5 секунд) - поэтому HTTP-запрос задерживается для запросов на обновление данных. Служба REST имеет множество методов, и клиентская сторона, которая существует для этой службы, ожидает, что после возврата вызова AJAX данные будут доступны для «GET», поэтому совершение транзакции асинхронным образом на стороне сервера - это не вариант (данные, t быть доступным для клиента сразу после POST).

Я использую hibernate.search.default.worker.execution=async, но этот параметр не помогает (улучшение составляет около 1 секунды). Причина заключается в том, что HS собирает данные для обновленных/созданных документов с использованием текущего сеанса/потока, а затем асинхронно индексирует в Lucene ..

Итак, мои вопросы: 1. Есть ли способ выполнить вычисление данных HS асинхронно на главную поток выполнения? Таким образом, фиксация транзакции не замораживается на время сбора данных. 2. Я полагаю, что с моей проблемой с использованием JMS с Master/Slave вам не поможет, потому что узкое место не индексирует себя, а собирает данные для индексации?

ответ

1

В настоящее время нет такого варианта.

В подобных ситуациях мне удалось оптимизировать доступ к данным в Hibernate, поскольку 2-5 секунд не очень впечатляет, например, глядя на кэширование второго уровня, делая ненужные отношения ленивыми (и необходимые отношения нетерпеливы). Помните, что никогда не делайте кешированное отношение нетерпеливым, или он не будет использовать кеш.

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

Мы могли бы придумать процесс асинхронного индексирования, но это довольно сложно: после прекращения текущей транзакции мы будем читать потенциально несогласованное состояние. Решение состояло бы в том, чтобы перечитать весь граф объекта в новой транзакции: после совершения транзакции откройте новый в чистом сеансе и перезагрузите все необходимые данные. Возможно, это интересный вариант, но есть вероятность, что ваш сервер и базы данных пострадают от всей дополнительной работы, создаваемой таким шаблоном.

Я подал некоторые конструктивные мысли, как https://hibernate.atlassian.net/browse/HSEARCH-2364

+0

Thx Sanne, проблема в том, что нам нужно переиндексацию 2 000+ документы в какой-то POST (обновление) запроса. Я думаю, что естественно, что сбор данных занимает так много времени в этом случае ~ 2 секунды. Это примерно 1 мс на документ, который я считаю ОК, поскольку у нас также есть довольно сложные отношения и большое количество связанных объектов, которые необходимо загрузить для документа. В качестве решения мы успешно используем именно то, что вы рекомендуете: _ «перечитать весь граф объекта в новой транзакции после совершения транзакции» _, используя Hibernate EventListener и Spring AsyncTaskExecutor. – aillusions

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