Get Social

Установка и настройка Sphinx 2.2.11 (Yii и дельта-индексы) на Ubuntu / Debian и RHEL / CentOS 7

После перехода с версии 1 на 2 в sphinx много изменений. Больше не работают запросы в командной строке через searh, удалены многие директивы из конфигурационного файла и другое. Будем разбираться.

Установка Sphinx 2.2.11 на Ubuntu / Debian и RHEL / CentOS 7

Для начала нужно поставить пакет:

Ubuntu/Debian:
aptitude install sphinxsearch

RHEL/CentOS:
yum install -y postgresql-libs unixODBC
wget http://sphinxsearch.com/files/sphinx-2.2.11-1.rhel7.x86_64.rpm
yum install sphinx-2.2.11-1.rhel7.x86_64.rpm

Настройка Sphinx 2.2.11 на Ubuntu / Debian и RHEL / CentOS 7

Ubuntu/Debian:
nano /etc/sphinxsearch/sphinx.conf

RHEL/CentOS:
vi /etc/sphinx/sphinx.conf

Сам конфигурационный файл Sphinx состоит из блоков для source, indexer и searchd.
Вот пример конфигурации Sphinx + дельта-индексы:

# for db connect to include in other sources
source dbconnect
{
	type			= mysql
	sql_host		= localhost
	sql_user		= your_db_user
	sql_pass		= your_db_pass
	sql_db			= your_db_name
	sql_port		= 3306
}

# --------- products --------- #
# sources products
source sphinx_source_products : dbconnect
{
        sql_query_pre		= SET NAMES utf8mb4
	sql_query_pre = \
	        update sphinx_delta_counter \
	        set last_post_id = (select max(id) from tb_products) \
	        where index_name = 'sphinx_index_products';
	sql_query = \
		SELECT id, title, descr \
		FROM tb_products \
		WHERE status = 1 # or any your condition
#	sql_attr_uint = id
	sql_field_string = title
	sql_field_string = descr
}
source sphinx_source_products_delta : dbconnect
{
        sql_query_pre		= SET NAMES utf8mb4
        sql_query = \
		SELECT id, title, descr \
		FROM tb_products \
		WHERE status = 1 AND id > (select last_post_id from sphinx_delta_counter where index_name = 'sphinx_index_products');
#	sql_attr_uint = id
	sql_field_string = title
	sql_field_string = descr
}
# indexes products
index sphinx_index_products
{
	source			= sphinx_source_products
	path			= /home-path-to-web-dir/example.com/sphinx_data/sphinx_products
	dict			= keywords
	morphology		= stem_ru, stem_en
	min_word_len		= 2
	docinfo			= extern
}
index sphinx_index_products_delta
{
        source                  = sphinx_source_products_delta
        path                    = /home-path-to-web-dir/example.com/sphinx_data/sphinx_products_delta
        dict                    = keywords
        morphology              = stem_ru, stem_en
        min_word_len            = 2
        docinfo                 = extern
}
# --------- / products --------- #

# some tables
# what you need
# just as it is done section above

indexer
{
	mem_limit		= 32M
}

searchd
{
	listen			= 9312
	listen			= 9306:mysql41
	log			= /var/log/sphinx/searchd.log
	query_log		= /var/log/sphinx/query.log
	read_timeout		= 5
	max_children		= 30
	pid_file		= /var/run/sphinx/searchd.pid
#	max_matches		= 1000
	seamless_rotate		= 1
	preopen_indexes		= 1
	unlink_old		= 1
	workers			= threads # for RT to work
	binlog_path		= 
#	binlog_path		= /var/log/sphinx
 # use /var/log/sphinxsearch/ and  /var/run/sphinxsearch/ paths for ubuntu
}

Замените тут “your_db_user”, “your_db_pass”, “your_db_name”, “/home-path-to-web-dir/example.com/” на свои значения. Создайте папку для хранения индексов, например “sphinx_data”. Отредактируйте sql_query и sql_query_pre под свою базу. Для этого необходимо продумать запрос для поиска, а также выбрать колонку поиска и прописать её в sql_field_string (если несколько – значит несколько строк прописать соотвественно).

