Начиная с определенного масштаба, вокруг любого базового поискового движка плюс рядом с ним неизбежно вырастает изрядная куча всяких интересных прослоек и сервисов. Особенно, когда одним лишь поиском по ключевым словам (либо вообще булевым, либо с простеньким ранжированием по формуле) дело ограничиваться перестает. Расскажу, как сегодня выглядит архитектура сервисов “вокруг и около поиска” у нас в Авито (числа и слова для привлечения внимания: 40M+ активных объявлений, тысячи RPS, ML ранжирование, пляски с анализом и доставкой данных, и всё такое).
2. Про что доклад
• НЕ про собственно поисковой движок
• Про всякое вокруг ещё, что – оказывается!! – нужно для боя
• Про живую систему, со своими фокусами и глупостями
• Про довольно нагруженную систему, highload
• Про “архитектуру highload” как бы
• (если выйдет неинтересно, вините организаторов, хихи)
• (если интересно, хвалите тоже их, впрочем)
3. Ты вообще кто! (И архитектура чего?)
• Зовут Андрей, строю движки, включая Sphinx
• Сегодня в Авито, “архитектура вокруг поиска” оттуда
• В сутки, прикидочно (оно постоянно растёт)…
• 40M активных объявлений, 0.4M новых
• 10M уников, 140M (пользовательских) поисков
• 1000M+ запросов собственно к движку (SphinxQL)
• В общем, есть некоторая нагрузка
5. Обязательный вопрос rev.20xx
• Почему не Elastic?
• Почему не Solr?
• Почему не Lucene?
• Почему не Xapian?
• Почему не Postgres?
• Почему не MongoDB?
• Почему не MySQL FULLTEXT?
• Почему не ht://dig?
6. Обязательный вопрос rev.2018
• Почему не Elastic?
• Потому что мы всё ещё умеем хорошо готовить Sphinx и C++
• Плюс исторически
• Например, Elastic не существовал :P
• Например, остальное не очень работало :P
9. Архитектура: на самом деле (упрощенно!)
• Функционально? Зоопарк!
• “index.php” // api-search, api-suggest, api-typos, …
// fts-engine, fts-mlranker // indexer-db, indexer-rt, db, db-replica,
// ml-labels, ml-metrics // photos-classifier, …,
// click-stream, click-aggr, …
• Названия цинично изменены, для понятности
• Технически? Зоопарк!
• golang, python, php, c++, lua, bash // k8s, docker, bare metal
// postgres, vertica, mongodb, tarantool… // catboost, avitonet…
10. Архитектура: на самом деле (упрощенно!)
api-search
api-suggest
click-aggr
ml-XXX
photos-XXX
indexer-rt
ESP (click-stream)
……
indexer-db
11. Движок как бы “не важен”
• Движок == базовая индексация и поиск, ну окей
12. Движок как бы “не важен”
• Движок == базовая индексация и поиск, ну окей
• А ещё есть ML ранжирование
• А ещё есть сборка нескольких результатов (поиска)
• А ещё есть опечатки, suggest, bubbles итп лингвистика
• А ещё есть доставка данных, причем из пачки мест, плюс RT
• А ещё есть некий feedback loop (клики и их анализ)
• А ещё есть поиск по фоткам
• А ещё…
13. Движок таки важен, конечно
• Наверняка же будет падать!!!
• Могут быть нужны спецправки
• Точно нужна всякая интеграция
• Особо когда ML
• Особо когда “свои” текстовые сигналы
• И почему это важно?
14. Движок таки важен, конечно
• Наверняка же будет падать!!!
• Могут быть нужны спецправки
• Точно нужна всякая интеграция
• Особо когда ML
• Особо когда “свои” текстовые сигналы
• Spice must flow
• Фундамент должен крепко стоять – надо уметь готовить
15. Большие архитектурные куски
1. Поиск == и по ключевикам, и без них
2. Индексация == полная, инкременты, апдейты
3. ML ранжирование == оценки, обучение, собственно
вычисление
4. Аналитика == от A/B тестов до онлайн анализа кликов
• “Бонусы” == suggest, typos, bubbles, …
• И кстати: где живет и в чем проявляется “highload”?
16. pt1: поиск L*
• Внезапно, 2 уровня (или даже 2.5), а не 1
• 1 уровень: “index.php” => fts-engine [c++]
• 2 уровня: “index.php” => api-search [go] => fts-engine [c++]
• 2.5 уровня: одновременно и так и эдак
• Скорее легаси, конечно, но так (было) надо!!
• Хочется ровно 2 уровня, конечно, работаем
• Зачем так?!
17. pt1: поиск L2, зачем
• Затем, что 1 “пользовательский” поиск == N “базовых”
• Потому что органика, pushes, premium, итп
• Потому что всякие смешивания выдач
• Затем, что асинхронность ftw (ну и перф ещё)
• Затем, что “настройки” обязательно нужно “свои”
• Затем, что это в т.ч. настройки смешивания выдач
• Затем, что релизы/багфиксы, AB-тесты, унификация web/mobile…
18. pt1: поиск L2, как
• “api-search” == Искало :)
• 2.5K rps, k8s, ~10 реплик
• 10K loc, Golang
• И зачем?
• Оно делает 1..5+ (ага, пять) запросов к fts-engine (это далее L1)
• Оно “сливает” результаты по БЛ для “клиента” (web, мобилки итп)
• Что интересно
• Источники (“драйвера”) отвязаны, теоретически ;) можно менять движки
• Коллеги из напрочь других отделов успешно коммитают, Golang FTW
19. pt1: поиск L1, зачем/как
• “fts-engine” == Sphinx
• 13K rps, bare metal, 20-30 машин
• 150K loc, C++
• И зачем?
• Обеспечивает “базовые” поиски, весь этот ярд
• ML ранжирование, поиск фоток итп сложный счёт, разумеется, строго тут
• Что интересно
• Тормозит (пока!) необязательно ML
20. pt2: индексация, что
• Режим 1, полный ребилд, “indexer-db”
• Режим 2, RT подливка, “indexer-rt”
• Режим 3, “пакетные” апдейты, “indexer-rt”
21. pt2: индексация, сколько
• Режим 1, полный ребилд == 40M за 15 минут, 50K rows/sec
• Режим 2, RT подливка == 0.4M новых за 24 часа, 5 rows/sec?
• Режим 3, “пакетные” апдейты
• Режим 2+3, RT подливка == 20+M за 24 часа, 200+ rows/sec
• Что интересно
• В случае “ядерной войны” очень спасает быстрый ребилд
• Где highload? Вроде бы нет, но есть целевые time budgets => и трюки!!!
22. pt2: индексация, как
• “indexer-db” == полный ребилд, выкатка, мониторинг, и т.п.
• 30-50+ GB total, 30+ MB/sec (***)
• ~6K+ loc, Python/PgSQL/bash/Puppet/…
• Python, генератор конфигов, мелочи для статистики, итп
• PgSQL, процедуры для индексации
• bash, всевозможные скрипты раскладки, проверки, прочих операций
• Puppet, конфигурация кластера
• Что интересно
• Brotli/zstd, uftp, rsync
23. pt2: индексация, как
• “indexer-rt” == RT подливка
• ~1.5K rps, мало, но это пока кратный запас…
• ~2K loc, Golang
• Postgres => pgq => “indexer-rt” => “fts-engine” (Sphinx)
24. pt3: ML ранжирование
• 10K+ запросов, 1M+ оценок, постоянно новые
• 15K loc, Python // Django
• Отдельный чёрный ящик => выдаёт новые модели
• Сложный чёрный ящик => Толока, оценки, метрики, обучение…
• Где highload?
• В обучении “как бы” нету; объемы нового приличные, но не шоковые
• В бою (вычисление модели) зато во весь рост; CatBoost FTW
• Что интересно
• Пробить плато “adhoc формула обойдена” заняло много времени
25. pt4: онлайн-аналитика
• Хотим анализировать и учитывать клики
• Хотим это делать онлайн
• Онлайн == с разумной задержкой, а не RT == немедленно
• RT даже вредно, надо фильтровать, усреднять, итп
• Где highload?
• Кликов при 140M/день поисков и 200+M/день просмотров много
• Обработать их всякими “смежными” системами небыстро, а надо
• Обработать и доставить хочется предельно быстро
• “click-aggr” == делаем спецсервис, бой близко
26. ptX: поиск по фоткам
• Хотим искать по фоткам!
• Оффлайн, считаем 40M+ дескрипторов для объявлений (AvitoNet)
• Онлайн, считаем 1 дескриптор для фотки и степень совпадения
• Где highload?
• Что интересно, не “у нас”, а в соседнем отделе!!!
• У нас: ну ок, лишние десятки GB индекса, фигня
• У нас: ну ок, нехитрая векторная математика, фигня
• У них: самое оно, расчет дескрипторов, тренировка нейросетки
27. ptY: “бонусные” сервисы
• Хотим подправлять опечатки
• Хотим показывать suggest
• Хотим…
• В целом, хотим всячески обрабатывать текстовый запрос
• А их, напоминаю, десятки млн в сутки
• Good: запросы “на обработку” сравнительно легковесные
• Ugly: отдельные сервисы; изготовление и доставка данных…
28. ptZ: а ещё внутренние системы
• Например, админка
• 600M+ объявлений за всё время эвар!!!
• Например, “легаси” код в монолите index.php
• ~25K строк (без учета всяких странных словарей)
29. Выводы!
• Поиск это не только лишь движок
• Даже тупо по строчкам
• Engine ~150K loc C++
• Infra ~35K loc Golang, Python, bash, Postgres, LUA, …
• Php ~25K loc PHP!
30. Выводы!
• Масса необходимых (c некоего масштаба) уровней прослоек
• Масса “трущихся” технологий
• Местами сильная нагрузка (а местами нет)
• Местами непростая обработка и доставка данных (а местами нет)
• Везде требования к надежности
• Почему-то $700K/сутки (по публичным данным FY 2017) немного жалко
• Поиск это не только лишь движок