Установка и интеграция solr с django под Ubuntu 12.04

от автора

image image

Введение

Как известно, на многих сайтах/веб-приложениях необходимо тем или иным образом реализовать поиск. Все хотят быстрый и качественный поиск. Разработчики помимо всего прочего хотят, чтобы поисковик был прост в установке и использовании. Так как речь идет о django, то перед нами встает ряд ограничений в реализации поиска (при условии, что в сутках 24 часа и дедлайны никто не отменял). Предлагаю вашему вниманию небольшой туториал о том, как поставить и максимально безболезненно интегрировать в django проект такой мощный поисковик, как apache solr. Всех заинтересованных прошу под кат.

Наши грабли

В прошлом у нас был не очень приятный опыт работы с django-sphinx. Сам sphinx отличный поисковик, django-sphinx тоже замечательная библиотека, но после django 1.3 приходится немного танцевать с бубном, чтобы завести весь этот стек. Но даже после того как все это настроено и работает остается ощущение, что все это лежит находится где-то там, отдельно от проекта, со своими индексами по крону и конфигами, не связанными с моделями на проекте. Да, там есть автогенератор конфигов, но завести его под 1.4+ не удалось, да и после каждой генерации пришлось бы править конфиги самого поисковика (searchd). В целом поиск django-sphinx работает, причем быстро и качественно, но поддерживать это не очень удобно, как и интегрировать в проект.

Как мы нашли для себя иголку в haystack

Вот настал черед нового проекта. И снова встал вопрос выбора поисковика. От django-sphinx мы сразу же отказались и стали искать альтернативное решение. Первая библиотека, на которую мы обратили внимание, это django-haystack, что неудивительно, т.к. это самая популярная библиотека для интеграции поисковиков в django. Посмотрев api, на ней и остановились. Нам обещали полную интеграцию с любым из предложенных поисковиков: elasticsearch, solr, whoosh, xapian. После беглого осмотра были приняты следующие решения:

  1. Whoosh исключили из-за отсутствия кучи мелких фич, некоторые из которых были необходимы для проекта. Да и поговаривают, что он по скорости проигрывает остальным вариантам.
  2. Xapian исключили после неудачной попытки интеграции стороннего бекенда.
  3. Осталось 2 варианта — elasticsearch и solr. Оба на java, оба на lucene, фичи практически идентичны. “Подбросив монетку” было решено использовать solr.

Больше граблей

Сразу скажу, что в данной статье описана в основном работа именно с solr, а не с haystack. Информацию по haystack можно найти в официальных доках, она хорошо изложена и дублировать ее здесь я не вижу смысла.

Библиотека выбрана, поисковик выбран. Пора приступать к работе. Первой же ошибкой была установка из официального репа ubuntu 12.04. В официальном репе версия solr 1.4, хотя документация haystack рекомендует версию 3.5+ во избежание оказий. Решили ставить сами. После серии проб и ошибок пришли к решению, которое отлично сработало как на локалках разработчиков, так и на тестовом и боевом серверах. Вот примерная последовательность действий:

  1. Ставим системные пакеты jre и jetty:
    apt-get install openjdk-7-jre-headless jetty 
  2. Python либы:
    pip install pysolr django-haystack 
  3. Немного “темной магии” для глобальной установки самого solr’а:
    #!/bin/sh #variables LIB_DIRECTORY="/opt/solr" CONF_DIRECTORY="/etc/solr" OLD_CONF_DIRECTORY="$LIB_DIRECTORY/example/solr/conf"  #check if already installed if ( [ -d $LIB_DIRECTORY ] && [ -d $CONF_DIRECTORY ] ); then     echo "solr is already installed"     exit fi  #install if not #download and unpack wget http://archive.apache.org/dist/lucene/solr/3.6.2/apache-solr-3.6.2.tgz tar -xvzf apache-solr-3.6.2.tgz  #install mv apache-solr-3.6.2 $LIB_DIRECTORY mv $OLD_CONF_DIRECTORY $CONF_DIRECTORY ln -s $CONF_DIRECTORY $OLD_CONF_DIRECTORY  #cleanup rm apache-solr-3.6.2.tgz  echo "solr installed" 

Конечно если вы не хотите ставить solr так “глобально”, то можно немного подкрутить скрипт и ставить в любую другую папку — solr работает сразу после разархивации без дополнительных танцев, просто мы хотели видеть конфиги в привычных местах и чтобы очередное “стороннее” приложение было там же, где и остальные.

