Что такое Sphinx
•
•
•
•
•
•
Сервер текстового поиска, http://sphinxsearch.com
Нет, не как Google/Yandex/Bing
Да, как Solr/Elastic/FAST/Verity/Autonomy/Yserver
Открытые исходники, бесплатный, GPL
300M+ запросов/сутки, 50+ TB коллекции
Кроме “просто поиска” умеет кучу всего
Про что доклад
•
•
•
•
•
Sphinx 2.1 == начали в 2012, выкатили в 2013
Sphinx 2.2 == начали в 2013, выкатим в 2013
~50 новых фич в 2.1
~40 новых фич в 2.2
Но фича, это может быть много…
Галопом по вершкам
• Линейка 2.1.x
• Встроенный адаптивный HA/LB
• Качество поиска
• Сигналы ранжирования, RU морфология, wordbreaker
• Начальная поддержка JSON
• Инструментирование (профайлинг на стероидах)
• Оптимизации!
• Бета в марте, релиз в октябре
Галопом по вершкам
• Линейка 2.2.x
• Манипуляции индексами, ALTER, ATTACH
• Качество поиска
• Сигналы + UDF v2, EN/DE/CN морфология, local_df
• Полная поддержка JSON
• Cпецфункции, GROUP <N> BY, табличные функции
• Оптимизации!
• Бета в октябре, релиз... принимаю ставки!
1. Про встроенный HA/LB
• Виды кластеров?
•
•
•
•
1 шард, N реплик
=> HAProxy
M шардов, 1 реплика
=> HAProxy (+бэкапы!)
M шардов, N реплик
=> HAProxy
M шардов, N реплик, выбросы/гетерогено => HA/LB
• Читать про agent_mirror, ha_strategy, и т.д.
• Говорят, подробнее в следующем докладе
2. Про качество поиска
• Качество поиска это НЕ ранжирование
• Токенизация, морфология, обработка при индексации
• Анализ и переписывание запросов при поиске
• Кворум, коррекция транслита/опечаток, расширения, и т.д.
• 1 поиск => 1…3+ запроса к серверу
• Ассессорские оценки качества
• Формула ранжирования
• Shameless plug: звоните, проконсультируем!!!
2. Про качество поиска: морфология
• stem_ar
• lemmatize_ru, _en, _de
• stem(BUSY) == BUSI, stem(BUSINESS) == BUSI
• lemma(BUSY) == BUSY, lemma(BUSINESS) == BUSINESS
• lemmatize_ru_all, _en_all, _de_all
• lemma(LEFT) == [LEAVE, LEFT]
• “He left us. Make a left turn.”
• “Поручик, это у вас что?!”
2. Про качество поиска: обработка
• $ echo lordofthering expertsexchange.com
| bin/wordbreaker --dict dict.txt split
lord of the rings
experts exchange
• regexp_filter
• wordforms = postmorph.txt:
~run > walk
# maps all of run, runs, running
2. Про качество поиска: ранжирование
• PACKEDFACTORS()
=> много циииферок!
+ данные ассессорских оценок (еще циииферки!)
=> машинное обучение
=> модель в UDF, sphinx_get_XXX_factors()
=> вложенные SELECT для переранжирования
= элитный поиск!!!
• NDCG boost = ?
3. Про JSON: что можно?
•
•
•
•
•
SELECT j.key1, BIGINT(j.abc.def*3+*x+456+)…
... WHERE j.key1=123
… ORDER BY j.key1*3+ ASC, … GROUP BY j.key1*3+
INSERT INTO rt (id, j) VALUES (123, '{x:[3,7,40]}')
SELECT id, ANY(t=3 FOR t IN j.x) FROM rt
• ALL(), ANY(), INDEXOF()
• UPDATE rt SET j.scalar=123 WHERE id=456
3. Про JSON: что (пока) нельзя?
• 2.1 поддерживает только { toplevel: ”value” }
• Нужно пользоваться 2.2
• Лимит в 4 GB JSON и строк на индекс
• Нужно шардить
• UPDATE не может добавлять, удалять ключи
• UPDATE не может менять тип, длину значений
• Нужно пользоваться REPLACE
3. Про JSON: скорость
• Алярм! По умолчанию значение это строка!!!
• 0.566 sec, SELECT * FROM lj ORDER BY j.c
• 0.038 sec, SELECT id, INTEGER(j.c) cc, title FROM lj
ORDER BY cc ASC
• 0.032 sec, SELECT id, c, title FROM lj ORDER BY c ASC
• Разница от 18% до 18 раз
• Знаешь тип => помоги движку!
4. Про более динамические индексы
• ALTER TABLE diskindex ADD COLUMN moo INTEGER
• ALTER TABLE rtindex ADD COLUMN moo INTEGER
• Пока нету ALTER TABLE rtindex DROP COLUMN moo
• ATTACH INDEX megabatch TO RTINDEX myrtindex
• myrtindex теперь может быть НЕ пустым!
• OPTIMIZE INDEX myrtindex
5. Про три спец-функции
•
•
•
•
Номер 1, механизм табличных функций
Можно полностью поменять result set
Пока только одна и встроенная, REMOVE_REPEATS
Планирую добавить UDF интерфейс
• Или сразу уже пора скрипты?!
• Голосуем, лес рук!!!!
5. Про три спец-функции
•
•
•
•
Номер 2, сделали GROUP <N> BY
Сделали группировку по нескольким ключам
Сделали поддержку HAVING
GROUP <N> BY aaa, bbb, ccc
WITHIN GROUP ORDER BY ddd ASC, eee DESC
HAVING fff
• И все это вроде как работает!!!
5. Про три спец-функции
mysql> SELECT id, channel_id FROM lj GROUP 2 BY channel_id
LIMIT 4;
+------+------------+
| id
| channel_id |
+------+------------+
|
1 |
1107024 |
|
2 |
1107024 |
|
5 |
1107004 |
|
6 |
1107004 |
+------+------------+
6. Про инструментирование
• Профилирование, трассировка, счетчики, логи…
•
•
•
•
•
SET profiling=1
SHOW PROFILE
SHOW PLAN
SHOW INDEX myindex STATUS
iostats, cpustats, predict_counters in SHOW META
6. Про инструментирование
mysql> SELECT * FROM test
WHERE MATCH('@title abc* @body hey') G
SHOW PLAN G
...
Variable: transformed_tree
Value: AND(
OR(fields=(title), KEYWORD(abcx, querypos=1,
expanded), KEYWORD(abcm, querypos=1, expanded)),
AND(fields=(body), KEYWORD(hey, querypos=2)))
6. Про инструментирование
mysql> SHOW INDEX lj STATUS;
+-------------------+-----------+
| Variable_name
| Value
|
+-------------------+-----------+
| index_type
| disk
|
| indexed_documents | 99984
|
| indexed_bytes
| 129481542 |
| ram_bytes
| 11945925 |
| disk_bytes
| 89392682 |
+-------------------+-----------+
5 rows in set (0.00 sec)
6. Про инструментирование
mysql> select * from lj where match('the who')
OPTION max_predicted_time=1000000; # also --iostats --cpustats
SHOW META;
...
+-------------------------+--------+
| fetched_docs
| 75190 |
| Variable_name
| Value |
| fetched_hits
| 262942 |
+-------------------------+--------+
| fetched_skips
| 148
|
| total
| 1000
|
| keyword[0]
| the
|
| total_found
| 16207 |
| docs[0]
| 58128 |
| time
| 0.013 |
| hits[0]
| 460421 |
| prediction_fetched_docs | 75190 |
| keyword[1]
| who
|
| prediction_fetched_hits | 262942 |
| docs[1]
| 17175 |
| prediction_skips
| 148
|
| hits[1]
| 32456 |
| predicted_time
| 18
|
+-------------------------+--------+
| dist_predicted_time
| 0
|
17 rows in set (0.00 sec)
7. Про оптимизации
• Вкрации ™ стало быстрее!!!
• Местами В РАЗЫ
• Скиплисты, GEODIST, мегасхемы, JSON,
токенизация, индексация XML, биграммы,
сниппеты…
7. Про оптимизации: что включить
• Скиплисты, [редкое частое], [the who]
• В среднем 1.7x раза (*) на тестовой коллекции LJ1M
• В пределе до 100x раз (*) на синтетических (?) тестах
• Как включить? Либо просто ребилд, либо --buildskips
• Биграммы, *“редкое любое”+, *“back to school”+
• => либо “back+to to+school” либо “back to+school”
• Как включить? bigram_freq_words, bigram_index
7. Про оптимизации: что автоматом
• Быстрее токенизатор => индексация, сниппеты
• Индексация до 1.25x раз, сниппеты до 1.6x (*) раз
• Быстрее фильтрация => спецслучаи
• Спецкод для WHERE arg=value
• Спецкод для 2, 3 условий через AND
• Быстрее обработка схем в SELECT, UPDATE
• От 1.02x до 3.5x (!) раз на гигантских схемах
7. Про оптимизации: что автоматом
• Быстрее доступ к JSON
• Спецкод для j.key1 случая, ~20%
• Начиная с 2.2 укладываем по порядку, ~20%
• Быстрее и едят СИЛЬНО меньше памяти сниппеты
• 32 MB док, было 970 MB, стало 50 MB
• Ведем работы про внедрение forward index cache
• Быстрее, умнее и точнее (!) GEODIST(a,b,c,d,
{in=deg, out=mi, method=adaptive})
8. А что еще?
•
•
•
•
•
•
•
•
•
•
Поиск по маске, [t?st*]
Двойная буферизация RT (нет задержек INSERT)
POLY2D(), GEOPOLY2D(), CONTAINS()
Многопоточный опрос удаленных нод (агентов)
Поиск в любых списках, SELECT … FROM dist1,dist2,local3 …
Вложенные выборки, SELECT * FROM (SELECT …) ORDER BY …
Строки в UDF функциях, CREATE FUNCTION … RETURNS STRING
Оператор ZONESPAN:xxx, функция ZONESPANLIST()
Агрегатная функция GROUP_CONCAT()
...и еще всякие “мелочи”