Категории публикаций
Подписка на рассылку по Email
новости (подписчиков: 2)
комментарии (подписчиков: 2)

Отменить подписку
Популярные публикации
Интересный опрос
Вы используете криптовалюту Bitcoin?

Да, давно использую
Начал использовать
Интересуюсь
Нет, не использую
А что такое Bitcoin?
Поблагодарить автора
donate
1B4ZZ2PXUd9E7AqEB82AqFnkpk2bt5hQG7

Установка Sphinx под Linux - строим свой поисковый сервер

Размещено в категории: Linux

Sphinx Sphinx - поисковый сервер и открытым исходным кодом (Open Source Search Server) для индексации контента из баз данных и осуществления полнотекстового поиска, разработанный Андреем Аксеновым. В статье пошагово рассказано как установить и настроить поисковый сервер Sphinx на сервер под управлением операционной системы Linux (Ubuntu/Dedian). Приведены примеры, советы и ссылки которые будут полезны как администраторам так и разработчикам.

Прежде чем приступить к пошаговому мануалу по установке и настройке поискового сервера Sphinx хочу вам рассказать как я познакомился с данной системой и что послужило толчком к ее использованию.

С самого начала, когда только начинал программировать на PHP и писал несложные сайты, я использовал собственный самописный поисковый движок с простой логикой. Он воспринимал одно и несколько слов в поисковой фразе и выдавал те записи в которых было обнаружено вхождение. Сначала делал с индексированием контента и кешированием индекса, потом делал полнотекстовый поиск на PHP. Конечно же данная реализация не лишена недостатков, основной недостаток - это не достаточно релевантная поисковая выдача поскольку мой движок не учитывал морфологию слов, а искал только прямые вхождения поисковых фраз с простым анализом распределенности по статье. Писать мощный поисковый модуль со сложной логикой и оптимизациями "на стероидах" у меня не было ни времени ни особого желания.

Яндекс

Позже я узнал про поиск от Яндекса, который без особого труда можно прикрутить к своему сайту используя Yandex XML Search API. К моему движку был написан модуль для осуществления поиска используя Yandex XML Search API и казалось бы все просто супер но со временем меня начали не устраивать некоторые ограничения и неудобства при работе с Yandex XML Search.

Вот что мне показалось неудобным при использовании Yandex XML Search API:

  • ограничение на количество запросов в сутки, а потом еще сделали график ограничений для разного времени суток. Хотите уменьшить ограничения...отправьте СМС на номер...шутка, можно стать партнером Яндекса, для аккаунта зарегистрироваться в партнерской сети Яндекс Директ (РСЯ), связаться с поддержкой Яндекса и рассказать им зачем вам нужно большое количество запросов к Yandex XML Search API.
  • поиск производится только по контенту, который проиндексирован Яндексом. Если странички нет в индексе Яндекса - ее вы никогда не увидите в поисковой выдаче своего сайта.
  • привязка сайта к стороннему сервису, зависимость поиска от него.

Sphinx

И тут я вспомнил что читал когда-то на Хабре и еще на каком-то блоге по HighLoad-проектам о мощном бесплатном поисковом движке с расширенным анализом и множеством возможностей по настройке и интеграции. Назывался этот движок Sphinx(сфинкс). Очень удачное название, хорошо запоминается и легко ищется в Google/Yandex.

Основные характеристики и возможности Sphinx:

  • индексирование:  до 10-15Мб на каждое ядро микропроцессора;
  • поиск: 150-250 поисковых запросов в секунду на каждое ядро при 1Млн документов в индексе;
  • высокая масштабируемость;
  • распределенный поиск;
  • поддержка до 32 и более полей при полнотекстовом поиске;
  • поддержка дополнительный атрибутов для каждого из индексируемых документов;
  • возможность использовать стоп слова;
  • поддержка однобайтовых (СЗ1251 и т.п) и двухбайтовых кодировок (UTF-8);
  • морфологический поиск с модулями для разных языков;
  • поддержка MySQL и PostgreSQL из коробки;
  • поддержка других ODBC совместимых баз данных;
  • кроссплатформенность;
  • готовые к использованию решения API для языков PHP, Python, Java.

Сфинкс используется на многих высоконагруженных проектах, к примеру это Хабрахабр, Викимапия и другие. Система себя зарекомендовала с наилучшей стороны, известно что существует поисковый кластер в котором проиндексировано около 3 миллиардов документов и который осуществляет более 50 миллионов поисковых запросов в сутки.