В общем уже можно запускать и все будет работать:

cd /opt/solr/example/ && java -jar start.jar 

Но не можем же мы так все оставить. Как же конфиги, переиндексация и нормальный запуск? Давайте по порядку.

Конфиги.

В данном контексте нас интересует 2 конфига:

  1. /etc/solr/schema.xml — сама схема данных и прочая информация для индексации и поиска, связанная непосредственно с нашими данными. Этот конфиг необходимо обновлять каждый раз, когда вы меняете индексы у себя в проекте.
  2. /etc/solr/solrconfig.xml — настройки самого solr’а, т.е. модули, handler’ы и прочие настройки, которые напрямую не касаются данных. Этот конфиг вам может пригодиться, если вам нужны дополнительные фичи solr’а.

После обновления любого из конфигов необходимо ребутать solr, чтобы изменения вступили в силу.
Для генерации schema.xml haystack поставляет замечательную команду build_solr_schema. Но у нее есть небольшой минус — при ее использовании нужно помнить куда надо класть конфиг, т.к. она либо принтит конфиг в консоль, либо в файл, если он указан. Можно немного поправить дело, если сделать собственную команду, полную копию build_solr_schema, просто указать дефолтное значение имени файла (в нашем случае это /etc/solr/schema.xml). Таким образом мы немного упростили жизнь разработчикам, ведь теперь достаточно только запустить эту команду и конфиг будет обновлен.

Переиндексация.

В нашем случае есть 2 варианта как поддерживать актуальность индексов:

  1. “Классический вариант” — полная переиндексация раз в N минут. Единственный плюс такого подхода, который приходит в голову, это его простота. Минусов немного больше: при большой базе это долго, между переиндексациями данные могут стать неактуальными.
  2. “Атомарная переиндексация” — переиндексация каждого объекта по сигналам post_save, post_delete и т.д. Главным плюсом очевидно будет скорость независимо от размера бд. Немаловажно, что при таком подходе весь контроль переиндексации находится “на глазах” в коде проекта, а не в каком-то там кроне или в лучшем случае таске celery. Но и тут не без минусов: неактуальность данных при неправильной реализации и оверхед при вызове сигналов с переиндексацией. Последний устраняется вынесением в асинхронный таск (в нашем случае celery).

Мы выбрали второй вариант (никто не запрещает выбрать оба сразу) и для реализации воспользовались простым миксингом для моделей и парой тасков:

Миксин:

class RefreshIndexMixin(object):     #index - соответствующий индекс модели, например PostIndex или CarIndex     def update_index(self, index):         current_app.send_task('project.tasks.update_index', args=[self, index])      def remove_index(self, index):         current_app.send_task('project.tasks.remove_index', args=[self, index]) 

В модели соответственно достаточно вызвать update_index или remove_index в соответствующем сигнале.

Таски

from celery import shared_task   @shared_task def update_index(obj, index):     index().update_object(obj)   @shared_task def remove_index(obj, index):     index().remove_object(obj) 

Нормальный запуск.

Мы повсеместно используем supervisor, поэтому в нашем случае долго думать не пришлось. Вот пример конфига для локалки/тестового сервера:

[program:solr] command=java -jar start.jar directory=/opt/solr/example/ stderr_logfile=/var/log/solr.error.log stdout_logfile=/var/log/solr.log autorestart=true 

Почему именно для локалки/тестового? Потому что solr “из коробки” идет с собственной админкой, где можно посмотреть индексы, настройки и т.д., а так же производить всякие манипуляции с этими данными. На боевом сервере вы скорее всего захотите отказаться от такой фичи, поэтому вот команда запуска только на localhost’е на дефолтном порте:

command=java -Djetty.host=127.0.0.1 -Djetty.port=8983 -jar start.jar 

Итог

Что мы имеем в сухом остатке:

  • мощный поисковый движок, который отлично интегрирован с django проектом
  • атомарное индексирование
  • легкое изменение любых настроек в рамках проекта
  • целый ворох дополнительных фич (faceting, more like this и т.д.), которые действительно работают

За то время, что мы используем эту связку, она показала себя отличнейшим образом со всех сторон. Пользователи и заказчик довольны быстрым и адекватным поиском на сайте. Для разработчиков наличие такого java-монстра практически незаметно, т.к. им нужны только индексы, пара команд manage.py и перезагрузка solr’а через supervisor.

ссылка на оригинал статьи http://habrahabr.ru/post/225999/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *