Лучшие практики для приложений RTB

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

Управление подключениями

Поддерживайте связи

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

Во-первых, для установления каждого нового соединения требуется дополнительный сетевой обход. Поскольку мы устанавливаем соединения по требованию, первый запрос на соединение имеет более короткий срок действия и с большей вероятностью истечет по времени, чем последующие запросы. Любые дополнительные тайм-ауты увеличивают частоту ошибок, что может привести к ограничению вашей системы назначения ставок.

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

Избегайте закрытия соединений

Начните с настройки поведения соединения. Большинство настроек сервера по умолчанию предназначены для сред с большим количеством клиентов, каждый из которых выполняет небольшое количество запросов. В случае RTB, напротив, небольшой пул машин отправляет запросы от имени большого количества браузеров, условно говоря. В этих условиях имеет смысл повторно использовать соединения как можно больше раз. Мы рекомендуем вам установить:

  • Таймаут простоя до 2,5 минут.
  • Максимальное количество запросов на соединение до максимально возможного значения.
  • Максимальное количество подключений равно максимальному значению, которое может разместить ваша ОЗУ, при этом следите за тем, чтобы количество подключений не приближалось слишком близко к этому значению.

Например, в Apache это повлечет за собой установку KeepAliveTimeout на 150, MaxKeepAliveRequests на ноль и MaxClients на значение, которое зависит от типа сервера.

После настройки поведения вашего соединения вам также следует убедиться, что ваш код системы назначения ставок не закрывает соединения без необходимости. Например, если у вас есть внешний код, который возвращает ответ по умолчанию «нет ставки» в случае внутренних ошибок или тайм-аутов, убедитесь, что код возвращает ответ, не закрывая соединение. Таким образом вы избежите ситуации, когда при перегрузке системы назначения ставок соединения начинают закрываться, а количество тайм-аутов увеличивается, что приводит к ограничению работы системы назначения ставок.

Держите связи сбалансированными

Если Авторизованные покупатели подключаются к серверам вашей системы назначения ставок через прокси-сервер, со временем соединения могут стать несбалансированными, поскольку, зная только IP-адрес прокси-сервера, Авторизованные покупатели не могут определить, какой сервер системы назначения ставок получает каждое вызов. Со временем, когда Авторизованные покупатели устанавливают и закрывают соединения, а серверы участников торгов перезапускаются, количество подключений, сопоставленных каждому, может сильно меняться.

Когда некоторые соединения интенсивно используются, другие открытые соединения могут оставаться в основном бездействующими, поскольку в данный момент они не нужны. По мере изменения трафика Авторизованных покупателей неактивные соединения могут стать активными, а активные соединения могут простаивать. Это может привести к неравномерной загрузке серверов системы назначения ставок, если соединения плохо кластеризованы. Google пытается предотвратить это, закрывая все соединения после 10 000 запросов, чтобы со временем автоматически сбалансировать горячие соединения. Если вы по-прежнему обнаруживаете, что трафик в вашей среде становится несбалансированным, вы можете предпринять следующие шаги:

  1. Выбирайте серверную часть для каждого запроса, а не один раз для каждого соединения, если вы используете внешние прокси.
  2. Укажите максимальное количество запросов на одно соединение, если вы проксируете соединения через аппаратный балансировщик нагрузки или брандмауэр, и сопоставление фиксируется после установки соединений. Обратите внимание, что Google уже указывает верхний предел в 10 000 запросов на одно соединение, поэтому вам нужно будет указать более строгое значение только в том случае, если вы по-прежнему обнаружите, что горячие соединения кластеризуются в вашей среде. Например, в Apache установите для MaxKeepAliveRequests значение 5000.
  3. Настройте серверы участников торгов так, чтобы они отслеживали частоту запросов и закрывали некоторые из своих соединений, если они постоянно обрабатывают слишком много запросов по сравнению с их коллегами.

Грамотно справляйтесь с перегрузкой

