Оптимизация индексирования Shpinx для LiveStreet, и чуть-чуть про его установку.
На самом деле, стандартный конфигурационный файл sphinx.conf идущий в комплекте с LiveStreet 1.0.1 (/install/sphinx.conf) слегка простоват. Собственно, это, с мелкими изменениями, всё та же конфигурация описанная господином kruft в далёком 2008 году ( за что ему, по сей день, огромнейший респект).
Не сказать, что с тех пор многое поменялось с вопросом интеграции Shpinx и LiveStreet «по умолчанию».(интересные, платные, плагины для поиска — иной разговор). Однако, вполне можно выжать гораздо больше и из того, что есть на халяву. :)
Чего опять хотелось?
Замечание (19.03.2013): Исправление древней проблемы с закрытыми блогами, на основе нижеописанной конфигурации: livestreet.ru/blog/tips_and_tricks/14568.html
Замечание (07.02.2013): Некоторые уточнения, в соответствии с подсказками из комментариев:
Итак, оптимизированный, sphinx.conf выглядит вот так:
Как обычно, dbprefix должен соответствовать префиксу таблиц в вашей базе.
А entityprefix обозвать как-то в соответствии с проектом, ну или вообще убрать(нужно это только для того, чтобы поддерживать несколько приложений на LiveStreet одним и тем же демоном Sphinx)
Вся оптимизация, собственно, в слегка изменённых SQL запросах, и применении директив sql_joined_field и wordforms. Никаких тайн, просто вечер в обнимку с официальной документацией Sphinx.
Парочка технических комментариев:
Соответствующий /config/modules/search/config.php LiveStreet (для краткости выброшены все комментарии):
Теперь самое интересное: wordforms.txt. Этот текстовый файл уникален для каждого проекта и содержит в себе синонимы нужных вам поисковых фраз. У нас, например, проект посвященный онлаин играм и люди часто ищут по какому-то удобному сокращению, которое как правило почти никогда не встречается в хорошо отредактированном тексте. Например «la2» вместо «Lineage II» или «салем» вместо «Salem». Хорошо, если автор теги умело прописал(которые, к слову, стандартным конфигурационным файлом к поиску тоже не привлекались), но на это лучше не надеяться. Вот в таких случаях синонимы очень помогают. Содержимое файла просто как грабли:
А теперь «чуть-чуть про установку». Ставилось это на Debian 6.0 «Squeeze», и оказалось делом на много более простым, сравнительно с тем что описывается в старых топах.
Warning: Если у вас не Debian, а другой Linux или ещё что, то это, скорее всего, будет означать другую структуру каталогов, и прочие мелкие неприятности.
Warning II: В особенности вам не повезло, если вам нужна поддержка языка отличного от русского или английского. Sphinx это может, но не в стандартной упаковке. Удачи вам с компиляцией, я мысленно с вами. :)
Как установить Sphinx на Debian:
Как запустить:
В заключение, про cron для полноты картины. Выглядит, конфигурация оного, у нас так:
Угу: топики раз в полчаса, комментарии раз в 10 минут. Да, я знаю что обычный совет — первое раз в три часа, второе раз в час. Но у нас полная индексация занимает менее двух секунд, и хоть как-то заметно сервер не грузит. С другой стороны, бывают дни, когда возбуждённое сообщество выдает на гора сотню комментариев и несколько новых заметок. Так чего тянуть? Пусть индексируется как можно быстрее. Я к тому, что не задумываясь следовать каким-то рекомендациям в этом вопросе — не лучший путь. Смотрите на собственную ситуацию с загрузкой сервера и активностью посетителей.
P.S. Посмотреть как работает «в живую» можно на сайте ММОзговед.
Не сказать, что с тех пор многое поменялось с вопросом интеграции Shpinx и LiveStreet «по умолчанию».(интересные, платные, плагины для поиска — иной разговор). Однако, вполне можно выжать гораздо больше и из того, что есть на халяву. :)
Чего опять хотелось?
- Чтобы топики искало не только по заголовку и тексту, но еще и по списку тегов, названию блога и автору.
- Чтобы комментарии искало ещё и по автору тоже (почему бы и нет?)
- Словарь синонимов, ибо Shpinx умеет и иногда полезно.
- Я так и не понял, зачем индексировать не опубликованные топики и забаненые комментарии, а потом фильтровать их LiveStreet-ом. Тайна сия велика есть. Решил выкинуть из индекса и то, и другое.
Замечание (19.03.2013): Исправление древней проблемы с закрытыми блогами, на основе нижеописанной конфигурации: livestreet.ru/blog/tips_and_tricks/14568.html
Замечание (07.02.2013): Некоторые уточнения, в соответствии с подсказками из комментариев:
- В конфигурацию добавлена директива compat_sphinxql_magics = 0 которая убирает безобидный, но раздражающий Warning при старте демона. Спасибо Lexx .
- Обращаю внимание на то, что минимальная версия Sphinx для этой конфигурации — 1.10-beta. Опять спасибо Lexx .
- В конфигурации применяется соединение посредством Unix socket, я не TCP/IP. Спасибо Orhideous
Итак, оптимизированный, sphinx.conf выглядит вот так:
############################################################################# ## data source definition ############################################################################# source entityprefixSource { type = mysql sql_host = localhost sql_user = mydbuser sql_pass = mydbuserpassword sql_db = mydb sql_port = 3306 sql_sock = /var/run/mysqld/mysqld.sock mysql_connect_flags = 32 # enable compression sql_query_pre = SET NAMES utf8 sql_query_pre = SET SESSION query_cache_type=OFF } source entityprefixTopicsSource : entityprefixSource { sql_query = \ SELECT t.topic_id, t.topic_title, UNIX_TIMESTAMP(t.topic_date_add) as topic_date_add, \ tc.topic_text, t.topic_publish, b.blog_title, u.user_login \ FROM dbprefix_topic t, dbprefix_topic_content tc, dbprefix_blog b, dbprefix_user u \ WHERE t.topic_id=tc.topic_id AND t.topic_publish=1 \ AND b.blog_id=t.blog_id AND t.user_id=u.user_id \ AND t.topic_id>=$start AND t.topic_id<=$end sql_joined_field = tags from query; select topic_id, topic_tag_text \ from dbprefix_topic_tag order by topic_id ASC sql_query_range = SELECT MIN(topic_id),MAX(topic_id) FROM dbprefix_topic sql_range_step = 1000 sql_attr_bool = topic_publish sql_attr_timestamp = topic_date_add sql_attr_multi = uint tag from query; SELECT topic_id, topic_tag_id FROM dbprefix_topic_tag } source entityprefixCommentsSource : entityprefixSource { sql_query = \ SELECT m.comment_id, m.comment_text, UNIX_TIMESTAMP(m.comment_date) as comment_date, \ m.comment_delete, u.user_login \ FROM dbprefix_comment m, dbprefix_user u \ WHERE m.target_type='topic' AND m.comment_delete=0 AND m.comment_publish=1 AND m.user_id=u.user_id \ AND m.comment_id>=$start AND m.comment_id<=$end sql_query_range = SELECT MIN(comment_id),MAX(comment_id) FROM dbprefix_comment sql_range_step = 5000 sql_attr_bool = comment_delete sql_attr_timestamp = comment_date } ############################################################################# ## index definition ############################################################################# index entityprefixtopicsIndex { source = entityprefixTopicsSource path = /var/lib/sphinxsearch/data/entityprefix/topicsIndex wordforms = /var/lib/sphinxsearch/data/entityprefix/wordforms.txt docinfo = extern morphology = stem_enru charset_type = utf-8 html_strip = 1 html_remove_elements = style, script, code } index entityprefixcommentsIndex : entityprefixtopicsIndex { source = entityprefixCommentsSource path = /var/lib/sphinxsearch/data/entityprefix/commentsIndex } ############################################################################# ## indexer settings ############################################################################# indexer { mem_limit = 32M } ############################################################################# ## searchd settings ############################################################################# searchd { listen = /var/run/sphinx.socket log = /var/log/sphinxsearch/searchd.log query_log = /var/log/sphinxsearch/query.log read_timeout = 5 client_timeout = 300 max_children = 100 pid_file = /var/run/searchd.pid workers = threads compat_sphinxql_magics = 0 } # --eof--
Как обычно, dbprefix должен соответствовать префиксу таблиц в вашей базе.
А entityprefix обозвать как-то в соответствии с проектом, ну или вообще убрать(нужно это только для того, чтобы поддерживать несколько приложений на LiveStreet одним и тем же демоном Sphinx)
Вся оптимизация, собственно, в слегка изменённых SQL запросах, и применении директив sql_joined_field и wordforms. Никаких тайн, просто вечер в обнимку с официальной документацией Sphinx.
Парочка технических комментариев:
- mem_limit = 32M 32 мегабайта это по умолчанию. Вообще рекомендация для Sphinx от 256 до 1024. В идеале, памяти должно быть просто достаточно для того чтобы индекс туда помещался целиком. У нас 500 топиков и 10000 комментариев — индекс занимает 15M. Решайте сами, но жадничать не стоит.
- query_log = /var/log/sphinxsearch/query.log лог поисковых запросов. Можно просто вырубить, но штука полезная. Для поиска потенциальных синонимов, например.
- workers = threads в стандартном файле от LiveStreet этой опции вообще нет, что означает, что используется умолчание workers = fork. fork хорош тем, что работает везде, даже на замшелых версиях BSD, но он же и наиболее ресурсоёмкий по CPU. Лучше fork не надо.
- По уму, рекомендуется почитать документацию Sphinx. Да, там много, и не по русски. Но будете знать что к чему в деталях.
Соответствующий /config/modules/search/config.php LiveStreet (для краткости выброшены все комментарии):
<?php $config['entity_prefix'] = 'entityprefix'; $config['sphinx']['host'] = 'unix:///var/run/sphinx.socket'; return $config; ?>
Теперь самое интересное: wordforms.txt. Этот текстовый файл уникален для каждого проекта и содержит в себе синонимы нужных вам поисковых фраз. У нас, например, проект посвященный онлаин играм и люди часто ищут по какому-то удобному сокращению, которое как правило почти никогда не встречается в хорошо отредактированном тексте. Например «la2» вместо «Lineage II» или «салем» вместо «Salem». Хорошо, если автор теги умело прописал(которые, к слову, стандартным конфигурационным файлом к поиску тоже не привлекались), но на это лучше не надеяться. Вот в таких случаях синонимы очень помогают. Содержимое файла просто как грабли:
la2 > lineage II салем > salemПрименение wordforms несколько увеличивает размер индекса, но практически никак не сказывается на скорости поиска. Если вам оно не надо — просто удалите из конфигурации строку с ним и всё. Но полезно иногда. Например, по «салем» с синонимом у нас в три раза больше топиков и комментариев стало находить, профит что не говори.
А теперь «чуть-чуть про установку». Ставилось это на Debian 6.0 «Squeeze», и оказалось делом на много более простым, сравнительно с тем что описывается в старых топах.
Warning: Если у вас не Debian, а другой Linux или ещё что, то это, скорее всего, будет означать другую структуру каталогов, и прочие мелкие неприятности.
Warning II: В особенности вам не повезло, если вам нужна поддержка языка отличного от русского или английского. Sphinx это может, но не в стандартной упаковке. Удачи вам с компиляцией, я мысленно с вами. :)
Как установить Sphinx на Debian:
wget http://sphinxsearch.com/files/sphinxsearch_2.0.6-release-1_amd64.deb dpkg -i sphinxsearch_2.0.6-release-1_amd64.debВсё. Последняя на данный момент версия, нужный файл находиться за две минуты на официальном сайте Sphinx. Никакие конфигурационные файлы системного уровня делать и/или править не надо — всё уже как надо сразу из пакета.
Как запустить:
searchdКак остановить:
searchd --stopКак проверить, запущен или нет:
ps ax | grep searchdКак запустить полную пере индексацию (демон для этого должен быть остановлен):
indexer --allГде, по умолчанию, должен быть файл sphinx.conf:
/etc/sphinxsearch/Мелкая особенность вышеописанного sphinx.conf файла — для индексов создаётся специальная папка:
mkdir /var/lib/sphinxsearch/data/entityprefix/А больше про установку Shpinx сказать особо нечего.
В заключение, про cron для полноты картины. Выглядит, конфигурация оного, у нас так:
*/30 * * * * /usr/bin/indexer --rotate entityprefixtopicsIndex > /dev/null 2>&1 */10 * * * * /usr/bin/indexer --rotate entityprefixcommentsIndex > /dev/null 2>&1
Угу: топики раз в полчаса, комментарии раз в 10 минут. Да, я знаю что обычный совет — первое раз в три часа, второе раз в час. Но у нас полная индексация занимает менее двух секунд, и хоть как-то заметно сервер не грузит. С другой стороны, бывают дни, когда возбуждённое сообщество выдает на гора сотню комментариев и несколько новых заметок. Так чего тянуть? Пусть индексируется как можно быстрее. Я к тому, что не задумываясь следовать каким-то рекомендациям в этом вопросе — не лучший путь. Смотрите на собственную ситуацию с загрузкой сервера и активностью посетителей.
P.S. Посмотреть как работает «в живую» можно на сайте ММОзговед.
47 комментариев
Там разве не «entity» должно быть вместо «index»?
Единственное, если мы выводим и по тегам, то было бы неплохо и их подсвечивать (). Я так понимаю за это отвечает ActionSearch.class.php. Не подскажите как теги прогонять через автозамену совпавшего с поисковым запросом? Топики и комментарии подсвечиваются из коробки.
поставил новую просто из пакета (по ссылке sphinxsearch.com/downloads/release/)
единственное в конфиг пришлось добавить
compat_sphinxql_magics = 0
без этого ругался.
Видимо надо было так.
1. yum erase sphinx
2. wget sphinxsearch.com/files/sphinx-2.0.6-1.rhel6.x86_64.rpm
3. rpm -ivh /sphinx-2.0.6-1.rhel6.x86_64.rpm
rpm -ivh /sphinx-2.0.6-1.rhel6.x86_64.rpm
error: open of /sphinx-2.0.6-1.rhel6.x86_64.rpm failed: No such file or directory
3-м пунктом
rpm -ivh ./sphinx-2.0.6-1.rhel6.x86_64.rpm
С listen = 9312 — выдает такое:
Если ставлю порт 3312 в конфиге, то получаю такую каку:
У меня CentOS. Хотя раньше был Debian. Было проще :)
/var/lib/sphinxsearch/data/entityprefix/ я создал.
То есть какой-нибудь barabumprefix? или просто prefix?
В качестве префикс — что угодно. как и написано в топе — этот префикс нужен только для поддержки нескольких сайтов на LS одним и тем же демоном Sphinx. Но если вы его поменяете, то надо менять его на новое значение везде, где он встречается в sphinx.conf. И в config.php на новое значении тоже. Можно и не трогать вообще. Можно заменить везде на пустую строку.
На хабре кстати, писалось, не начёт сфинкса правда, а насчёт nginx+php-fpm, tcp гораздо лучше их пахал.
Префиксы расставлены соответственно сайтам, демон и останавливается и индексирует и стартует, в файлах config/modules/search/config.php префиксы указаны правильно соответственно
$config['entity_prefix'] = 'multi_'; и
$config['entity_prefix'] = 'ptz_';
Версию sphinx поставил последнюю 2.0.8. Помогите пожалуйста решить проблему поиска на двух сайтах. Спасибо.
$config['entity_prefix'] = 'multi_';
$config['entity_prefix'] = 'ptz_';
нужно было прописывать название БД, а я дурак префиксы из конфига sphinx.conf прописал:)
Вот этот топик хорошо помог livestreet.ru/blog/questions/11067.html
Указываем имя нужных БД у entity_prefix для поиска, на обоих виртуальных хостах в ['DOCUMENT_ROOT']/config/modules/search/config.php.
Я генерировал sphinx.conf как написано в том топике при помощи питоновского скрипта, и этот скрипт сформировал конфиг, где в качестве префиксов ко всяким source и прочим оказались прописаны именно названия баз данных. Х.З. кому верить:) И главное поиск тоже работает.
Вот прикиньте — Сфинкс складывает все свои индексные файлы в одну папку. Сайтов на одном сервере может быть несколько, а Сфинкс на сервере — один. И для каждого сайта он должен создать индексный файл TopicIndex (для поиска по топикам). Если префиксов не будет, то при работе с разными сайтами будет использоваться один файл и все будет валиться в хаотичную кучу. Для этого и нужны префиксы, чтоб для разных сайтов разные файлы использовались. Напр., для одного сайта — oneTopicIndex, для другого — twoTopicIndex и т.д.
Т.е. в качестве префиксов что угодно может быть, самое главное — они должны быть разными. Использовать в качестве префикса имя БД — не лучшая идея. Ведь несколько сайтов на ЛС могут юзать одну базу — достаточно им префиксы таблиц разные задать. Поэтому я бы советовал юзать в качестве префикса либо имя сайта (оно-то уникально), либо название БД+префикс таблиц
Небольшое отличие, ставил на Ubuntu 12.04 и в конфиге заменил пути к индексам с /var/lib/sphinxsearch/* на /var/run/sphinxsearch/*
Есть ли какая-то пошаговая инструкция для идиотов? Был бы очень признателен.