Полистав документацию и прочитав бегло несколько русских/английских статей по установке в уме быстро очертил себе четкий алгоритм действий. Со своим опытом установки и настройки Sphinx я хочу сейчас познакомить тебя, мой дорогой читатель.

Как все работает

На сервер ставится поисковый демон Sphinx, который индексирует через заданный промежуток времени статьи и контент вашего сайта - создает поисковый индекс. На вашем сайте подключается Sphinx API, который есть для Java, PHP, Ruby (можно написать реализацию и для других языков), пишется поисковый модуль который делает несложные запросы к демону(сервису) Sphinx - searchd. При запросе поисковой фразы с поисковой формы сайта через Sphinx API делается обращение к демону searchd, который нам возвращает ID записей с нужной сортировкой и фильтрацией. Дальше имея ID публикаций мы делаем один запрос к БД сайта и получаем всю информацию о наших статьях, остается только красиво вывести список найденных элементов.

Установка и настройка Sphinx на Linux

Предполагается что у вас уже установлена ОС Linux, на которой будет работать (или уже работает ) сайт или сервис, на котором нужно будет использовать Sphinx Search API.

Обновляем источники пакетов и ставим нужный софт:

apt-get update
apt-get install gcc make libmysqlclient15-dev libmysql++-dev g++

Идем по ссылке http://sphinxsearch.com/downloads/release/ и качаем архив с исходными кодами для последнего стабильного релиза ( Get Source tarball tar.gz ). Потом распаковываем архив и переходим в разархивированную папку. Вот к примеру я качал 2.1.3-release:

cd /tmp/
wget -c "http://sphinxsearch.com/files/sphinx-2.1.3-release.tar.gz" && ls
tar -xf sphinx-2.1.3-release.tar.gz
cd sphinx-2.1.3-release

Теперь компилируем наш Сфинкс с поддержкой MySQL (есть поддержка и других БД, смотри док.), поскольку весь полезный контент сайта хранится в БД MySQL:

./configure --with-mysql --prefix=/usr/local/sphinx 
make
make install

Копируем шаблон файла с настройками и редактируем его содержимое под наши нужды:

cp /usr/local/sphinx/etc/sphinx.conf.dist /usr/local/sphinx/etc/sphinx.conf
nano /usr/local/sphinx/etc/sphinx.conf

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

# Настройки источника "mysqlbasename" с которого будем брать контент
source mysqlbasename
{
 type = mysql # тип источника, в данном случае БД MySQL
 sql_host = localhost # Хост MySQL
 sql_user = dbusername # Пользователь MySQL
 sql_pass = dbuserpassword # Пароль MySQL
 sql_db = mysqlbasename # Название БД в MySQL
 sql_port = 3306 # Порт сервера MySQL
 sql_query_pre = SET NAMES CP1251 # Кодировка индексируемой таблицы
# Запрос которым делаем выборку всех записей, которые должны быть проиндексированы
 sql_query =  SELECT title, full_text  FROM posts WHERE publicated=1
# Используется только в CLI (при обращении через командную строку), можно оставить пустым
 sql_query_info = SELECT * FROM posts WHERE id=$id
}

