Содержание
Система управления метаданными в Авито | Фрол Крючков | AvitoTech
Каждая классификация в какой-то момент своего роста сталкивается с проблемой систематизации, упорядочивания и организации своих метаданных. Почему это так важно? Чтобы ответить на этот вопрос, нам нужно понять несколько основных вещей о метаданных и о том, как они используются.
Скорее всего, вы уже работали с метаданными. Я приведу короткий пример, чтобы вы могли получить представление. Предположим, у вас есть сайт, на котором пользователи могут публиковать информацию о том, что они продают. Чтобы разместить рекламу, продавец заполняет определенные поля, такие как заголовок , категория , цена , местоположение, и т. д. Эти поля, значения списка и типы значений, которые могут заполнять пользователи, являются метаданными. Проще говоря, это данные о данных.
Рисунок 1. Примеры метаданных: название, категория, цена, описание объявления
После того, как продавец подал объявление, ему необходимо оплатить листинг. Эти листинговые сборы обычно основаны на информации в объявлении. Например, цена автомобиля может существенно различаться в зависимости от года выпуска и марки. Или это может быть местоположение, которое больше всего влияет на листинговые сборы. Не очевидно, что скорость и плавность изменения метаданных компании станут узким местом для поиска стратегий монетизации путем проведения A/B-тестов.
Рисунок 2. Использование метаданных в бизнесе
Менее очевидный пример — когда метаданные помогают настроить SEO. Не секрет, что чем больше органического трафика у сайта, тем лучше для бизнеса. Страницы результатов поисковой системы (SERP) и рекламные страницы являются самыми популярными страницами в объявлениях. Рекламные страницы менее интересны, поэтому я опишу случай SERP.
Пользователи могут использовать миллионы комбинаций фильтров. Каждая комбинация фильтров дает уникальную поисковую выдачу. И это плохо для SEO, когда тонны поисковых запросов пользователей разбросаны по тоннам поисковой выдачи, потому что вес каждой страницы мал. Чтобы решить эту проблему, появился канонический URL.
Один уникальный канонический URL группирует относительно похожие страницы и заставляет их считаться одной страницей для поисковых систем. Например, пользовательский поиск по всем автомобилям старше пяти лет попадет в один канонический URL «5-year-old-car», даже если пользователь укажет конкретную марку или цвет. Или критерий поиска: «дом напротив пляжа» с дополнительным фильтром типа коттедж или квартира значения не имеет; это будет «перед пляжем». Это простые примеры, но я думаю, что вы поняли идею. Повторюсь: чем быстрее ваша система позволит вам адаптироваться к меняющемуся миру, тем лучше.
На этом этапе вы можете применить один и тот же шаблон ко всем следующим полям:
- какие данные должен предоставить пользователь;
- какой тип метаданных, отображаемых в рекламе, приводит к лучшему CTR;
- обнаружение мошеннических списков;
- индексация;
- ценовое предложение;
- вы называете это.
Мы обсудили преимущества быстрого изменения метаданных. Но что мешает быстро изменить его?
Из рисунка 2 видно, что метаданные объединяют все домены приложения. Вот почему трудно внести изменения в какую-либо его часть. Даже незначительные изменения типа атрибута могут сломать всю систему. Например, изменение одного атрибута из списка значений в форме подачи объявления может нарушить алгоритмы поисковой индексации и монетизации.
Мы хотели, чтобы разные отделы легко принимали решения относительно своих метаданных без взаимодействия с другими отделами. В то же время отделы должны при необходимости синхронизировать метаданные между разными доменами. Например, когда мы хотим добавить обязательное поле в определенную категорию, не нарушая индексацию поиска или удаляя поля, используемые при расчете платы за листинг. Помня об этом, мы определили функциональные требования к нашей системе управления метаданными или информационной модели, как мы ее называем.
Функциональные требования:
- Решение должно предоставлять нашим инженерам и аналитикам возможность легко вносить изменения в метаданные, такие как добавление, удаление и обновление атрибутов и категорий, а также их типов, значений и параметров.
- Любые изменения в метаданных пространства конкретного отдела не должны влиять на метаданные других отделов. Если это невозможно, мы должны предупредить пользователей. Например, атрибуты для добавления на десктоп, iOS и Android с разными версиями, пространство атрибутов для поисковой индексации, модерации, поисковых фильтров и визуализации на разных платформах.
- Каждый отдел (доменное пространство) должен иметь возможность запускать несколько версий своих метаданных одновременно, т. е. для целей A/B-тестирования.
Нефункциональные требования:
- Система должна легко масштабироваться по горизонтали.
- Он должен эффективно использовать память и быть быстрым во время выполнения.
- Должна быть терпима к несоответствию версий.
- Удобно для работы в сети.
Самый простой способ хранить метаданные — встроить их в схему базы данных и жестко закодировать в кодовой базе. Чтобы показать это, мы приступим к нашему первому примеру. После того, как пользователь отправил рекламу, она будет сохранена в таблице базы данных со следующей схемой:
Рисунок 3. Схема таблицы для хранения рекламы
Не поймите меня неправильно. В данном случае это совершенно прекрасный способ сделать вашу схему, и я почти уверен, что в большинстве случаев он достаточно хорош. Однако в нашем случае нам нужно запустить несколько разных категорий. Каждая категория — это целая вертикаль в нашем бизнесе, и каждая вертикальная команда хочет экспериментировать в своей категории, добавляя, удаляя, изменяя столбцы.
Мы также хотим провести A/B-тестирование, добавив новое поле в определенную категорию, чтобы узнать, понравится ли оно пользователям. Это не будет проблемой, если вам не нужно изменить схему и добавить новое поле, что требует блокировки всей таблицы. Это довольно сложно, если вы запускаете базу данных с миллиардами рекламных объявлений. Даже если вы сегментируете базу данных по категориям, вам все равно потребуется выполнить миграцию, установить значения по умолчанию и т. д. Вторая проблема заключается в том, что для изменения схемы требуется новая фиксация для изменения схемы базы данных и новое развертывание службы для запуска миграции схемы. Это не та беглость, которую мы хотели.
Давайте представим один возможный способ организации схем базы данных, который не потребует от нас выполнения миграций для доставки новых атрибутов:
Рисунок 4. Вообразимое решение для динамических метаданных вокруг атрибутов рекламных объявлений
Ого, пять новых таблиц вместо одной, и еще пара не показаны для простоты. Но не бойтесь. Идея проста: мы превращаем наши столбцы в строки, а остальные — это вспомогательные таблицы для запуска системы. Этот подход называется Модель значения атрибута сущности (EAV) .
Так много новых таблиц в основном потому, что теперь наше приложение отвечает за обеспечение логической схемы. В старом подходе база данных отвечала за обеспечение согласованности данных с помощью внешних ключей. Подход EAV приводит нас к двум проблемам:
- Наше приложение должно отвечать за согласованность данных.
- При такой нормализованной схеме производительность во время выполнения сильно пострадает.
Другой подход заключается в использовании документно-ориентированного способа хранения структуры атрибутов и данных. Мы оспорили этот подход и пришли к выводу, что если бы мы сохраняли свойства и данные в каждом рекламном документе, это стоило бы нам слишком много памяти. И самое главное, работа со старыми документами в кодовой базе обременительна.
Мы не рассматривали графовые базы данных из-за отсутствия опыта в нашей компании.
Основные идеи, использованные при разработке нашей информационной модели, устарели и хорошо зарекомендовали себя — нормализация для согласованности, денормализация для производительности. Мы пошли по этому пути и придумали два глобальных компонента:
- Система управления метаданными с дружественным пользовательским интерфейсом для управления вариациями шаблона EAV.
- Фронтенд для бэкенда — высокопроизводительные микросервисы, выполняющие операции с данными во время выполнения. Они используют сильно денормализованный интерфейс данных для внутренней системы для проверки, подготовки к рендерингу и других целей.
После формирования этих глобальных компонентов возник шаблон EAV: как обеспечить согласованность данных на уровне приложения и ускорить его работу во время выполнения.
Рисунок 5. Основные элементы инфомодели
Ядро системы инфомодели состоит из двух основных элементов. Первый — это каталог категорий, атрибутов, значений и возможных отношений. Второй — макет, абстракция, состоящая из трех других элементов, о которых мы поговорим позже.
Каталог
Каталог представляет собой нормализованное хранилище категорий, атрибутов и значений в третьей нормальной форме. Он отражает архитектуру шаблона EAV, рассмотренную ранее, но только его атрибутивную часть. В каталоге есть список категорий, который является корнем для остальных атрибутов. Это список категорий, в которых работает наш бизнес, таких как аренда автомобилей, продажа автомобилей, продажа недвижимости, аренда недвижимости, краткосрочная аренда недвижимости и другие.
Далее идет каталог атрибутов. Атрибуты являются свойством категории. Например, это может быть марка , модель , год выпуска на аренду автомобиля . Для недвижимости это может быть город , район, или площадь кв. Значения являются всеми возможными значениями атрибутов перечислимого типа. Например, для атрибута марка категории авто возможные значения: audi, bmw или ford .
Также каталог отвечает за все возможные отношения между атрибутами и их значениями:
Рисунок 6. Формат отношений между атрибутами и значениями
Чтобы объяснить, почему нам все же нужно сохранить все возможные отношения, нам нужно перейти ко второму основному компоненту инфомодели — макету .
Макет
Макет представляет собой композицию из трех различных компонентов.
Макет
Макет — это имя для трех манифестов, описывающих поведение, структуру и свойства пространства имен. Компоненты макета решают одну проблему, имеющую две стороны:
- Возможность по-разному представлять одни и те же метаданные в разных пространствах имен.
- Изоляция одного пространства имен от других, чтобы одна команда могла изменять любые свойства поведения, структуры и свойства формы, не затрагивая другие пространства имен.
Отношения отвечают за определенную структуру данных в пространстве имен или макете, как мы называем это внутри. Проще показать на примере с рисунка 7:
Рисунок 7. Пример двух структур отношений одних и тех же метаданных
Как видите, есть две пользовательские истории, в которых мы используем одни и те же метаданные в разных схемах.
Первый случай — подача нового объявления о продаже автомобиля. В этом потоке самым коротким способом для пользователя указать свой автомобиль будет сначала выбрать марку, затем выбрать модель этой марки, затем указать год выпуска автомобиля и так далее. По мере того, как пользователь заполняет поля, становится меньше вариантов для выбора. Мы можем даже заполнить остальные поля автоматически на каком-то шаге, потому что остается только один вариант.
Другой пример: посетитель ищет автомобиль. Они обычно ищут с более широким диапазоном. Таким пользователям проще заполнить марку и модель и выбрать из списка 4–8 поколений, чем подбирать конкретные годы. В таких сценариях в игру вступают отношения. Используя несжатую структуру каталога с картинки 6, мы можем настроить любые отношения компоновки. Эта идея также широко используется при проверке входных данных пользователя.
Форма полей. Следующим элементом макета является форма полей. Этот компонент представляет собой декларативный способ описания полей, отображаемых для пользователя или для внутреннего бэкэнда.
Форма состоит из списка полей, которые связаны с определенными отношениями и атрибутами. Важно то, что здесь объявлены все конфигурации полей. Это означает, что семантически один и тот же атрибут может иметь разные свойства в разных макетах. Например, у нас есть атрибут бренда, и когда пользователь отправляет рекламу, поле выглядит как вход для выбора одной опции. Однако в форме поиска это поле с несколькими вариантами. Форма отвечает за:
- Список полей атрибутов формы.
- Связь между полями и фактическими атрибутами формы и каталогом.
- Свойства полей и самой формы.
Правила. Последний элемент макета — это манифест правила. Это декларативный DSL (предметно-ориентированный язык) для описания поведения полей формы. Этот компонент отвечает за отображение/скрытие, включение/отключение, проверку полей на основе состояния всей формы и даже изменение их свойств и состояний.
Вы можете увидеть результат этого элемента при выборе марки. Он запускает новое состояние формы, когда мы отображаем атрибут модели. Или другой пример, когда в выбранном городе есть метро, мы покажем атрибут со станциями метро. Стоит отметить, что манифесты никто не пишет. Система управления метаданными создает их автоматически в пользовательском интерфейсе.
Управление версиями
Макеты — отличный способ различать разные платформы, домены и отделы. Однако, когда у каждого отдела есть свой набор макетов, они быстро понимают, что хотят запускать несколько версий одного и того же макета одновременно для A/B-тестов или когда мы объединяем старые версии мобильных приложений или внутренних сервисов.
Реализация управления версиями макетов концептуально ничем не отличается от системы контроля версий, такой как Git. Он использует систему ветвления. У нас есть сущности, которые могут меняться: каталоги и макеты (правила, отношения, формы). Мы также знаем, что у нас должна быть возможность запускать столько версий одного и того же макета, сколько у нас есть A/B-тестов.
Это приводит нас к реализации, в которой у вас есть ветки для различных A/B-тестов. Но чтобы использовать конкретную ветку, включая основную ветку, вы должны ее освободить. В момент релиза происходят две основные вещи.
Во-первых, серверная часть объединяет все изменения и выводит их в эффективный формат хранения, к которому можно легко получить доступ во время выполнения. Во-вторых, выпуск тега версии, сгенерированного для того, какая версия макета может быть доступна в производстве. Чтобы поддерживать актуальность метаданных A/B-тестов, вы можете объединить основную ветвь. Слияние основной ветки с A/B-тестированием необходимо, так как вы поддержали все объекты после выпуска версии метаданных, включая те, которые вы даже не трогали. Это происходит потому, что мы решили реализовать стратегию только добавления, которая требует менее сложной реализации.
Маршрутизация
Прежде всего, что такое маршрутизация? Мы уже обсудили множество элементов, таких как версии и макеты. Маршрутизация была придумана для того, чтобы клиент (мобильное приложение, фронтенд-браузер, фронтенд-сервис) мог указать макет и версию для его использования.
Технически маршрутизация — это просто строка, по которой другие службы могут получить доступ к макетам. Он имеет шаблон: {версия}.{имя макета}.{категория}. В реальной жизни это выглядит так: REAL-123. new-adv-mobile.13. Тег версии обычно обозначает задачу Jira, в которой запрашиваются изменения. Однако, если вы хотите отладить макет в промежуточной версии, не выпуская новую версию, вы можете указать dev.real-123 в качестве имени тега. Тогда все спецификации будут генерироваться по запросу. Я не буду обсуждать, как это делается в этой статье, потому что это совсем другая тема.
Рисунок 8. Маршрутизация
Здесь менее очевидное наблюдение: наличие категории в маршруте обеспечивает максимальную степень детализации A/B-тестов. Это сделано специально. У каждого отдела или бизнес-вертикали есть своя «песочница» для проведения экспериментов без дублирования с другими отделами. Однако внутри маршрута все конфликтующие A/B-тесты должны быть соответствующим образом организованы внутри одного отдела.
Одна из основных целей новой системы управления метаданными заключалась в том, чтобы убедиться, что мы можем легко вносить новые изменения, в том числе несовместимые с предыдущими версиями. Это невозможно, если серверная часть обслуживает последнюю версию, потому что это приводит к тому, что мы предоставляем новую версию конечной точки для критических изменений. Огромной архитектуре сложно перейти на следующую версию API. Поэтому мы решили изменить эту парадигму и предоставить клиентам ту версию, которую они хотят.
Поскольку мы рассмотрели все компоненты, пришло время показать всю концепцию. Для этого я воспользуюсь аналогией с призмой. По крайней мере, это работает для меня, и я надеюсь, что это сработает и для вас. Итак, у вас есть золотой источник ваших каталогов метаданных. Также у вас есть макеты, которые представляют собой набор правил, форм и отношений. Идея довольно проста: различные макеты подобны призме, которая фильтрует и изменяет представление и поведение золотого источника каталогов.
Рисунок 9. Макеты как призма для определенных бизнес-доменов
Есть несколько важных вещей, которые макеты делают и не делают:
- Макет не отвечает за внешний вид форм. Он содержит структуру в виде шагов и свойств полей. Но он действует как конфигурация для интерфейса.
- Макет не всегда служит визуальным представлением чего-либо. Макет может быть механизмом проверки, представлением данных для внутреннего использования и т.п. Кроме того, макет может выступать в качестве механизма шаблонов для канонических URL-адресов поисковой выдачи.
- Одновременно можно использовать разные версии одного и того же макета. В основном это происходит с мобильными приложениями, в разных версиях которых используются старые API и A/B-тесты.
На этом этапе мы можем перейти к более техническим деталям:
Рисунок 10. Схема компонентов системы управления метаданными
В системе управления метаданными есть три основных уровня: серверная часть информационной модели, внешняя часть информационной модели. и бытовые услуги.
- Серверная часть отвечает за внесение изменений в метаданные, загрузку каталогов из внешних источников, выпуск новых версий.
- Внешний интерфейс отвечает за доступ в режиме реального времени к макетам, каталогам и атрибутам. Наиболее распространенные варианты использования: проверка формы для веб-сайта или мобильного устройства, сборка представления атрибутов для рекламы, сборка формы для рендеринга для веб-сайта или мобильного устройства.
- Потребительские услуги реализуют бизнес-логику. Это может быть интерфейс, мобильное приложение или внутренний сервис.
Серверная часть EAV для системы управления метаданными более или менее похожа на типичное веб-приложение. Он состоит из реляционной базы данных, одностраничного приложения и нескольких сложных ETL. Здесь вы можете управлять данными каталогов, правил и отношений, создавать макеты, создавать ветки, выпускать новые версии. Однако специфические вещи относятся к нашим внутренним инструментам, например автоматическое тестирование всей системы при внесении изменений в метаданные. Все эти выпуски новой версии информационной модели запускают ряд тестов E2E, чтобы убедиться, что наши пользователи по-прежнему могут добавлять или искать рекламу в каждой категории.
Рисунок 11. Одностраничное приложение бэкенда информационной модели
С технической точки зрения это сложное веб-приложение с большим количеством доменной логики и валидаторов. Они гарантируют, что все макеты, отношения, категории и атрибуты по-прежнему работают после применения изменений метаданных. Например, мы должны проверить, что нет циклических зависимостей, недостижимых состояний и так далее. Многое также происходит с генерацией макетов по запросу для отладки в промежуточной среде.
Реализация управления версиями
Стоит упомянуть, как управление версиями реализовано в базе данных. Мы много изучали управление версиями и решили использовать стратегию добавления журнала. Эта стратегия означает, что всякий раз, когда мы делаем даже малейшее изменение, например, исправляем орфографическую ошибку, нам необходимо выпустить новую версию с дублированием всех сущностей: макета, каталогов и т. д.
Для реализации техники версионирования в базе данных , мы решили скопировать всю схему в Postgres со всеми сущностями для новой версии. Мы не обнаружили никаких недостатков этого подхода, за исключением того, что он замедляет работу пользовательского интерфейса инструментов, которые сканируют все схемы для их отображения и управления ими. Несмотря на то, что ограничений на количество схем почти нет, это не так важно, потому что жизненный цикл схемы для каждой версии не длится очень долго и ограничивается продолжительностью разработки версии и ее тестирования. После того, как новая версия инфомодели готова и протестирована, мы ее выпускаем. Но что означает освобождение?
Что происходит на этапе выпуска
Мы выпускаем новую версию инфомодели, когда уверены, что применили все изменения и готовы запустить ее в производство.
Для запуска новой версии в производство мы запускаем сервисы валидаторов и серию E2E-тестов. Они проверяют выпуск новой версии метаданных, чтобы гарантировать, что она не будет семантически разрушать пользовательский опыт. Следующий шаг — сгенерировать манифесты из текущего состояния базы данных и сбросить их в хранилище статических файлов. Вот и все.
Когда клиенты требуют выпущенную версию макета, службы внешнего интерфейса обращаются к этому хранилищу манифестов и подготавливают их для обработки запросов клиентов. Эти файлы распространяются nginx с разным уровнем кэширования, например, etags. Каждый новый выпуск создает дамп новой версии и никогда не затрагивает старые версии, поскольку мы использовали только добавление версий.
Однако, когда мы хотим протестировать конкретную версию в staging, мы не делаем всех этих шагов. Вместо этого манифесты генерируются по запросу. Манифесты могут быть очень большими, поскольку некоторые из них содержат иерархические зависимости данных и могут ухудшить работу пользователя. Чтобы решить эту проблему, вопросы производительности и памяти в продакшене, мы разделяем такие манифесты на иерархические разделы. Это повышает скорость генератора по требованию и увеличивает количество попаданий в кэш для манифестов в рабочей среде.
Распространение релиза
Формат файлов json, которые сохраняются для чтения и интерпретации внешним интерфейсом, будет обсуждаться в части внешнего интерфейса. На данный момент стоит отметить, что они никогда не удаляются, а также разбиваются на отдельные части в целях оптимизации для внешних служб. Хранилище обеспечивает легкий доступ ко всем версиям инфомодели, которые когда-либо были выпущены, и мы не беспокоимся о том, что кто-то запросит абсолютные или старые версии, они всегда будут доступны. После выполненного релиза мы архивируем схему базы данных этой версии.
Внешние службы — это базы данных только для чтения со встроенным пользовательским интерпретатором для их упрощенного DSL. Существует три службы: служба компоновки, служба механизма правил и служба создания URL-адресов. Однако из-за архитектуры всей системы они имеют много общих деталей реализации и свойств. Давайте сначала посмотрим на диаграмму компонентов для служб внешнего интерфейса:
Рисунок 12. Диаграмма компонентов для служб внешнего интерфейса
Может показаться, что службы действуют как прокси перед хранилищем. Но это не так, потому что файлы метаданных, находящиеся в хранилище, сами по себе не имеют смысла. Во-первых, вы должны «скомпилировать» файлы метаданных, чтобы выполнять к ним запросы. Кроме того, у сервисов нет нагрузки на запись, и они действительно услуги без гражданства . Это свойство дает нам Неограниченное горизонтальное масштабирование ( по крайней мере, пока сети кластеров k8s не лопнут).
Рисунок 13. Диаграмма потока запросов
Диаграмма потока запросов показывает нам, что службы внешнего интерфейса делают внешние исходящие запросы только в том случае, если запрошенный макет отсутствует в кеше. Это единственный случай, когда нам нужны внешние запросы, в противном случае сервис отвечает на запрос из внутреннего кеша в памяти. Исходящие запросы происходят редко. Они происходят при выпуске новой основной ветки инфомодели, запуске новых A/B-тестов или развертывании сервисов. Но сначала мы должны поговорить о кэшировании.
Освобождение кэша
Сколько макетов экземпляр может хранить в памяти одновременно? В реальном мире ответ — это зависит. Наиболее важными причинами являются количество зависимостей между атрибутами, которые превращаются в объемы ОЗУ, занимаемые службой. Самая глубокая категория Авито с большим количеством атрибутов и взаимозависимостей между ними — категория авто. Только посмотрите на количество зависимостей только для производителя автомобилей Acura:
Рисунок 14. Количество узлов и зависимостей между атрибутами
На данный момент ясно, что мы не можем позволить себе хранить все макеты в памяти. Мы не можем этого сделать из-за огромного размера и постоянно меняющегося количества макетов из-за A/B-тестов и пошаговой разработки системы. Мы должны использовать ограничение, которое представляет собой количество макетов, которые мы можем хранить в памяти одновременно:
Рисунок 15. Использование слота кэш-памяти. Зеленая линия — это выпуск новой версии сервиса
. Однако в нашем случае мы не можем просто использовать стратегию LRU или LFU для вытеснения раскладок. Причина в непропорциональном использовании разных макетов. Например, верстка для проверки подачи новой рекламы встречается на пару раз реже, чем верстка показа атрибутов на странице с рекламой:
Чтобы решить эту проблему, мы выбрали кэш ARC. Кэш Arc отслеживает частоту и давность использования определенного макета. Это помогает не вытеснять макеты, которые получают относительно мало запросов в секунду, но также очень важны. Примером такого макета является отправка нового объявления, которое имеет небольшое количество запросов, но очень важно иметь его в кеше из-за важности не пропустить отправку формы пользователем.
Прогрев кеша
Всякий раз, когда мы развертываем группу экземпляров интерфейсных служб в рабочей среде, они запускаются с пустым кешем. Разогрев на реальных запросах пользователей — плохой опыт для наших потребителей, потому что это может закончиться неудачным запросом на отправку нового объявления. Поэтому мы придумали стратегию разогрева.
Каждая служба знает, что находится в ее кеше в памяти. Таким образом, экземпляр выгружает список макетов в памяти в кластер Redis.
Рисунок 17. Процесс прогрева кэша в памяти
Процесс развертывания выглядит следующим образом:
- Мы используем стратегию скользящего обновления, которая позволяет нам распределять нагрузку, когда мы чрезмерно загружаем спецификации макетов.
- Экземпляр переходит к кластерам Redis и получает список используемых в данный момент макетов. После этого он подтверждает собственное успешное развертывание, предоставляя балансировщикам нагрузки k8s проверку работоспособности 200.
- Служба просматривает список и загружает макеты так же, как и при промахах кеша. Если что-то пойдет не так, экземпляр пропускает этот процесс.
- После всего этого служба сообщает k8s, что готова обрабатывать запросы.
Рисунок 18. Прогрев кэша перед получением запросов инстансами
Зеленая пунктирная линия на рисунке показывает, когда новые инстансы получили запросы от балансировщика нагрузки. Пик до этого показывает, сколько времени ушло на прогрев конкретного макета. Запуск примерно 60 экземпляров занимает около четырех минут.
Система управления метаданными является неотъемлемой частью высоконагруженной секретной системы. В нашем случае это помогает проводить A/B-тесты любых изменений метаданных, настраивать SEO и значительно сокращать время выхода на рынок для запуска функций, связанных с метаданными. Нам потребовалось много работы, чтобы создать нашу текущую систему, и мы все еще с нетерпением ждем новых улучшений. Тем более, что эта система вызвала много запросов от внутренних команд, которые активно используют ее ежедневно, есть много работы для улучшения!
AVITO на английском языке Перевод
Avito , non capisci.
Авитус Вы не поняли.
Авито sta cercando di avere un incontro con Teodorico
Авитус едет искать аудиенции у Теодориха и готов.
Игорь Кокорин Trovato на Avito Авто цена интересная в Inghilterra. связаться с продавцом.
Игорь Кокорин Нашел на Авито автомобиль по доступной цене в Англии. связался с продавцом.
Sul avito trovato un annuncio a buon mercato la macchina.
На авито нашел объявление о недорогой машине.
Си, авито .
Да, родовой .
Caduta ===Intanto, il risentimento della popolazione romana contro Avito cresceva.
Недовольство населения Италии против иностранца Авитуса росло.
Trovato на Avito Авто цена интересная в Inghilterra. связаться с продавцом.
Найден на Авито Автомобиль по доступной цене в Англии. связался с продавцом.
Деви Мандаре Авито .
Мне нужно, чтобы вы отправили Авитус .
Mi tolse il padre il mio retaggio avito .
Он лишил меня моего отца, моего родового наследия.
Все вопросы о событиях, которые не связаны с Avito .
Все эти тактики только способствовали росту популярности Обмен .
Nacque in una nobile famiglia, che possedeva il castello avito di Pers in Friuli.
Он происходил из знатной флорентийской семьи, владевшей Линари замком в долине Ламоне.
Immagine: Castel Tirolo, castello avito dei Conti di Tirolo.
Изображение: Замок Тироло, родовая резиденция графов Тироля.
Consolidamento del potere === Il potere di Avito sarebbe dipeso dall’atteggiamento delle Principali Forze in gioco
Консолидация власти === Эффективная власть Avitus зависела от поддержки всех основных игроков на Западе , новый император Авитус и вестготы отправили совместное посольство,
Авито Бачи, figlio di Микеле Бачи и Энрика Риньяни
Авито Бачи, сын Микеле Бачи и Энрика Риньяни.
Il regno di Avito см. Испанию Visigoti,
Во время правления Avitus вестготы расширились до Испании,
Gratis Avito . ma, annunci, comprare e vendere quando vuoi, dove vuoi.
Бесплатно Авито . ма, рубричные объявления, покупайте и продавайте, когда хотите и где хотите.
La narra del barone Освальдо Ламбертенги, продавец в суо кастелло avito по дебету.
Барон Освальдо Ламбертенги вынужден продать свой родовой замок, чтобы расплатиться с долгами.
Nel 457 Ricimero rovesciò un altro imperatore, Avito , innalzando al trono Maggioriano.
В 457 году Рицимер сверг другого императора, Авита , возведя на престол Майориана.
по семпио, су Авито .
например, на авито .
il luogo di nascita di S. Avito , la cui abbazia è un patrimonio mondiale dell’unesco.
место рождения св. Авита , чье аббатство является объектом Всемирного наследия ЮНЕСКО.
Армия публицистической эры Vietato nel Mercato Popolare Avito .
реклама оружия запрещена на популярной торговой площадке Авито .
fu battezzato dal vescovo Avito ди Вена.
он был крещен епископом Авитусом Венским.
In una lettera giunta a noi, Avito di Vienna si congratula con Clodoveo per il suo battesimo,
Сохранившееся письмо от Avitus из Вены, поздравляющее Хлодвига с крещением, делает
Su un colle maestoso emerge Castel Tirolo, il suo battesimo
0 0 ди Тироло Конти делла Валь Веноста.
На величественном холме возвышается Кастель Тироло, родовая резиденция графов Тироля Графов Валь Веноста.
Ricimero convinse il Senato romano a deporre Avito e fece killare a Ravenna, nel Palazzo»in Classis»,
Рицимер приказал римскому сенату свергнуть Avitus и приказал убить «magister militum» Ремиста в Palatium в Classe,
le truppe di Vario Avito proclamarono invece il loro comandante:
войска Varius Avitus объявили его императором,
Avito Bachi, figlio di Michele Bachi e Avito
2
20006 Бачи, сын Микеле Бачи и Энрики Риньяни.