Sphinx delta index. Индексирование больших объёмов данных.

Для того, чтобы не переиндексировать в течение дня (если у вас большая база данных mysql) всю базу, используются дельта-индексы. Просто создаём в базе mysql таблицу “sphinx_delta_counter” с колонкой “last_post_id”. Из запроса в конфиге, думаю, понятно, что сюда записывается последний проиндексированный id. В поиск потом нужно будет включить оба индекса.

Для работы с русским языком нужно установить кодировку базы: SET NAMES utf8 (или SET NAMES utf8mb4), а также морфологию: параметр stem_ru . Строку “sql_query_pre = SET NAMES utf8mb4” обязательно нужно прописывать в каждый source отдельно, если в общий connect -> это не работает. Долго пришлось мучаться с ошибкой из-за того, что sphinx не индексировал русские слова.

Настройка Sphinx для Yii2

  1. Поставить расширение yii2-sphinx для Yii.
  2. Отредактировать config/main.php (секция components):
    'sphinx' => [
    'class' => 'yii\sphinx\Connection',
    'dsn' => 'mysql:host=127.0.0.1;port=9312;',
    'username' => '', # тут обычно не надо ничего указывать
    'password' => '', # тут обычно не надо ничего указывать
    ],
  3. Полнотекстовый поиск с морфологией и прочими плюшками:
    use yii\sphinx\Query;
    $query_search = new Query();
    $search_result = $query_search->from('siteSearch')->match($q)-all();

Индексация, запуск и проверка Sphinx

После настройки конфигурационного файла sphinx нужно проиндексировать все source, которые мы создали:
indexer --all

Потом прописать в крон (как тут видно – раз в сутки пересоздаётся полный индекс, а каждые 5 минут – дельта):
crontab -e
0 1 * * * /usr/bin/indexer --config /etc/sphinx/sphinx.conf sphinx_index_course --rotate > /dev/null
*/5 * * * * /usr/bin/indexer --config /etc/sphinx/sphinx.conf sphinx_index_course_delta --rotate > /dev/null

Перед запуском службы полезно будет сделать владельцем папки с индексами sphinxsearch (или sphinx):
chown sphinxsearch: /home-path-to-web-dir/example.com/sphinx_data

Запускаем Sphinx командой:
systemctl start searchd

В Ubuntu (или Debian), возможно получите сообщение:
Failed to start searchd.service: Unit searchd.service not found.
В этом случае – попробуйте такой вариант:
systemctl start sphinxsearch
Можно также включать sphinx альтернативной командой:
/etc/init.d/sphinxsearch start
Также, возможно, необходимо в файле /etc/default/sphinxsearch будет прописать START=yes (вместо START=no).

Чтобы проверить, можно воспользоваться такой командой:
systemctl status searchd
или
systemctl status sphinxsearch

Также, чтобы убедиться, что служба работает и слушает заданные порты:
ps aux | grep search
lsof -i tcp:9306
lsof -i tcp:9312

Раньше (в sphinx 1.x) можно было проверить поиск в консоли:
search -i название_индекса "слова поиска"

Теперь эту функцию убрали, но, всё равно есть возможность проверить, всё ли хорошо с индексацией и попадают ли нужные слова в индекс.

Вместо поиска в консоли sphinx можно использовать следующую команду:
indextool --dumphitlist sphinx_index_course "какое-нибудь слово" | more

Кроме того, можно проверить поиск с помощью MySQL-клиента, как предлагает разработчик Sphinx:

# To query search daemon using MySQL client:
mysql -h 0 -P 9306
mysql> SELECT * FROM test1 WHERE MATCH(‘test’);

Ошибки при запуске Sphinx

любые deprecated – это наследие от предыдущих версий – закомментируйте или удалите эти параметры