# настройки построения индекса с использованием источника "mysqlbasename"
index mysqlbasename
{
 source = mysqlbasename # Имя источника данных
# Путь по которому будут сохранены файлы индекса, если индекс большой то можно 
# перенести на отдельный раздел или жесткий диск. path = /usr/local/sphinx/var/data/mysqlbasename # Настройка хранения значений атрибутов документов, extern - хранить раздельно по ID. docinfo = extern mlock = 0 # Бдокировка памяти для кеширования данных, 0 - нет. morphology = stem_en, stem_ru, soundex # набор морфологическиз препроцессоров для обработки. min_word_len = 3 # минисмальная длина слова для индексации charset_type = sbcs # Single Byte Character Set - кодировка, в данном случае для CP1251. html_strip = 1 # Чистить или нет HTML (1 - да) } # настройки индексатора indexer { mem_limit = 32M # лимит памяти для работы индексатора } # настройки поискового демона (SearchDaemon, searchD) searchd { listen = 9312 # порт для работы через API listen = 9306:mysql41 # порт для комуникаций с MySQL log = /usr/local/sphinx/var/log/searchd.log # логи демона query_log = /usr/local/sphinx/var/log/query.log # логи поисковых запросов read_timeout = 5 # таймаут чтения в секундах client_timeout = 300 # таймаут поддержания соединения, между запросами в секундах max_children = 30 # Максимально допустимое количество порождаемых процессов pid_file = /usr/local/sphinx/var/log/searchd.pid # PID(ProcessID) файл родительского процесса max_matches = 1000 # Максимальное количество полученных результатов seamless_rotate = 1 # предотвращает паралич search при работе с большим количеством кешируемых данных preopen_indexes = 0 # Откривать все индексы при запуске, 0 - нет unlink_old = 1 # чистка старых индексов, 1 - да mva_updates_pool = 1M # Резервируемый размер пула в ОЗУ для обновлений max_packet_size = 8M # Максимальный размер сетевого пакета для обмена данными max_filters = 256 # Максимальное количество фильтров что можно использовать на один запрос max_filter_values = 4096 # Макс. количество значений для одного фильтра } # --eof--

Запускаем индексацию наших данных:

/usr/local/sphinx/bin/indexer --all --verbose

В случае успешного индексирования получим примерно вот такие строки:

Sphinx 2.1.3-dev (r4319)
Copyright (c) 2001-2013, Andrew Aksyonoff
Copyright (c) 2008-2013, Sphinx Technologies Inc (http://sphinxsearch.com)

using config file '/usr/local/sphinx/etc/sphinx.conf'...
indexing index 'mysqlbasename'...
WARNING: Attribute count is 0: switching to none docinfo
collected 518 docs, 3.2 MB
sorted 0.4 Mhits, 100.0% done
total 518 docs, 3195655 bytes
total 0.637 sec, 5013995 bytes/sec, 812.74 docs/sec
total 2 reads, 0.000 sec, 745.7 kb/call avg, 0.3 msec/call avg
total 8 writes, 0.001 sec, 390.4 kb/call avg, 0.2 msec/call avg

Запускаем поискового демона:

/usr/local/sphinx/bin/searchd

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

Sphinx 2.1.3-dev (r4319)
Copyright (c) 2001-2013, Andrew Aksyonoff
Copyright (c) 2008-2013, Sphinx Technologies Inc (http://sphinxsearch.com)

using config file '/usr/local/sphinx/etc/sphinx.conf'...
listening on all interfaces, port=9312
listening on all interfaces, port=9306
precaching index 'mysqlbasename'
precached 1 indexes in 0.000 sec

Делаем тестовый поисковый запрос, где YOUR_QUERY_STRING - ваша поисковая фраза:

/usr/local/sphinx/bin/search --config /usr/local/sphinx/etc/sphinx.conf YOUR_QUERY_STRING

После запуска будет выведена длинная простыня записей что отвечают критериям поиска.

Проверяем работу поиска с использованием PHP API. Внимание: PHP должен быть установлен на сервере! "YOUR_QUERY_STRING" - ваш поисковый запрос

cd /tmp/sphinx-2.1.3-release/api/
php test.php YOUR_QUERY_STRING

Надеюсь у вас все получилось? - отлично! Теперь осталось сделать чтобы демон стартовал при загрузке/перезагрузке ОС, а также настроить периодику индексирования данных.

nano /etc/init.d/searchd

Копипастим (CTRL+C, CTRL+V) этот текст в скрипт /etc/init.d/searchd :

#!/bin/bash

#!/bin/sh
### BEGIN INIT INFO
# Provides:          searchd
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# X-Interactive:     true
# Short-Description: Stop/Start SphinxSearch Daemon
### END INIT INFO

case "${1:-''}" in

'start')
/usr/local/sphinx/bin/searchd
;;

'stop')
/usr/local/sphinx/bin/searchd --stop
;;

'restart')
/usr/local/sphinx/bin/searchd --stop
sleep 1
/usr/local/sphinx/bin/searchd
;;

*)
echo "Usage: $SELF start|stop|restart"
exit 1
;;

esac

Даем права на скрипт запуска и регистрируем его в автозапуске:

chmod +x /etc/init.d/searchd
update-rc.d searchd defaults

Добавляем в крон(crontab) запуск индексатора каждые сутки:

nano /etc/crontab

Дописываем в конец эту строчку:

0  0    * * *   root    /usr/local/sphinx/bin/indexer --rotate --all --config /usr/local/sphinx/etc/sphinx.conf

Все готово! Вы установили и настроили поисковый сервер Sphinx.

