4.2 миллиона запросов за 24 часа. Среднее время ответа: 774 мс. Доля успешных ответов: 99.91%. Та же нагрузка в среднем занимала 2.5 секунды за семь дней до перестройки нашей архитектуры. Это падение среднего времени ответа на 70% на том же оборудовании, для тех же целевых сайтов и с тем же пулом proxy. Мы переписали те части маршрута запроса, которые незаметно отнимали время у наших клиентов.
Это разбор того, что именно изменилось, как реально выглядят цифры и почему Single и Proxy Finder отличаются не просто так.
Сначала о данных. Цифры в этом посте взяты из рабочего трафика, за исключением одного конкретного целевого хоста. Этот хост активно применял rate limit и блокировал запросы всю неделю, что искажает любую метрику. Если включить его, успешность падает примерно до 95%. Но этот разрыв в 5% не является сбоем нашей инфраструктуры. Это один сайт, отвергающий запросы независимо от того, насколько хорош наш алгоритм выбора. Мы исключили его, чтобы вы могли видеть работу системы на лояльных целях.
Что показывают данные
Вот средний показатель за день по нашему рабочему трафику за последнюю неделю:

С 22 по 27 апреля: средние значения от 2318 мс до 3116 мс, трафик от 2.8 до 7.7 млн запросов в день. 25 апреля выделяется показателем 3116 мс на 7.7 млн запросов, что является субботним пиком (объем на выходных заметно выше и тянет среднее значение вверх). 28 апреля: 672 мс на 3.8 млн запросов. 29 апреля (неполный день, до 09:00 UTC): 880 мс на 1.7 млн запросов на данный момент.
Та же архитектура. Те же proxy. Те же целевые сайты. Другой маршрут запроса.
Картина по перцентилям четче среднего. Средние значения могут скрывать длинные хвосты. Перцентили не могут.

На графике сравниваются 24 часа после нашей перестройки с 24 часами до. p50 почти не сдвинулся (и вырос на 4%, что является честными данными, быстрый маршрут уже был в порядке, и новый алгоритм выбора тратит немного больше усилий в начале, чтобы сэкономить много времени в конце). Среднее значение упало на 48% в этом окне. p95 снизился с 8.5 до 3.9 секунд, падение на 54%. p99 снизился с 20 до 7.8 секунд, падение на 61%. Именно здесь возникает боль, и именно это вы реально чувствуете, когда ваш скрапер ждет возврата самых медленных 5% запросов. По сравнению с семью днями до перестроения (когда среднее значение держалось около 2.5 секунд), сегодняшнее среднее значение 774 мс означает падение на 70%.
Доля успешных ответов тоже выросла: с 98.85% до 99.91% за тот же период. В частности для Proxy Finder этот показатель достиг 99.89%. Для Single 99.96%. Это цифра, которой мы гордимся больше всего, поскольку она говорит о том, как часто мы возвращаем полезные данные с первой попытки без необходимости повтора.
Два продукта, два профиля задержки
Мы не сравниваем Single и Proxy Finder друг с другом. Они решают разные задачи и имеют разные бюджеты задержки. Если вы используете один и смотрите на цифры другого, вы смотрите не на то табло.

