вторник, 4 декабря 2012 г.

Liferay и Solr

Зачем SOLR

Liferay использует для поиска (индексации и выполнения запросов) Lucene - это "стандартное" решение для организации поиска в мире java (возможно и не только).
Что такое SOLR? Если очень утрированно - то это тот же lucene - только обернутый серверной оболочкой, позволяющей дернуть его удаленно по http протоколу.
Одна их хороших особенностей Liferay (хотя иногда это вызывает проблемы) - это то, что работа с внешними системами осуществляется через некоторое унифицированное API, что позволяет менять реализацию или используемые системы. Например как раз "подсовывая" свою реализацию Workflow API мы смогли научить Liferay использовать для бизнес-процессов не штатный Kaleo (велосипед еще тот) - а Activiti.
Работа с поиском осуществляется ровно тем же способом: при необходимости что-то проиндексировать или выполнить поисковый запрос Liferay обращается через некоторое унифицированное  API к подсистеме поиска. По умолчанию подсистема поиска использует Lucene, однако можно подсунуть другую реализацию - в частности для Liferay "из коробки" есть поддержка SOLR - реализованная в плагине solr-web.
Итак - в каких ситуациях имеет смысл использовать  SOLR:

  1. Кластеризация. Если у вас Liferay  поднят в кластере - использование Lucene  приведет к ошибкам. Дело в том, что Lucene  по умолчанию хранит свои индексы на файловой системе - при этом лочит их. Если каждая нода будет использовать свою папку для индексации - то поиск будет просто неправильно работать - в одной ноде вы создадите какую-то статью, lucene этой ноды ее проиндексирует,  но в случае выполнения поиска на других нодах вы просто не найдете этой статьи - потому что другие lucene ничего об этом знать не будут. Если же вы попробуете все lucene натравить на одну папку - то одна из них залочив индексы не пустит другие. Штатное решение - вынос поиска на SOLR - в этом случае все ноды обращаются к одному SOLR серверу.
  2. Вынос поисковой нагрузки. Если в вашем случае на поиск ложится большая нагрузка - то можно вынести поиск на отдельный (иногда более мощный) сервер (который в свою очередь тоже может кластеризоваться).
  3. Дополнительные возможности отладки поиска. К SOLR вы сможете обратить в режиме runtime  и сформировав правильные запросы посмотреть - что именно он сохранил и как он ищет. С Lucene это несколько сложнее.
Если один из приведенных случаев - ваш - добро пожаловать к продолжению:

Настройка интеграции Liferay и SOLR

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

  1. Поставить и настроить SOLR  сервер.  Он может быть установлен как на отдельном физическом сервере или отдельном сервере приложений (достаточно обычного томката), так и на том же сервере что и сам Liferay (в его же tomcat)
  2. В Liferay установить (предварительно собрав если это требуется) модуль интеграции с SOLR - solr-web. В случае если у вас кластер - установку надо будет сделать на все ноды кластера.

Установка и настройка  SOLR сервера

  • Скачать и распаковать (в некоторую папку <zip>) дистрибутив SOLR. Для версии Liferay 6.1.0 гарантированно работает версия SOLR 1.4.1, гарантированно не работает 4-ая, и вроде как после танцев с бубном работает SOLR 3.x - но оно вам надо (с бубном танцевать)? В 6.1.1 возможно будет работать SOLR 3.5 -  но надо проверять.
  • Создаем папку где будет жить solr (например /opt/solr)
  • кидаем <zip>/dist/apache-solr-1.4.1.war в /opt/solr
  • копируем <zip>/example/solr/conf в /opt/solr/conf
  • Заменяем /opt/solr/conf/schema.xml на файл docroot/WEB-INF/conf/schema.xml из исходников solr-web (откуда их взять - смотри ниже)
  • Исправляем /opt/solr/conf/solrconf.xml (прописываем где лежит data - что бы не искать ее потом по всему серверу):