Ах да...про безопасность еще хочу упомянуть: сфинкс открывает порты 9312, 9306(указанные в настройках) на всех интерфейсах, настоятельно рекомендую прикрыть их при помощи файрвола на наружном интерфейсе(интернет). Вот два простых правила для IPTABLES:

iptables -A INPUT -p tcp -i eth0 --dport 9306 -j DROP
iptables -A INPUT -p tcp -i eth0 --dport 9312 -j DROP

Где eth0 - имя наружного сетевого интерфейса.

PHP - пример простого взаимодействия со Sphinx

Итак, сервер настроен все проиндексировано, работоспособность проверена. Качаем себе Sphinx API класс для работы в PHP:

https://code.google.com/p/sphinxsearch/source/browse/trunk/api/sphinxapi.php?r=2014

Помещаем скрипт sphinxapi.php в свой проект и подключаем этот скрипт при помощи include/require.

Вот простая реализация подключения и выборки при помощи PHP(код для примера):

$cl = new SphinxClient();
$page = 3; // our results page number
$items_per_page = 10; // show 10 results per page
$index_name = 'mysqlbasename '; // Index name to fetch from
$request = 'купить носки';

$cl->SetServer( "localhost", 9312 ); // server, port
$cl->SetConnectTimeout( 1 ); // max connect timeout
$cl->SetMaxQueryTime(1000); // max query timeout
$cl->SetMatchMode( SPH_MATCH_ALL  ); // ALL, ANY, PHRASE, EXTENDED...
$cl->SetLimits(intval($page*$items_per_page), intval($items_per_page), 1000);
$result = $cl->Query( $request, $index_name );
if ( $result === false ) {
 if( $cl->GetLastWarning() ) { // check for warnings
  echo 'WARNING: '.$cl->GetLastWarning();
  exit;
 }
 // no warnings found, result=FALSE
 exit('Cannot connect etc.');
}

echo 'Total results found: '.$result['total'];
// Compose comma separated string with posts IDs
foreach ($result['matches'] AS $key => $row)
		$ids_arr[] = intval($key);
	$ids_csv = join(',', $ids_arr);
// fetch posts from DB
$mysql_result = mysql_query(SELECT id, title, text FROM `posts` WHERE id IN (".$ids_csv.") AND publicated=1);
while ( $mysql_object = mysql_fetch_object($mysql_result) ) {
...
}
...

 

Полезные ссылки

http://sphinxsearch.com - оффициальный сайт поискового движка Sphinx.

http://sphinxsearch.com/docs/ - официальная документация для каждого из релизов Sphinx.

http://sphinxsearch.com/wiki/doku.php?id=sphinx_docs - Wiki документация по Sphinx на одной странице.

http://sphinxsearch.com/wiki/doku.php?id=php_api_docs - Wiki документация по PHP API для Sphinx.

http://code.google.com/p/sphinxsearch/ - исходники и примеры на code.google.com.

Этой информации с лихвой достаточно чтобы во всем разобраться и все настроить под себя.

 (0/5) голосов: 0   просмотров: 1276


Тематика:  sphinx  поиск  сервер  сервис  linux

Комментарии к публикации (3)
fregat 1 fregat 
20 Ноябрь 2015 08:56

Доброго времени суток, Total results found показывает что 24, $result['matches'] отсутствует в массиве $result. Как проблему побороть?

0 
ph0en1x 2 ph0en1x 
20 Ноябрь 2015 11:21

Здравствуйте. Статья писалась на момент выхода версии sphinx-2.1.3-release, с этой версией все проверено и прекрасно работает. Если же у вас установлена данная версия то следует пересмотреть настройки сервера Sphinx, проверить все ли хорошо с кодировкой для вашего текста и с кодировкой по умолчанию для версии PHP, которая работает на вашем сервере приложений.

Если у вас другая, более свежая версия сервера SphinxSearch (например 2.2.10-release) то здесь нужно использовать более новый SphinxSearch PHP API - https://code.google.com/p/sphinxsearch/source/browse/trunk/api/sphinxapi.php
Также в данном случае более целесообразно использовать новый инструмент для запросов к серверу SphinxQL Query Builder for PHP, который является более производительным и позволяет задавать условия выборки результатов используя синтаксис подобный до языка SQL - http://sphinxsearch.com/blog/2014/10/20/sphinxql-query-builder-for-php/

0 
Игорь 3 Игорь 
14 Июнь 2016 12:12

добрый день,
я бы заказал у вас установку на сервер сфинкса.
бд с 3 млн товаров.
ответьте, если есть желание.

0 

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