Оптимизация для ускорение запросов

Имеется сайт с большим количеством товаров. Количество порядка 50 млн.
Сейчас он работает на поисковике sphinx 3. до этого был sphinx 2.
Работает более менее нормально. Было решено перейти на мантикору.
Создали распределенный rt индекс (состоит из 8 штук), написали индексатор и отдельный скрипт обновления данных. Дополнительно настроили репликацию базы чтобы индекс был на одном сервере и а запросы на выборку к другому серверу, для распределения нагрузки.
Индексатор справляется отлично. за 3 часа все 50 млн товаров добавляет в индекс или обновляет. отсутствующие удаляет.
репликация так же работает отлично. Что-то изменили на первом сервере, тут же появляются данные на втором.
Но вот как только мы переключили запросы со sphinx на мантикору, тут же увидели увеличение времени генерации страниц. sphinx справляется раза в два быстрее чем мантикора.
Но заметили такую закономерность. запросы тормозят не все подряд а только некоторые. грубо говоря при отправке 200-300 запросов в сек среднее время отдачи 0.5 сек
если брать отдельные запросы (причем 200-300 не выключаем) и отправлять по одному, то они выполняются за 0,1 сек. и поймать запрос который выполняется долго просто не реально…
По мониторингу нагрузки нет. CPU выросло где-то а 10%, диски тоже работаю 30-40% от своих возможностей. Памяти 256 ГБ. Ядер проца 32 шт.

Подскажите в какую сторону смотреть?

Смотрите в сторону:

Sphinx работал тоже на RT индексах или plain? При нагрузке что показывает dstat? Где боттлнек? Процессор или диск? iowait большой?

Sphinx работал на plain индексах.
Сейчас все таки обнаружили что нагрузка на CPU очень сильная. на одном из серверов нагрузка почти 100% на другом 50%
может мы как то не так сделали индексы.
CREATE TABLE ind0 (
section_id integer,
section_hz integer,
user_id integer,
price integer,
discount integer,
type_id integer,
city_id multi,
name_len ,
name text
) min_prefix_len=‘3’ index_exact_words=‘1’ index_field_lengths=‘1’ morphology=‘lemmatize_ru, lemmatize_en’
Таких индексов 8 штук объединенных в один составной
выборка идет обычным матчем с указанием city_id и иногда добавляется section_id
может из за каких то дополнительных настроек сильно все тормозит?

может быть, что rt_mem_limit установленый по умолчанию - оказался низким, для ваших обемов данных и у вас оказывается очень много дисковых чанков.

Можете проверить вывод команды show index ind0 status и запустить optimize для индексов где количество disk chunks велико?

show index ind0 status показывает
http://joxi.ru/a2XxWWIwXL6K2g
rt_mem_limit увеличил до 2 ГБ на каждый из 8 индексов.

еще такой вопрос
при выставлении в запросе весов то возникает ошибка
Fields specified in field_weights option not found: [section_hz]

из конфига убрал min_prefix_len=‘3’ index_exact_words=‘1’ index_field_lengths=‘1’ может какая то опция указывает чтото?

и можете дать ссылку где почитать насчет дисковых чанков? за что они отвечают, что дают? т.е. их физику.
также интересует FACET что это? на что влияет? в моем понимание фасетный индекс ускоряет запросы но тут не могу разобраться для чего?

при отправке 200-300 запросов в сек среднее время отдачи 0.5 сек
если брать отдельные запросы (причем 200-300 не выключаем) и отправлять по одному, то они выполняются за 0,1 сек

Так а что тут странного? Concurrency 200-300 отличается таки от concurrency 1 в 200-300 раз и просадка latency в 5 раз вроде нормальна при этом.

Создали распределенный rt индекс (состоит из 8 штук)

Sphinx работал на plain индексах.

disk_chunk : 15

Ядер проца 32 шт

В sphinx до конца непонятно как было: то ли один всего индекс, то ли 8 шардов и соответственно 8 индексов, но в данном случае в Manticore у вас получается 15 чанков * 8 шардов = 120 чанков (по сути plain индексов), а ядер 32. И concurrency пикует до 200-300. Думаю, в вашем случае можно попробовать чанка по два на шард оставить, если вообще не один. Попробуйте optimize index IDX option cutoff=2 для каждого шарда сделать (в test environment) в качестве эксперимента. Тут нужно выбирать исходя из того, чего хочется: низкий latency в пиках - тогда при таком concurrency поменьше чанков оставлять или вне пиков - тогда можно и побольше. В общем нужно экспериментировать.

Fields specified in field_weights option not found: [section_hz]

Это не филд у вас, а атрибут:

section_hz integer

и можете дать ссылку где почитать насчет дисковых чанков? за что они отвечают, что дают? т.е. их физику.

Да всё просто: RT индекс - это по сути просто обёртка, которая скрывает в себе plain index’ы + дистрибутивный индекс + RAM chunk. Инсертите в RT - сперва всё аккумулируется в RAM chunk’е, когда rt_mem_limit переполняется - сбрасывается в дисковый чанк, т.е. по сути создаётся plain index.

также интересует FACET что это? на что влияет? в моем понимание фасетный индекс ускоряет запросы но тут не могу разобраться для чего?

Просто такая группировка. Почитайте в доке - Manticore Search Manual: Searching > Faceted search

Посмотрите курс - Manticore Faceting

sphinx работал на 8 шардах. отдельные индексы 8 штук plain типа

Насчет 200-300 запросов в сек не выключаются когда я отправляю 1 запрос с верху.

по чанкам все понял. снизил на 2 но пока видимо идет перерасчет так как не быстро всем 8 индексам перейти на 2. пока только 3 индекса стали с двумя чанками.

пои филду и атрибуту. поясните разницу пожалуйста. как это отличается? всмысле как создать тогда этот вилд? я думал section_hz integer уже как бы создало поле которое может участвовать в опциях.

и расскажите пожалуйста по производительности разницу между атрибутом и филдом? т.е. если я переведу из атрибута в филд нагрузка теоретически увеличится?

Еще такой вопрос: в запросах которые я отсылаю везде присутствует указание города any(city_id) IN (1,2,3,…)
city_id это атрибут типа multi . все верно для такой выборки? может есть какой то типа индекс как в mysql который бы отсекал ненужные значения в поиске?

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

По Фасету понял. Функционально он предоставляет данные по вариантам фильтрации по том или иному атрибуту. По сути это как фильтр в каталоге товаров.

Спасибо большое за optimize index IDX option cutoff=2 Действительно снизив чанки до двух сервер перестал нагружаться по процессору. подумываю увеличить на 3. суммарно будет 24 чанка. ядер все таки 36. поэтому 12 ядер будет свободно

Подскажите пожалуйста а есть тогда смысл разбивать индекс на 8 шардов если чанки по факту делают тоже самое? или все таки не тоже самое?
т.е. в моем случае 8 шардов по 2 чанка в каждом это 16 чанков суммарно. Если я сделаю один единственный индекс и там укажу 16 чанков?

Прочитайте для начала Manticore Search Manual: Creating an index > Data types , пожалуйста.

Зависит от многого, однозначно сказать нельзя. Но вообще использование full-text вместо атрибутов - это скорее хак, редко нужно.

Да, для синтаксиса any … in атрибут типа multi - то, что надо.

Пока нет, работаем над этим.

Зависит от запроса и рапределения искомых данных в чанках или шардах. Важно, чтоб не читалось и не обрабатывалось лишнего, а нужное читалось и обрабатывалось параллельно. Как этого добиться в вашем конкретном случае нужно думать и экспериментировать.

1 Like