<dataDir>${solr.data.dir:/opt/solr/data}</dataDir>
  • Делаем папку /opt/solr доступной для чтения-записи пользователем, под которым запущен tomcat (ну или какой там у вас  app server используется)
  • Кладем в tomcat (например в тот же что используется и для  liferay  - например в /opt/liferay/tomcat-7.0.27) файл /opt/liferay/tomcat-7.0.27/conf/Catalina/localhost/solr.xml с указанием контекста:
<?xml version="1.0" encoding="utf-8"?>
    <Context docBase="/opt/solr/apache-solr-1.4.1.war" debug="0" crossContext="true">
    <Environment name="solr/home" type="java.lang.String" value="/opt/solr" override="true"/>
</Context>
  • В результате должен запуститься solr (смотрим логи)
  • Если все запустилось - то должен появится http://<hostname>/solr - можно даже побаловаться - поделать запросы

Установка и сборка solr-web

Исходники solr-web можно взять из svn liferay тут: http://svn.liferay.com/repos/public/plugins/branches/6.1.x/webs/solr-web/
Только учтите - что тегов для определенной версии Liferay для прагинов нет, потому надо просто смотреть по истории ревизию на дату релиза необходимой версии Liferay (для Liferay 6.1.0 это например 7 января 2012 года) и берите исходники по данное ревизии (для Liferay 6.1.0 это будет ревизия 97229)
Сборка и деплой штатными средствами plugins sdk. Из настроек - требуется только подправить url  показывающий на SOLR сервер - либо в исходниках до сборки в файле docroot/WEB-INF/classes/META-INF/solr-spring.xml либо уже после деплоя (проигнорировав ошибку первого деплоя портлета - так как он не сможет обратиться к SOLR) в файле webapps/solr-web/WEB-INF/classes/META-INF/solr-spring.xml
<bean id="com.liferay.portal.search.solr.server.BasicAuthSolrServer" class="com.liferay.portal.search.solr.server.BasicAuthSolrServer">
<constructor-arg type="java.lang.String" value="http://localhost:8080/solr" />
</bean>
Вот этот localhost и надо поменять на реальный url.

Как проверить что работает

Первое что надо будет сделать после настройки - это вызвать переиндексацию. Control Panel -> Server Administration -> Reindex all indexes
При этом в логах томката где установлен SOLR  сервер должно посыпаться куча логов.
Что бы проверить что  SOLR работает на каждой ноде надо выполнить какое-нибудь действие обращающееся к подсистеме поиска - создать какой-нибудь  веб-контент, просто открыть и сохранить пользователя. Если при этом идут логи в SOLR  сервере - с высокой долей вероятности все работает :)

Важные замечания

У нас в одном из проектов solr  стоял в том же томкате что и первая нода, сторая обращалась к нему. Когда обращение делалось по порту 80 ( и потом прокидывалось nginx-ом) - то на второй ноде плагин solr-web не заводился - команды к  SOLR  вызывали ошибки. Когда поменяли на работу по порту 8080 - стало нормально. Видимо  nginx как-то портил запрос.

Ооооочень желательно что бы /solr не был доступен снаружи для анонимных пользователей. Можно отрубать доступ внешним сервером (apache  или nginx), или разрешать доступ только с определённых ip (что бы доступ был только с нод кластера). Ну и следить что бы по порту 8080 тоже было не достучатся.

Перед тем как перейти на использование SOLR - зайдите на issues.liferay.com -  и посмотрите... дальше сами решайте - надо вам или нет.

Если вы используете solr-web для версии 6.1.0 - обратите внимание на такую замечательную багу  как LPS-25152 - мне больше всего нравится что у нее приоритет minor. На самом желе эта бага о том, что если вы поставили SOLR для Liferay 6.1.0 -  то в панели управления у вас будут показываться пользователи и организации для всех portal instance-ов... вот такой вот минорный косячок :) Бага исправлена в 6.1.1 - для 6.1.1 ее надо бекпортить



1 комментарий:

Rolich Sergey комментирует...

Пробовал поднимать 3.5, частично получается, но все равно гемор такой что оно того не стоит, лучше использовать 1.4.