Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

"Бэк-офис в Avito: миллиард объявлений на 10 серверах" Вячеслав Крюков (Avito)

239 views

Published on

Из доклада вы узнаете, как сделать полную индексацию такого большого объема данных, быстро актуализировать этот индекс и найти нужное объявление.

Published in: Internet
  • Be the first to comment

  • Be the first to like this

"Бэк-офис в Avito: миллиард объявлений на 10 серверах" Вячеслав Крюков (Avito)

  1. 1. Бэк-офис в Avito:Бэк-офис в Avito:Бэк-офис в Avito:Бэк-офис в Avito:Бэк-офис в Avito: миллиард объявлениймиллиард объявлениймиллиард объявлениймиллиард объявлениймиллиард объявлений на 10 серверахна 10 серверахна 10 серверахна 10 серверахна 10 серверах Вячеслав КрюковВячеслав КрюковВячеслав КрюковВячеслав КрюковВячеслав Крюков SphinxSearch Meetup #2 @ AvitoSphinxSearch Meetup #2 @ AvitoSphinxSearch Meetup #2 @ AvitoSphinxSearch Meetup #2 @ AvitoSphinxSearch Meetup #2 @ Avito
  2. 2. Зачем нужен Backoffice? • Модерация объявлений • Управление • пользователями • магазинами • сообщениями • контекстными объявлениями • И много еще зачем • И для всего нужен поиск SphinxSearch Meetup #2 @ Avito
  3. 3. Основное хранилище объявлений • PostgreSQL • Данные нормализованы SphinxSearch Meetup #2 @ Avito
  4. 4. Что мы хотим от поиска в Backoffice? • Обрабатывать много объявленй • Высокую актуальность • Приемлемую скорость выполнения запросов • Унификацию SphinxSearch Meetup #2 @ Avito
  5. 5. Sql источник и дельта индексация - классика жанра • Делим индекс на две части Small и Main • Запоминаем метку времени последней индексации Main • Периодически переиндексируем Small от этой метки • Пока его размер приемлем SphinxSearch Meetup #2 @ Avito
  6. 6. Дельта индексация Переиндексируем Small SphinxSearch Meetup #2 @ Avito Small Main
  7. 7. Дельта индексация Переиндексируем Small SphinxSearch Meetup #2 @ Avito Small Main
  8. 8. Дельта индексация Переиндексируем Small, Small уже совсем и не Small SphinxSearch Meetup #2 @ Avito Small Main
  9. 9. Дельта индексация Переиндексировали Main, Small стал маленьким SphinxSearch Meetup #2 @ Avito Small Main
  10. 10. Дельта индексация Переиндексируем Small SphinxSearch Meetup #2 @ Avito Small Main
  11. 11. Дельта индексация Переиндексируем Small SphinxSearch Meetup #2 @ Avito Small Main
  12. 12. Дельта индексация Переиндексировали Main, Small стал маленьким SphinxSearch Meetup #2 @ Avito Small Main
  13. 13. Дельта индексация - известные проблемы • Small быстро пухнет • И переиндексируется с каждым разом медленнее • Мы вытаскиваем повторно из базы все больше и больше данных • Падает актуальность • И надо переиндексировать Main • Возможно, слишком часто, чем хотелось бы SphinxSearch Meetup #2 @ Avito
  14. 14. Дельта индексация: почему часто переиндексировать Main плохо? • Мы вытаскиваем все данные • Мы не запрещаем JOIN в запросах • А даже любим их • Переиндексировать Main это долго • Либо очень сложно SphinxSearch Meetup #2 @ Avito
  15. 15. Дельта индексация - пытаемся оптимизировать • Делим индекс на три части Small, Medium, Main • Храним две метки времени индексации для Medium, Main • И периодически переиндексируем Small от первой метки • А Medium от второй • Пока их размер приемлем SphinxSearch Meetup #2 @ Avito
  16. 16. Дельта индексация Переиндексируем SphinxSearch Meetup #2 @ Avito Small Medium Main
  17. 17. Дельта индексация Переиндексируем Small SphinxSearch Meetup #2 @ Avito Small Medium Main
  18. 18. Дельта индексация Переиндексируем Small...Small... SphinxSearch Meetup #2 @ Avito Small Medium Main
  19. 19. Дельта индексация Переиндексируем Small...Small...Medium SphinxSearch Meetup #2 @ Avito Small Medium Main
  20. 20. Дельта индексация Переиндексируем Small...Small...Medium...Small SphinxSearch Meetup #2 @ Avito Small Medium Main
  21. 21. Дельта индексация Переиндексируем Medium...Small...Small SphinxSearch Meetup #2 @ Avito Small Medium Main
  22. 22. Дельта индексация Переиндексируем Medium...Small...Small...Medium SphinxSearch Meetup #2 @ Avito Small Medium Main
  23. 23. Дельта индексация Переиндексируем Medium...Small...Small SphinxSearch Meetup #2 @ Avito Small Medium Main
  24. 24. Дельта индексация Переиндексируем Medium...Small...Small...Main...Medium...Small SphinxSearch Meetup #2 @ Avito Small Medium Main
  25. 25. Дельта индексация: после оптимизации • Переиндексация Main происходит реже • Но она все равно нужна • Если не раз в сутки • Так раз в неделю • И даже если раз в месяц - это плохо • Хотим это делать в крайнем случае SphinxSearch Meetup #2 @ Avito
  26. 26. Всякая экзотика • Апдейтим атрибуты, а в дельте только изменения текста • RT • может упасть • Мерж индексов • быстро работает • но фейлится в самый неподходящий момент • Предложите свой вариант SphinxSearch Meetup #2 @ Avito
  27. 27. Pipe источник индексации • Необходима собственная реализация извлечения данных • Широкие возможности: можно объеденять данные с различных серверов БД, источников с разными форматами SphinxSearch Meetup #2 @ Avito
  28. 28. TSV pipe • TSV - Tab Separated Values • Работает быстрее XML Pipe • Проще обрабатывается SphinxSearch Meetup #2 @ Avito
  29. 29. TSV pipe + дельта индексация Как это устроено • Выделяем несколько частей-чанков • Small, Medium, Main и т.п. • Как для обычной дельта схемы • Отдельный TSV файл • соответствующий какому-либо чанку • отсортирован по убыванию id объявления SphinxSearch Meetup #2 @ Avito
  30. 30. TSV pipe + дельта индексация Как это устроено • Выделяем самый маленький TSV чанк - Pre • Ставим его перед остальными TSV чанками • В него генерируем данные • по времени от сохраненной метки • маленькими порциями • Сортируем по убыванию id объявления • После генерации сохраняем новую метку SphinxSearch Meetup #2 @ Avito
  31. 31. TSV pipe + дельта индексация Как это устроено • Осуществляем последовательный мерж TSV чанков • Мерж TSV чанков по лэтенси • indexer забирает заданные TSV файлы и строит индексы • Применяем TSV KL для удаленных объявлений • Применяем Sphinx KL для приоритета актуальности младших чанков над старшими • Большие TSV файлы жмем • Гибкие и простые блокировки SphinxSearch Meetup #2 @ Avito
  32. 32. TSV pipe + дельта индексация Профит • Вычитываем данные из БД только один раз • Одна метка • Манипулировать отсортированными TSV файлами просто и быстро • Можем вытаскивать данные не только из БД • А из любого др. хранилища и любом др. формате • indexer быстро обрабатывает TSV файлы • Очень полезно при смене версии Sphinx • И отсутствии обратной совместимости формата индексов SphinxSearch Meetup #2 @ Avito
  33. 33. Мерж TSV чанков по лэтенси Генерим данные в Pre SphinxSearch Meetup #2 @ Avito Pre Small Main
  34. 34. Мерж TSV чанков по лэтенси Сгенерили После генерации Pre сохранили новую мектку SphinxSearch Meetup #2 @ Avito Pre Small Main
  35. 35. Мерж TSV чанков по лэтенси Смержили Pre в Small SphinxSearch Meetup #2 @ Avito Pre Small Main
  36. 36. Мерж TSV чанков по лэтенси Генерим данные в Pre SphinxSearch Meetup #2 @ Avito Pre Small Main
  37. 37. Мерж TSV чанков по лэтенси Сгенерили SphinxSearch Meetup #2 @ Avito Pre Small Main
  38. 38. Мерж TSV чанков по лэтенси Смержили Pre в Small SphinxSearch Meetup #2 @ Avito Pre Small Main
  39. 39. Мерж TSV чанков по лэтенси Генерим данные в Pre SphinxSearch Meetup #2 @ Avito Pre Small Main
  40. 40. Мерж TSV чанков по лэтенси Сгенерили SphinxSearch Meetup #2 @ Avito Pre Small Main
  41. 41. Мерж TSV чанков по лэтенси Смержили Pre в Small SphinxSearch Meetup #2 @ Avito Pre Small Main
  42. 42. Мерж TSV чанков по лэтенси Генерим данные в Pre SphinxSearch Meetup #2 @ Avito Pre Small Main
  43. 43. Мерж TSV чанков по лэтенси Сгенерили SphinxSearch Meetup #2 @ Avito Pre Small Main
  44. 44. Мерж TSV чанков по лэтенси Смержили Pre в Small, мерж занял слишком много времени SphinxSearch Meetup #2 @ Avito Pre Small Main
  45. 45. Мерж TSV чанков по лэтенси Смержили Small в Main SphinxSearch Meetup #2 @ Avito Pre Small Main
  46. 46. Мерж TSV чанков по лэтенси Генерим данные в Pre SphinxSearch Meetup #2 @ Avito Pre Small Main
  47. 47. Мерж TSV чанков по лэтенси Сгенерили SphinxSearch Meetup #2 @ Avito Pre Small Main
  48. 48. Мерж TSV чанков по лэтенси Смержили Pre в Small SphinxSearch Meetup #2 @ Avito Pre Small Main
  49. 49. Мерж TSV чанков по лэтенси Генерим данные в Pre SphinxSearch Meetup #2 @ Avito Pre Small Main
  50. 50. Мерж TSV чанков по лэтенси Сгенерили SphinxSearch Meetup #2 @ Avito Pre Small Main
  51. 51. Мерж TSV чанков по лэтенси Смержили Pre в Small SphinxSearch Meetup #2 @ Avito Pre Small Main
  52. 52. Мерж TSV чанков по лэтенси Генерим данные в Pre SphinxSearch Meetup #2 @ Avito Pre Small Main
  53. 53. Мерж TSV чанков по лэтенси Сгенерили SphinxSearch Meetup #2 @ Avito Pre Small Main
  54. 54. Мерж TSV чанков по лэтенси Смержили Pre в Small SphinxSearch Meetup #2 @ Avito Pre Small Main
  55. 55. Мерж TSV чанков по лэтенси Генерим данные в Pre SphinxSearch Meetup #2 @ Avito Pre Small Main
  56. 56. Мерж TSV чанков по лэтенси Сгенерили SphinxSearch Meetup #2 @ Avito Pre Small Main
  57. 57. Мерж TSV чанков по лэтенси Смержили Pre в Small SphinxSearch Meetup #2 @ Avito Pre Small Main
  58. 58. Мерж TSV чанков по лэтенси Генерим данные в Pre SphinxSearch Meetup #2 @ Avito Pre Small Main
  59. 59. Мерж TSV чанков по лэтенси Сгенерили SphinxSearch Meetup #2 @ Avito Pre Small Main
  60. 60. Мерж TSV чанков по лэтенси Смержили Pre в Small, мерж занял слишком много времени SphinxSearch Meetup #2 @ Avito Pre Small Main
  61. 61. Мерж TSV чанков по лэтенси Смержили Small в Main SphinxSearch Meetup #2 @ Avito Pre Small Main
  62. 62. Блокировки при мерже Pre-Small Генерим Pre и лочим Small, что бы потом с ним смержиться SphinxSearch Meetup #2 @ Avito Pre Small Main
  63. 63. Блокировки при мерже Pre-Small Сгенерли Pre, другая генерация Pre пока невозможна SphinxSearch Meetup #2 @ Avito Pre Small Main
  64. 64. Блокировки при мерже Pre-Small Смержили Pre в Small SphinxSearch Meetup #2 @ Avito Pre Small Main
  65. 65. Блокировки при мерже Pre-Small Разлочили Pre и Small, возможна следующая генерация Pre SphinxSearch Meetup #2 @ Avito Pre Small Main
  66. 66. Блокировки при мерже промежуточных TSV чанков Перед мержем Small в Main SphinxSearch Meetup #2 @ Avito Pre Small Main
  67. 67. Блокировки при мерже промежуточных TSV чанков Лочим Main, перемещаем Small в Small.tmp Залочить Main можно, если в этот момент не был залочен Small SphinxSearch Meetup #2 @ Avito Pre Small.tmp Main
  68. 68. Блокировки при мерже промежуточных TSV чанков Мержим Small.tmp в Main, можем мержить Pre в Small SphinxSearch Meetup #2 @ Avito Pre Small Small.tmp Main
  69. 69. Блокировки при мерже промежуточных TSV чанков Все еще мержим Small.tmp в Main, Small растет SphinxSearch Meetup #2 @ Avito Pre Small Small.tmp Main
  70. 70. Блокировки при мерже промежуточных TSV чанков Получили новый Main, Small растет SphinxSearch Meetup #2 @ Avito Pre Small Main
  71. 71. Перегенерация Main Надо согнать все данные по цепочке TSV чанков в конец перед Main SphinxSearch Meetup #2 @ Avito Pre Small Medium Main
  72. 72. Перегенерация Main Согнали SphinxSearch Meetup #2 @ Avito Pre Small Medium Main
  73. 73. Перегенерация Main Переместили Medium в Medium.tmp, генерируем Main.new SphinxSearch Meetup #2 @ Avito Pre Small Main Medium.tmp Main.new
  74. 74. Перегенерация Main Генерируем Main.new, растет Small SphinxSearch Meetup #2 @ Avito Pre Small Main Medium.tmp Main.new
  75. 75. Перегенерация Main Генерируем Main.new, растет Small и готов к мержу в Medium SphinxSearch Meetup #2 @ Avito Pre Small Main Medium.tmp Main.new
  76. 76. Перегенерация Main Генерируем Main.new, смержили Small в Medium SphinxSearch Meetup #2 @ Avito Pre Small Medium Main Medium.tmp Main.new
  77. 77. Перегенерация Main Генерируем Main.new, опять растет Small SphinxSearch Meetup #2 @ Avito Pre Small Medium Main Medium.tmp Main.new
  78. 78. Перегенерация Main Генерируем Main.new, опять смержили Small в Medium SphinxSearch Meetup #2 @ Avito Pre Small Medium Main Medium.tmp Main.new
  79. 79. Перегенерация Main Генерируем Main.new, растет Small SphinxSearch Meetup #2 @ Avito Pre Small Medium Main Medium.tmp Main.new
  80. 80. Перегенерация Main Main.new сгенерился, опять смержили Small в Medium SphinxSearch Meetup #2 @ Avito Pre Small Medium Main Medium.tmp Main.new
  81. 81. Перегенерация Main Main.new переместили в Main, Medium.tmp удалили После перегенерации Main сохранили новую мектку SphinxSearch Meetup #2 @ Avito Pre Small Medium Main
  82. 82. Перегенерация Main Особый, тяжелый случай • Останавливаем реплику • Вычитываем через Seq Scan все данные для Main • Нарезаем TSV файлы по нодам • Сохраняем новую метку SphinxSearch Meetup #2 @ Avito
  83. 83. Реализация схемы TSV pipe + дельта индексация • Около 3000 строк PHP • Генератор данных - TSVGeneratorBase • AdmItems • ProItems • AdmAds • ... • Всего 9 генераторов и 70% кода SphinxSearch Meetup #2 @ Avito
  84. 84. Реализация схемы TSV pipe + дельта индексация • Управление вводом/выводом - TSVResource • Обычные TSV файлы • .gz • создание TSV файла c одной строкой SphinxSearch Meetup #2 @ Avito
  85. 85. Реализация схемы TSV pipe + дельта индексация • Мержер файлов - PHPMerger • Мерж предсортированных TSV файлов • Мерж с TSV KL SphinxSearch Meetup #2 @ Avito
  86. 86. Реализация схемы TSV pipe + дельта индексация Выделение TSV чанка в отдельную сущность SphinxSearch Meetup #2 @ Avito TSVChunkFirst TSVChunkMedium TSVChunkMedium TSVChunkLast
  87. 87. Реализация схемы TSV pipe + дельта индексация Выделение TSV чанка в отдельную сущность • Первый чанк - TSVChunkFirst • process • processRange • processFull • generate • reset SphinxSearch Meetup #2 @ Avito
  88. 88. Реализация схемы TSV pipe + дельта индексация Выделение TSV чанка в отдельную сущность • Промежуточный чанк - TSVChunkMedium, последний чанк - TSVChunkLast • process • processFull • merge • move • reset • archive SphinxSearch Meetup #2 @ Avito
  89. 89. Реализация схемы TSV pipe + дельта индексация Выделение TSV чанка в отдельную сущность • TSVManager - cборщик цепочки чанков из экземпляров • TSVChunkFirst • TSVChunkMedium • TSVChunkLast • Запускает обработку цепочки SphinxSearch Meetup #2 @ Avito
  90. 90. Реализация схемы TSV pipe + дельта индексация Конфигурация 'adm_items' => [ 'nodes' => 100, 'path' => '/path/to/tsv', 'chunks' => [ 'pre' => [], 'small' => [], 'medium' => ['latency' => 1000, 'throttle' => 15 * 60], 'main' => ['gzip' => 1, 'latency' => 40000, 'throttle' => 61 * 60], 'archive' => ['gzip' => 1, 'throttle' => 61 * 60, 'schedule' => ['wH' => '002']], // schedule - воскресенье 2 ночи ], ] SphinxSearch Meetup #2 @ Avito
  91. 91. Архитектура поискового кластера Распределение данных • Нужно больше для обеспечения скорости выполнения запроса • Чем для обработки большого числа запросов • Утилизирует многоядреность SphinxSearch Meetup #2 @ Avito
  92. 92. Архитектура поискового кластера Распределение данных • Равномерно распределяем наш миллиард объявлений по 100 нодам • 10 нод на каждом из 10 контейнерах • Можем переиграть число нод, обработав TSV файлы • Намного быстрее, чем вычитать всю базу SphinxSearch Meetup #2 @ Avito
  93. 93. Архитектура поискового кластера Управление конфигурацией • Контейнерная архитектура, LXC • Динамическая конфигурация для indexer и searchd • Конфигурация контейнеров в манфетах puppet SphinxSearch Meetup #2 @ Avito
  94. 94. Архитектура поискового кластера Раздача TSV файлов по контейнерам при индексации SphinxSearch Meetup #2 @ Avito Cron-server, генерация TSV файлов Search-container01 ... Search-container10 Node1 Small1 Medium1 Main1 Archive1 ... Node10 Node91 ... Node100 Small100 Medium100 Main100 Archive100
  95. 95. Архитектура поискового кластера Запуск indexer на контейнерах Search-container01-10 • Каждую минуту по крону • Только для тех индексов, для которых обновились TSV файлы • touch <TSV файл> - индекс будет перестроен заново • indexer срабатывает • Small - мили сек • Medium - сек • Main - десятки сек • Archive - сотни сек SphinxSearch Meetup #2 @ Avito
  96. 96. Примерные объемы данных • Индексы - десятки гб на ноду • TSV файлы - десятки гб на ноду SphinxSearch Meetup #2 @ Avito
  97. 97. Архитектура поискового кластера Объединение контейнеров в кластере SphinxSearch Meetup #2 @ Avito HAproxy on app's Search-pool01...10 Search-container01 ... Search-container10 Node1 ... Node10 Node91 ... Node100
  98. 98. Архитектура поискового кластера Конфигурация индексов, поля и атрибуты, порядок соотв. колонкам в TSV файле #!/usr/bin/env bash INDEX='items' INDEX_CHUNKS="archive.gz main.gz medium.tsv small.tsv" MAX_NODE_ID=100 HAS_KL=1 SOURCE_CONF=" field = title field = description attr_bigint = price attr_uint = user_id attr_uint = category_id attr_uint = location_id ... SphinxSearch Meetup #2 @ Avito
  99. 99. Архитектура поискового кластера Конфигурация индексов, привязка tsv файлам ноды source s_archive_1:s_template { tsvpipe_command = ssh ... -q cron-server cat /path/to/tsv/archive_1.*gz | zcat } index archive_1:template { type = plain source = s_archive_1 path = /home/sphinx/src/archive_1 } SphinxSearch Meetup #2 @ Avito
  100. 100. Архитектура поискового кластера Конфигурация индексов, Sphinx KL source s_kl_main_1:s_kl_template { xmlpipe_command = ssh ... -q cron-server /path/to/kl.sh /path/to/tsv/main_1.*gz } source s_main_1:s_template { tsvpipe_command = ssh ... -q cron-server cat /path/to/tsv/main_1.*gz | zcat } index main_1:template { type = plain source = s_main_1 source = s_kl_main_1 path = /path/to/indexes/main_1 } SphinxSearch Meetup #2 @ Avito
  101. 101. Архитектура поискового кластера Конфигурация индексов, сборка индекса ноды index items_1 { type = distributed local = archive_1 local = main_1 local = medium_1 local = small_1 } SphinxSearch Meetup #2 @ Avito
  102. 102. Архитектура поискового кластера Конфигурация индексов, сборка индекса контейнера index items { type = distributed agent = localhost:9314:items_1 agent = localhost:9314:items_11 agent = localhost:9314:items_21 agent = localhost:9314:items_31 agent = localhost:9314:items_41 agent = localhost:9314:items_51 agent = localhost:9314:items_61 agent = localhost:9314:items_71 agent = localhost:9314:items_81 agent = localhost:9314:items_91 } SphinxSearch Meetup #2 @ Avito
  103. 103. Архитектура поискового кластера Конфигурация индексов, сборка индекса кластера index items { type = distributed agent = search-container01:9314:items agent = search-container02:9314:items agent = search-container03:9314:items agent = search-container04:9314:items agent = search-container05:9314:items agent = search-container06:9314:items agent = search-container07:9314:items agent = search-container08:9314:items agent = search-container09:9314:items agent = search-container10:9314:items } SphinxSearch Meetup #2 @ Avito
  104. 104. Оптимизации и лайфхаки • Обновите версию Sphinx • threads, thread_pool • local, dist_threads, agent, max_children • Ограничение выдачи • Обратный поиск • Универсальные поля • JSON атрибуты • Ranker может многое SphinxSearch Meetup #2 @ Avito
  105. 105. Время генерации/мержа, кол-во items
  106. 106. Отставание Small
  107. 107. Отставание medium
  108. 108. Спасибо, вопросы ?Спасибо, вопросы ?Спасибо, вопросы ?Спасибо, вопросы ?Спасибо, вопросы ?

×