пятница, 14 мая 2010 г.

Как увеличить скорость процесса индексации Sphinx Search

Индексирование – это одна из двух важных операций выполняемых Sphinx Search (далее Sphinx). Если учитывать, что индексирование миллиона документов может занять от 20-30 минут на среднем сервере, то можно сказать, что индексирование одна из самых важных операций, которую стоит продумать очень тщательно.


Почему надо оптимизировать скорость индексации документов?



  1. Индексация очень “тяжелый” процесс для системы, каждый раз когда выполняется индексация, система использует много CPU и IO ресурсов

  2. Переиндексирование и объединение (merge) индексов занимает вдвое больше места на диске, чем объем всего индекса

  3. Индексирование замедляет выполнение других задач, например поиска по документам или выполнение sql запросов

  4. Загруженная система “тормозит” работу веб сайта, а из-за этого сайт теряет часть своих пользователей.


В этой статье вы узнаете как избежать всех выше перечисленных проблем.


Источник данных


Sphinx поддерживает два SQL источника данных – это MySQL и PostgreSQL. Sphinx работает таким образом, что на основе слов из источника данных формирует индекс, который любит очень разрастаться в размере и занимать все дисковое пространство и память.


Не будем останавливаться на оптимизации баз данных, а скажу одно, проверьте, что sql запросы, которые будут выбирать данные для индекса – работаю быстро. Это можно сделать с помощью команды sql EXPLAIN. Если же вас все таки не устраивает производительность вашей баз данных, то за дополнительными советами вы можете обратиться на сайт www.mysqlperformanceblog.com.


Итак, первое правило такое: индексируйте только те поля таблиц, по которым собираетесь выполнять поиск. Например не стоит включать в индекс большие текстовые поля, если по ним не будет поиска. Особенно это важно, если вы используете Sphinx не как полнотекстовый поиск, а как key-value базу данных.


Второе правило: держите длину индекса как можно меньше. Скажем у вас есть каталог товаров размером в 10GB, и товары которые были добавлены год назад вы не хотите использовать в поиске. Поэтому сделайте ограничение на выбираемые данные, не включайте в и индекс всю базу данных, а ограничьтесь только последним годом, задав соответствующее условие в sql запросе. Таким образом вы добьетесь существенного уменьшения длины индекса и увеличения производительности поиска.


Третье правило: разбивайте большие индексы на более мелкие в соответствии какому либо критерию. Например, год можно разбить по кварталам и уменьшить индекс в 4 раза. Если вам известна, какая категория товаров в какое время была добавлена, то вы можете производить поиск, только в одном из четырех индексов, а для поиска по всем данным, можно использовать распределенный индекс, который будет включать все четыре квартальных индекса. Прежде чем решить какую схему использовать с одним монолитным индексом или четырьмя распределенными, проверьте запросы которые вы будете выполнять к sphinx. Если большинство запросов потребует использование индекса за весь год, то возможно вам и не стоит разбивать индекс по кварталам. Смотрите ниже как может повлиять использование распределенных индексов на общую производительность запросов.


Четвертое правило: используйте ranged (ограниченные) запросы по количеству выбираемых записей. Это уменьшит нагрузку на sphinx и на базу данных.


Аттрибуиты


Каждый атрибут по умолчанию занимает 32 или 64 бита, и учитывая, что обычно Sphinx используется для индексирования по меньшей мере миллионов документов, то в Sphinx была предусмотрена возможность задавать определенный размер для атрибута.


Пятое правило: ограничивайте длину атрибуту битовой маской, там где это возможно. Например количество стран не превышает размера в 16 бит, поэтому такой атрибут стоит ограничить 2 байтами. А это уменьшит размер атрибута в 2 раза на 32 битной платформе и в 4 раза на 64 битной, что в свою очередь существенно уменьшит общий размер индекса. Конечно, лучшим вариантом будет ограничить каждый атрибут с минимальным запасом длины. Но, в таком случае, незабывайте периодически проверять атрибуты, чтоб неожиданно не выйти за пределы размера атрибута.


Распределенные (distributed) индексы



Про распределенные индексы вы должны знать, что скорость работы такого индекса зависит от скорости самого медленного агента. В большой системе с тысячами индексов, десятками sphinx агентами и несколькими серверами тяжело обнаружить проблему “медленного агента”. Но, как показала практика, всегда найдется какой нибудь перезагруженный sphinx агент, который замедляет 20% всех запросов. Избежать этой проблемы можно с помощью регулярного поэтапно тестирования каждого агента и переноса нагрузки на других агентов. Много информации про скорость выполнения запросов вы можете получить исследуя логи shpinx.


Поэтому шестое правило следующее: регулярно тестируйте sphinx запросы и анализируйте логи.


Конфигурационные параметры индексера



При переиндексации, опция inplace_enable позволяет уменьшить вдвое требуемое дисковое пространство при переиндексации. Но, с другой стороны включение этой опции замедлит производительности индексации на 5-10%. Эта опция будет полезна на серверах с очень ограниченным количеством дискового пространства, правда при потере производительности индексации. По умолчанию опция отключена и следует заметить, что она влияет только на indexer не затрагивая никоим образом searchd.


С помощью mem_limit можно контролировать количество выделяемой оперативной памяти для индексации. Наиболее оптимальным вариантом будет установка от 256Mb до 1024Mb. Слишком низкие значения могут привести к ухудшению скорорсти индексации. Слишком высокие могут привести к timeout с MySQL базой. Так как буффер пул необходимо будет обработать большой, то возможна потеря соединения. По умолчанию данный параметр равен 32Mb. Максимальное значение 2047Mb.


Опция max_iops влияет на количество I/O(read, write) операций работы с диском в секунду. Если во время индексации, производительность поиска существенно уменьшается, то стоит подумать о настройке max_iops. По умолчанию данная опция имеет значение 0, т.е. неограничено (unlimited). Также стоит обратить внимание на опцию max_iosize, которая позволяет установить размер буфера чтения/записи при индексации. По умолчанию эта опция равна 0, т.е. размер буфера не ограничен. С помощью утилиты fio вы можете вычислить количество I/O операций в секунду, а также узнать размер I/O кеша. После того как вы определили характеристики вашего диска, попытайтесь потестировать indexer и searchd с разными настройками max_iops и max_iosize.


Вывод





  • Формируйте свой основной sql запрос (sql_query) грамотно.





  • Не включайте все поля сразу, а выбирайте только те, которые будете использовать.





  • Используйте условия (where) в sql выборке, чтоб не перегружать индекс ненужными данными.





  • Разбивайте большие монолитные индексы, на более мелкие в соответствии какому либо критерию, например по кварталу или году.





  • Используйте возможность пошаговой выборки (ranged queries), это уменьшит вероятность блокировки базы данных на время выборки.





  • Ограничивайте короткие атрибуты битовой маской.





  • Тестируйте sphinx запросы и анализируйте логи.








© Yaroslav Vorozhko for Просто про веб технологии, 2010. |
Permalink |
No comment |
Add to
del.icio.us


Post tags:

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

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