В идеале квоты должны быть установлены достаточно высокими, чтобы ваша система назначения ставок могла получать все запросы, которые она может обработать, но не более того. На практике поддержание квот на оптимальном уровне является сложной задачей, и перегрузки действительно случаются по разным причинам: выход из строя серверной части в часы пик, изменение структуры трафика, в результате чего для каждого запроса требуется дополнительная обработка, или значение квоты. просто установлен слишком высоко. Следовательно, стоит подумать о том, как поведет себя ваша система назначения ставок при поступлении слишком большого количества трафика.

Чтобы учесть временные сдвиги трафика (до одной недели) между регионами (особенно между Азией и западом США, а также востоком и западом США), мы рекомендуем зазор 15 % между 7-дневным пиком и количеством QPS для каждого торгового места.

С точки зрения поведения при больших нагрузках участники торгов делятся на три большие категории:

Участник торгов, отвечающий на все вопросы

Несмотря на простоту реализации, этот претендент показывает худшие результаты при перегрузке. Он просто пытается ответить на каждый поступающий запрос ставки, несмотря ни на что, помещая в очередь те, которые не могут быть обслужены немедленно. Сценарий, который в результате получается, часто выглядит примерно так:

  • По мере роста частоты запросов растут и задержки запросов, пока все запросы не начнут истекать по тайм-ауту.
  • Задержки резко растут по мере того, как частота вызовов приближается к пику
  • Вступает в силу регулирование, резко сокращающее количество разрешенных вызовов.
  • Задержки начинают восстанавливаться, что приводит к уменьшению дросселирования.
  • Цикл начинается заново.

График задержки для этого участника торгов напоминает очень крутую пилообразную структуру. Альтернативно, запросы в очереди заставляют сервер начинать подкачку памяти или делать что-то еще, что вызывает долгосрочное замедление, а задержки вообще не восстанавливаются до тех пор, пока не закончатся часы пик, что приводит к снижению частоты вызовов в течение всего пикового периода. В любом случае будет сделано меньше вызовов или на них будет получено меньше ответов, чем если бы квота была просто установлена ​​на более низкое значение.

Участник торгов «ошибка при перегрузке»

Эта система назначения ставок принимает уточнения до определенной ставки, а затем начинает возвращать ошибки для некоторых уточнений. Это можно сделать с помощью внутренних тайм-аутов, отключения очереди соединений (контролируемой ListenBackLog на Apache), реализации режима вероятностного сброса, когда загрузка или задержки становятся слишком высокими, или с помощью какого-либо другого механизма. Если Google обнаружит уровень ошибок выше 15 %, мы начнем регулировать. В отличие от участника торгов, который «отвечает на все», этот участник торгов «сокращает свои потери», что позволяет ему немедленно восстановиться, когда уровень запросов снижается.

График задержки для этого бидера напоминает неглубокую пилообразную структуру при перегрузках, локализованную вокруг максимально приемлемой скорости.

Участник торгов «без ставки при перегрузке»

Этот претендент принимает запросы до определенной частоты, а затем начинает возвращать ответы «без ставок» при любой перегрузке. Как и в случае с системой назначения ставок «ошибка при перегрузке», это можно реализовать несколькими способами. Отличие здесь в том, что никакой сигнал не возвращается в Google, поэтому мы никогда не ограничиваем количество вызовов. Перегрузку поглощают интерфейсные машины, которые пропускают на серверные части только тот трафик, который они могут обработать.

График задержки для этого участника торгов показывает плато, которое (искусственно) прекращает параллельную скорость запросов в часы пик, и соответствующее падение доли ответов, содержащих предложение.

Мы рекомендуем сочетать подход «ошибка при перегрузке» с подходом «отсутствие ставки при перегрузке» следующим образом:

  • Переназначьте внешние интерфейсы и настройте их на ошибку при перегрузке, чтобы максимизировать количество соединений, на которые они могут реагировать в той или иной форме.
  • При возникновении ошибки при перегрузке интерфейсные машины могут использовать стандартный ответ «без предложения», и им вообще не нужно анализировать запрос.
  • Внедрите проверку работоспособности серверных частей, чтобы, если ни у одной из них нет достаточной мощности, они возвращали ответ «без предложения».

