...

среда, 11 июня 2014 г.

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

imageimage

Введение




Как известно, на многих сайтах/веб-приложениях необходимо тем или иным образом реализовать поиск. Все хотят быстрый и качественный поиск. Разработчики помимо всего прочего хотят, чтобы поисковик был прост в установке и использовании. Так как речь идет о 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://ift.tt/1raQsip
    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.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий