Documentation index
- ReadMe
- Things To Know
-
- New Style Rotation
Когда ваша база разрастается до приличного размера, скажем больше 100 000 галер, скорость поиска стандартным средствами mysql заметно падает.
Sphinx это система быстрого поиска с учетом морфологии. Более того, имеет смысл внедрять ее и до достижения вашей базой приличного размера из-за преищуществ морфологического поиска.
Sphinx условно делает “выжимку” из базы в виде id - кейворды. Поиск по такой базе намного быстрее (к тому же сама структура Sphinx оптимизированна именно для поиска)
Алгоритм работы примерно такой: скрипт делает запрос в Sphinx, тот возвращает только ИД галер, и скрипт делает выборку этих ИД из mysql базы. Из этого следует то, что если меняется mysql база, то надо менять и sphinx базу.
Как работает сфинкс: он проходит по всей базе и составляет на ее основе свой индекс (Sphinx Search Index ), по которому умеет искать быстро и хорошо. Из чего следует что периодически этот индекс надо обновлять. Если в базе были изменения они появяться в Sphinx Search Index только после переиндексации.
На большой базе переиндексация может быть довольно тяжелым процессом поэтому добавляется Sphinx Delta Index, смысл которого что можно индексить только новые записи, что быстро, и потом периодически сливать воедино с Sphinx Search Index
Так же можно индекссиировать сфинксом лог поисковых запросов, что б пользоваться преимуществами сфинкса для поиска похожих запросов (Sphinx Search Log Index)
Сфинкс умеет по-разному искать (Sphinx Search Mod) и ранжировать результаты поиска (Sphinx Ranker Mod), в документации сфинкса полностью расписано какие они бывают и на что влияют.
При поиске очень общего слова может быть очень много результатов и огромная пагинация, в большинстве случаев это не надо и можно ограничить максимальное кол-во результатов поиска (Sphinx Max Matches)
indexer --all --rotate
Все.
Надо периодически запускать индексирование базы:
indexer --all --rotate
При создании индекса sphinx делает индекс текущего состояния базы и если после индексирования в базе были какие-либо изменения, то sphinx не найдет новых данных, тк они были добавлены после индексирования.
Логический вывод из этого: надо проводить реиндексацию после каждого изменения в базе, однако проблема в том, что если база достаточно большая то индексация может занимать длительное время. И индексация это очень затратный по ресурсам процесс.
Что бы решить эту проблему придумали delta index – это индекс в который попадут измения, которые произошли с момента полной индексации и до момента создания дельта индекса. При этом, поскольку индексируется малое кол-во данных, операция проходит очень быстро.
При поиска sphinx будет искать и в основном индексе и в дельта индексе, и таким образом будет видеть все измения. Создание дельта индекса можно поставить как угодно часто.
Итого :
в основную часть, которая у вас уже есть надо добавить после
sql_query_pre = SET NAMES utf8
строку
sql_query_pre = UPDATE rot_settings SET value = (SELECT MAX(gallery_id) FROM rot_gallery_info) WHERE name = 'sphinx_max_gallery_id'
Теперь надо добавить создание дельта индекса
source delta : your_name_source { sql_query_pre = SET NAMES utf8 sql_query = SELECT gi.gallery_id, UNIX_TIMESTAMP(gi.activation_date) as date, alt, description, gi.duration, sponsor_id, gs.total_ctr, gi.content_type, \ (SELECT group_concat(tag_name) FROM rot_gal2tag g2t \ LEFT JOIN rot_tags as t on t.tag_id = g2t.tag_id \ WHERE g2t.gallery_id = gi.gallery_id) as tags, \ (SELECT group_concat(tag_id) FROM rot_gal2tag g2t \ WHERE g2t.gallery_id = gi.gallery_id) as tag_ids, \ (SELECT group_concat(name) FROM rot_groups \ WHERE rot_groups.id in (SELECT group_id FROM rot_gallery_stats1 WHERE rot_gallery_stats1.gallery_id = gi.gallery_id AND group_id != 0) ) as group_names, \ \ (SELECT group_concat(gss.group_id) FROM rot_gallery_stats1 as gss \ WHERE gss.gallery_id = gi.gallery_id AND group_id != 0) as categories \ FROM rot_gallery_info AS gi \ JOIN rot_gallery_data1 AS gd ON gi.gallery_id = gd.gallery_id \ JOIN rot_gallery_stats1 AS gs ON gs.gallery_id = gi.gallery_id \ WHERE gi.gallery_id > ( SELECT value FROM rot_settings WHERE name = 'sphinx_max_gallery_id' ) \ AND gallery_status = 'active' and gallery_type = 0 \ and gs.best_thumb = 'yes' and gs.group_id = 0 } index delta : your_name_index { source = delta path = /your_full_path/data/delta }
Как можно заметить запрос такой же, отличается только наличием в выборке по sphinx_max_gallery_id.
После этого надо доабвить в крон индексацию новых записей так часто, как вам нравится строкой
indexer --rotate delta
После создания индекса надо прописать delta в Sphinx Delta Index настройках ротации.
и раз в сутки например можно присоединять дельта индекс к основному
indexer --rotate --merge your_name_index delta
Все.
Когда пользователь ищет что-то на сайте (domain.com/?search=…) то этот запрос пишется в базу, что б потом можно было вывести лог запросов. Через какое-то время запросов может быть много плюс иногда полезно организовать морфологический поиск среди них. Для чего эти запросы так же можно индексировать сфинксом.
Для этого добавляем в конфиг сфинкса
source search_queries { type = mysql sql_host = YOUR_HOST sql_user = USERNAME sql_pass = PASSWORD sql_db = DB_NAME sql_port = 3306 # optional, default is 3306 sql_query_pre = SET NAMES utf8 sql_query = SELECT sq_id, search_query, hits, items_found FROM rot_search_queries WHERE hits > 0 GROUP BY search_query sql_attr_uint = hits sql_attr_uint = items_found } index search_queries_index { source = search_queries path = /WHERE_TO_STORE docinfo = extern morphology = stem_en }
и прописываем в сетингах Sphinx Search Log Index. Теперь этот индекс будет использован для выборки например похожих запросов для поиска, например у вас запрос domain.com/?search=…, вы выводите галеры по этому кейворду, а так же можно добавить список похожих поисков <thumb search_log=all filter=GET_search, вот для этой выборки и будет использован сфинкс, что будет быстрее и с использованием морфологии.
При этом так же нельзя забывать про реиндексацию. например, у нас был поиск “вася”, дал 10 реузльтатов и лучшая галера там ИД 123. в базе ИД этой записи например 789 (ИД лучшщей галеры и ИД записи результатов поиска - это разные ИД). Сфинкс возвращает только ИД, в данном случае 789. И вот прошло какое-то время, поискали мы вася и оно вернуло уже другой результат, в базу его записало с ИД 888. А в реиндекса в сфинксе не было. И онвернул старый ид 789, которого уже нет. Или например который сейчас выдает какой-то другой результат, но в любом случае не актуальный.
Sphinx Search Index основной индекс
Sphinx Delta Index - дельта индекс
Sphinx Search Log Index
Sphinx Search Mod for advanced user only, do not change if you are not sure Sphinx Ranker Mod for advanced user only, do not change if you are not sure Sphinx Max Matches for advanced user only, do not change if you are not sure default 20000
По дефолту слейв подхватывает данные сфинкса из базы мастера. те прописав сфинкс на мастере - все слейвы начинают так же юзать сфинкс.
Тут у вас может получиться следующий момент: по дефолту все пишут хост для сфинкса - localhost. Если слейв выносится на другой сервак - то логично что локалхост для него не работает в этом случае. Опять же логично что для этого случая надо прописать не локалхост, а конкретный ИП сервака где находится сфинк. И сразу проверить что коннекты разрешены на этот порт на этом серваке с того сервака, где стоит слейв.
Если вы используете поиск сфинкс то по дефолту он ищет по релевантности (domain/?search=…
Можно так же сортировать результаты поиска по дате (domain/?search=…&order=date) и продолжительности (domain/?search=…&order=duration).
Sphinx обладает большими возможностями по настройке индексирования и поиска. Например, хорошей идее добавить в конфиг эти необязательные строки.
min_word_len = 3 # Минимальная длина индексируемого слова min_infix_len = 2 # Минимальная длина инфикса (префикс в том числе) enable_star = 1 # Использовать оператор усечения "*"
Но конечно лучше всего пройтись по документации sphinx и выбрать параметры для себя.
Об этом написано выше, но стоит повторить. Сфинкс - это не магия, он ищет по своему индексу. Свой индекс у него получается когда он проводит индксацию вашей базы. Если вы изменили базу (добавили галер, удалили и тп), а реиндексацию сфинкса не запустили - сфинкс про это не узнает.
Это значит, что надо периодически проводоить реиндексацию. лучший вариант: смотреть когда у вас минимальная нагрузка и запускать индексацию в это время по крону.
По дефолту для поиска используется конструкция примерно WHERE description LIKE '%search_term%'. В настройках ротации есть пункт
Search fields If you don't use Sphinx the script will use Mysql built-in functionality. It's slower so we limit amount of fields Please, read the last WIKI about the last option.
По дефолту скрипт ищет по в description, в этом пункте можно настроить поиск в Title (Alt), либо по обоим полям сразу, что конечно создает несколько больше нагрузки.
Лучший вариант - это настройка Sphinx о чем рассказано ниже.
Но есть компромисный вариант: FullText Search для Mysql (последний из пунктов опции Search fields). Его смысл в том, что Mysql так же умеет искать учитывая морфологию, однако до версии 5.6 он это делал только для таблиц MyISAM.
Итого если вы хотите использовать этот вариант, который несоклько проще варианта Sphinx в настройке надо для таблиц rot_gallery_data* добавить индекс
ALTER TABLE `rot_gallery_data1` ADD FULLTEXT ( `alt` , `description` )
И переключить в настройках опцию на поиск FullText.