Это позволяет поглотить некоторую перегрузку и дает бэкэндам возможность отвечать ровно на столько запросов, сколько они могут обработать. Вы можете думать об этом как о «отсутствии ставок при перегрузке», когда клиентские машины возвращаются к «ошибке при перегрузке», когда количество запросов значительно превышает ожидаемое.

Если у вас есть система назначения ставок «реагировать на все», рассмотрите возможность преобразования ее в систему назначения ставок «ошибка при перегрузке», настроив поведение соединения так, чтобы она фактически не перегружалась. Хотя это приводит к возврату большего количества ошибок, это сокращает время ожидания и предотвращает попадание сервера в состояние, в котором он не может отвечать ни на какие запросы.

Ответить на пинги

Убедитесь, что ваша система назначения ставок может отвечать на пинг-запросы, но не управляет соединением как таковое, что на удивление важно для отладки. Google использует ping-запросы для проверки работоспособности и отладки статуса участника торгов, поведения закрытия соединения, задержки и многого другого. Запросы Ping имеют следующую форму:

Google

id: "\3503cg\3023P\364\230\240\270\020\255\002\231\314\010\362\347\351\246\357("
is_test: true
is_ping: true

OpenRTB JSON

"id": "4YB27BCXimH5g7wB39nd3t"

OpenRTB Протобуф

id: "7xd2P2M7K32d7F7Y50p631"

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

Рассмотрите возможность пиринга

Еще один способ уменьшить задержку или нестабильность сети — использовать пиринг с Google. Пиринг помогает оптимизировать путь трафика к вашей системе назначения ставок. Конечные точки соединения остаются прежними, но меняются промежуточные ссылки. Подробности см. в руководстве по пирингу . Причины, по которым пиринг считается лучшей практикой, можно резюмировать следующим образом:

  • В Интернете транзитные каналы выбираются в первую очередь с помощью «горячей маршрутизации», которая находит ближайший канал за пределами нашей сети, который может доставить пакет к месту назначения, и маршрутизирует пакет через этот канал. Когда трафик проходит через участок магистральной сети, принадлежащий провайдеру, с которым у нас много пиринговых соединений, выбранный канал, скорее всего, будет находиться рядом с местом начала пакета. За пределами этой точки мы не можем контролировать маршрут, по которому пакет следует к участнику торгов, поэтому по пути он может быть перенаправлен в другие автономные системы (сети).

  • Напротив, при наличии соглашения о прямом пиринге пакеты всегда передаются по пиринговому каналу. Независимо от того, откуда исходит пакет, он проходит по ссылкам, которыми владеет или арендует Google, пока не достигнет общей точки пиринга, которая должна находиться недалеко от местоположения участника торгов. Обратный путь начинается с короткого перехода к сети Google и остается в сети Google до конца пути. Проведение большей части пути через инфраструктуру, управляемую Google, гарантирует, что пакет будет идти по маршруту с низкой задержкой и позволит избежать значительной потенциальной изменчивости.

Отправить статический DNS

Мы рекомендуем покупателям всегда отправлять в Google один статический результат DNS и полагаться на Google в обеспечении доставки трафика.

Вот две распространенные практики DNS-серверов участников торгов при попытке балансировки нагрузки или управления доступностью:

  1. DNS-сервер выдает один адрес или подмножество адресов в ответ на запрос, а затем каким-то образом циклически обрабатывает этот ответ.
  2. DNS-сервер всегда отвечает одним и тем же набором адресов, но меняет порядок адресов в ответе.

Первый метод плохо справляется с балансировкой нагрузки, поскольку на нескольких уровнях стека используется много кэширования, и попытки обойти кеширование, скорее всего, также не принесут желаемых результатов, поскольку Google взимает с участника торгов плату за время разрешения DNS.

Второй метод вообще не обеспечивает балансировку нагрузки, поскольку Google случайным образом выбирает IP-адрес из списка ответов DNS, поэтому порядок ответов не имеет значения.

Если участник торгов внесет изменение DNS, Google будет учитывать TTL (время жизни), установленное в его записях DNS, но интервал обновления остается неопределенным.