Single это одноразовый HTTP request через нашу инфраструктуру. Вы даете нам URL и, примерно в 99% реальных рабочих вызовов, id для proxy, который, как вы уже знаете, работает. Мы извлекаем URL через этот proxy, вы получаете response. Никакой логики ротации, никаких каскадов повторных попыток, никакой текучести proxy. Последние 24 часа: p50 равен 100 мс, p95 равен 371 мс, p99 равен 581 мс. Большинство вызовов завершаются менее чем за пятую долю секунды. Даже худший 1% возвращается менее чем за 600 мс.
Proxy Finder это слой обнаружения. Он чередует ваш запрос в пуле публичных proxy, проверяет каждого кандидата, повторяет попытку при сбое и возвращает первый response, который реально сработал, плюс id того proxy, который это сделал. p50 равен 445 мс, p95 равен 5.4 секундам, p99 равен 10.2 секундам. Медленнее, потому что так нужно. Вся суть в том, что IP, с которого ваш скрапер обращается к целевому сайту, является ротируемым, одноразовым и расходным. Вы меняете несколько секунд накладных расходов на устойчивость к черным спискам и rate limit.
Причина, по которой Single такой быстрый, не в магии. Дело в том, что Single доверяет тому, что Proxy Finder должен был обнаружить. Когда вы вызываете Proxy Finder один раз, и он возвращает "этот proxy сработал, вот его id", последующие обращения к той же цели через Single пропускают весь этап обнаружения. Вы идете напрямую к proxy, который уже прошел проверку.
Как команды используют их вместе
Большинство команд, часто обращающихся к цели, следуют двухэтапному шаблону. Первый вызов является исследовательским, остальные целевыми.
Первый вызов идет к Proxy Finder. Он проходит ротацию через пул, проверяет каждого кандидата на соответствие вашим правилам приема и возвращает ответ вместе с id сработавшего proxy. Этот id является вашим маркером для любого будущего вызова, который хочет обратиться к той же цели.
Каждый последующий вызов идет к Single с прикрепленным id для proxy. Никакого обнаружения, никакой валидации, никакого каскада повторов. Мы маршрутизируем ваш запрос через указанный вами proxy и передаем ответ обратно. Это маршрут, который достигает 100 мс на p50.
Если proxy, который работал вчера, сегодня блокируется, вы возвращаетесь к Proxy Finder для одного вызова на повторное обнаружение, а затем возобновляете получение в Single с новым id. Мы не скрываем устаревание. Если переданный вами id для proxy мертв, мы быстро сообщим вам об этом, чтобы вы могли выполнить ротацию.
Разделение 99 к 1 (Single доминирует по объему, Proxy Finder доминирует в обнаружении) это то, почему наши цифры для Single выглядят именно так. Дело не в том, что Single сам по себе более быстрый продукт. Дело в том, что Single это стабильное состояние, а Proxy Finder это этап калибровки. Большинство рабочих нагрузок в основном находятся в стабильном состоянии.
Если ваша задача "получить этот JSON из чистого публичного API, которому все равно, кто его вызывает", пропустите proxy полностью и используйте Single сам по себе. Если ваша задача "попасть на эту защищенную страницу с пула одноразовых IP без получения флага", комбинируйте их. Это не альтернативы. Это этапы одного и того же рабочего процесса.
Что мы изменили
Большинство улучшений получено за счет перестройки трех вещей в маршруте ротации proxy. Ни одна из них не была новой идеей. Это были просто вещи, которые мы откладывали.
Пул перестал доверять плохим данным. До перестроения каталог proxy хранил записи дольше, чем следовало. Некоторые из этих записей больше не были доступны. Выбор одной из них означал, что вы тратили от 15 до 30 секунд на выяснение этого на горьком опыте. Мы перешли к модели, в которой пул отражает то, что реально работает в режиме, близком к реальному времени, а алгоритм выбора предпочитает IP, которые недавно показали успешный результат.
Оценка качества для каждого proxy, а не просто работает или нет. Раньше proxy, который отвечал 5 секунд, выглядел так же, как тот, который отвечал 300 мс, если оба в конечном итоге завершались успешно. Теперь алгоритм выбора отслеживает и задержку. Медленные, но работающие proxy сдвигаются вниз в очереди. Быстрые используются повторно, пока они горячие. Это важнее, чем кажется, потому что длинный хвост распределения задержки это в основном медленные, но работающие proxy, которые старый алгоритм выбора продолжал выбирать.
Оценка качества по целям. proxy, который надежен на одном домене, может быть нестабильным на другом. IP, которые чисто работают с одним сайтом, блокируются или попадают под rate limit на другом. Наш алгоритм выбора теперь отслеживает успешность и задержку для каждого целевого хоста, а не только глобально. Когда вы запрашиваете получение данных с конкретного домена, мы выбираем из proxy, которые недавно реально хорошо работали на этом домене. Глобально хорошие proxy остаются в игре, но proxy с хорошей историей на конкретной цели превосходит proxy с хорошей историей в целом.
Более умная эскалация повторов. Раньше при сбое запроса мы немедленно рассылали параллельные попытки. Это было расточительно, и, что хуже, один плохой proxy мог вызвать каскад последующих попыток, которые все по очереди завершались сбоем. Теперь повторные попытки эскалируются последовательно с короткими задержками между попытками, так что сбой это сбой, а повтор это повтор, а не множитель.
Есть вторая категория изменений, которую стоит назвать, даже если она менее заметна для вас.
Устойчивость к перезапуску. Ранее повторное развертывание любой нашей инфраструктуры запросов означало окно от 5 до 15 минут, когда карта оценки качества proxy должна была перестраиваться с нуля. В течение этого окна алгоритм выбора по сути угадывал. Клиенты видели это как скачок задержки сразу после каждого деплоя. Теперь мы сохраняем эту карту качества между перезапусками. Система запускается прогретой. На сегодняшний день мы можем развертывать изменения инфраструктуры в середине дня, не создавая вам скачков задержки. Тест перезапуска, который мы провели сегодня утром, показал 15-секундный сбой подключения и нулевое время восстановления после него. Это тихое, но значимое изменение в нашем ритме развертывания: нам больше не нужно планировать повторные развертывания с учетом вашего трафика.
Более чистые сигналы сбоя. Когда что-то внутри нашей инфраструктуры идет не так, ваша логика повторных попыток теперь получает правильный HTTP код статуса для принятия мер. Бэкенд, который кратковременно недоступен, возвращает 503. Бэкенд, который вернул некорректный JSON, возвращает 502. Подлинная внутренняя ошибка возвращает 500. Раньше все три выглядели как 500, что означало, что ваша логика повторов не могла отличить "подождите и попробуйте снова" от "это сломано, эскалируйте". Теперь может.
Как это выглядит для вас
Если вы запускаете скраперы с ротацией proxy, практическое изменение заключается в том, что ваши p95 и p99 сокращаются примерно вдвое по сравнению с прошлой неделей. Среднее время запроса снижается. Количество повторных попыток из-за медленных, но в конечном итоге работающих proxy, снижается. Задержка в хвосте, из-за которой задание на 1000 запросов занимает час вместо 20 минут, падает вместе с этим.
Если вы используете Single, вы увидите, что работа алгоритма выбора окупается в основном в хвосте. p99 упал до менее 600 мс, что означает, что даже ваш неудачный 1% запросов теперь возвращается быстро. Single уже был быстрым. Теперь он стабилен.
Честные ограничения
Мы исправили не все. Несколько особенностей, которые все еще применимы:
p99 в Proxy Finder все еще около 10 секунд. Мы сократили его вдвое, но длинный хвост реален. Отчасти это наша вина (глубина пула, шум алгоритма выбора на редких целях). Во многом нет: целевые сайты могут быть медленными сами по себе, могут применять rate limit для определенных маршрутов, могут выдавать страницы с CAPTCHA, которые требуют времени на проверку, или могут просто выдать тайм-аут. Наша инфраструктура может выбрать лучший доступный IP, но она не может ускорить целевой сервер, который решает, отвечать ли. Если ваша работа зависит от того, чтобы каждый запрос возвращался быстрее 5 секунд, установите тайм-аут на каждый запрос, который соответствует вашим допускам, и доверьтесь уровню повторных попыток.
Некоторые цели враждебны, и это отражается на ваших цифрах. Как упоминалось в начале, уровень успеха в 99.91% исключает один хост, который активно блокирует нас на этой неделе. Если включить его, показатель падает примерно до 95%. Этот хост не уникален. Любой агрегатор, работающий с публичными веб-данными, видит это. Цель меняется от недели к неделе. Перестроение алгоритма выбора дает системе гораздо лучшие шансы на маршрутизацию в обход враждебных целей, но она не может переопределить сайт, который решил полностью отказаться от трафика. Наша задача дать вам максимально чистые данные в лояльных случаях и быстро выдать сбой во враждебных.
Сравнение в тот же день содержит шум. В 24-часовом окне, которое мы показываем на графике перцентилей, сравнивается вчерашний день с позавчерашним. Эффекты дня недели, дисперсия целевых сайтов и состав пула меняются между любыми двумя окнами. Мы уверены в направлении (7-дневный график показывает четкую точку перегиба 28 апреля), но если вы проверяете нас на своей собственной рабочей нагрузке, проводите сравнение как минимум в течение недели.
Что дальше
Переписывание алгоритма выбора это основа. Несколько вещей, которые мы поставили в очередь за ним:
Общая карта оценки качества между инстансами, чтобы они учились друг у друга, а не строили независимые карты. Прямо сейчас каждый из них имеет собственную картину того, какие proxy хорошие. Это работает, но это расточительно: каждый инстанс платит ту же цену за обучение параллельно.
Выбор на основе уверенности, когда мы предпочитаем proxy, которые мы реально протестировали в последние несколько минут, тем, о которых мы только догадываемся. Полезно для клиентов с небольшим объемом, чей трафик не поддерживает алгоритм выбора в горячем состоянии самостоятельно.
И на более длинный горизонт: перенос большего количества решений в алгоритм выбора, чтобы оценка качества для цели стала одним из многих сигналов (профиль задержки цели, паттерны времени суток, здоровье сегмента пула). Теперь существует инфраструктура, позволяющая делать это без замедления горячего пути.
Самый дешевый запрос это тот, который нам не пришлось повторять. Перестроение алгоритма выбора это ставка на то, что лучшие данные в момент выбора побеждают большее количество попыток постфактум. Первые 24 часа фактов говорят о том, что это правильная ставка.