Pull to refresh

Comments 53

У вас на графике скорость или объём данных? Немного смущает размерность в тебибайтах. Да и канал в 60 терабит/с за гранью моего понимания

Похоже на объем за день, а не скорость. У них на офф сайте речь идет о 3.5 млрд событий в день, что сделает печки из устройств пользователей, которых всего у них менее 50 млн судя по оф.сайту, а активных существенно меньше

Для сути рассказа это на самом деле роли не играет, важны относительные изменения при раскатке на 100% пользователей. Я взял метрику с двух наших граничных роутеров, слил в одну серию данных и просуммировал по суткам, вот и всё. Кажется комментарий ниже правильный, это весь трафик за 24 часа.

Ага, только суть рассказа она для админов/разработчиков.
А я со своим сетевым бэком в первую очередь зацепился за график =)
И для меня увидеть на графике скорость на 5 порядков отличающуюся от привычных гигабит — новость на 4 порядка круче вашей экономии 70% трафика. Тут собственно тоже возникло бы куча вопросов, где, как, почему, какое оборудование, и вообще как вы умудрились обогнать по трафику в 5 раз крупнейшие точки обмена трафиком.
В любом случае экономия 70% вещь предельно выдающаяся, примите поздравления, но не ставьте размерность в тебибайтах/сутки — она сетевиков до инфакта может довести.

Однако, с одной стороны такое простое решение, но и правда порой до подобного не так просто дойти и потом внедрить. Результат конечно очень впечатляет.

Перестать использовать json и использовать бинарный протокол?

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

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


Второе — переход на схему (когда имена/идентификаторы полей отсутствуют).


А уже третье — сжатие.

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

Первое телодвижение в любой оптимизации — это то, которое даёт максимальный выигрыш на единицу потраченного времени. Может сжатие и не даёт прямо космического выигрыша, но обычно приделывается за пару часов, максимум — пару дней, если ещё потратить время на подбор алгоритма сжатия. А переход на новый протокол, и уж тем более на схему может потребовать очень серьёзных переделок.
amarao, это интересная тема, вам не попадались попытки исследовать и померить разницу?
Дело в том, что при сильно сжимаемом контенте (80% по оценке авторов поста) может оказаться, что бинарная сериализация (без сжатия) может оказаться сравнимой по весу со сжатой JSON-сериализацией.

Интуитивно вы правы, а на практике оказалось, что сжатие — очень точечная и неинвазивная для нашей многолетней кодбазы операция — дало 80% результата ценой даже не 20%, а наверное 2% усилий (тут заплакал Вильфред Парето).

Первое — выделить в отдельный слой, а потом уже хоть бинарный, хоть жатый, хоть XML картинкой в PDF (последнее — шутка, не надо так).

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

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

BSON — формат хранения, а не передачи.

Во-первых это действительно большое изменение, особенно на фоне того, чем в итоге обошлись мы. Во-вторых, и это важнее, бинарный протокол сложно отлаживать. Если это Protobuf — нужно централизованно хранить proto-файлы и подкладывать их прокси-серверу, через который идёт дебаг клиента. А сжатие потом поверх всё равно пришлось бы делать, поскольку выигрыш Protobuf vs JSON в дикой природе составляет всего 10%-30%.

Разница 10-30% — это уже после сжатия, как я понимаю.
Без сжатия Protobuf в разы компактнее

Нет, это до компрессии. Основное преимущество Protobuf — быстрая сериализация/десериализация, а по части размера — в стандартном случае 20%-30%, посмотрите бенчмарки.

Я их и посмотрел прежде чем писать коммент. И зная как оно внутри устроено я честно говоря с трудом представляю как там в принципе можем быть всего 20-30%. Многое конечно зависит от данных, но все же если где-то PB не выигрывает заметно у JSON то происходит что-то странное. Ну там все данные идут в виде длинных строк, например. Тогда overhead у JSON будет не так заметен. Но для сериализации небольших структурированных сообщений да с integer / float данными (а это как раз похоже на ваш кейс) protobuf рулит. Пример бенча на Хабре: habr.com/ru/post/458026

Скорость конечно тоже важный фактор, но там flatbuffers вне конкуренции :)

Возможно, кому-то будет полезно узнать о существовании Envoy Mobile. По сути это Envoy. Такой же, как на backend’е, но линкующийся с мобильным приложением. Поддерживается и Kotlin, и Swift. Он берет на себя всё, что касается коммуникации с сервером, то есть играет ту же роль, что Envoy-sidecar в сервис-мэшах: оконечивание TLS, компрессия и реквестов, и респонсов, и многое другое. Декомпрессия тоже поддерживается. Мы добавили этот функционал осенью. Поддержка brotli есть пока в виде моего пулл-реквеста в основной репо Envoy. Если zstd действительно так хорош, наверно и его есть смысл добавить.

Очень странно, что при фразе «много трафика от клиентов» сразу не внедрили сжатие.

Я написал: потому что это не решало основную возникшую тогда проблему, а только отодвигало ее.

Ну почему это? Если бы внедрили обычный gzip, то и не вернулись бы к ней.

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

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

(«приложение открылось», «приложение запросило ленту контента», «пользователь просмотрел контент», «пользователь поставил смайл (лайк)» и так далее) составляло около 5 млрд в сутки. Сегодня это число приближается к 14 млрд.

Во время брейншторма по поводу одного из таких инцидентов прозвучала идея: раз мы создаём этими событиями такой колоссальный объём трафика

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

Перестали насиловать устройства и каналы пользователей?

Также стало видно, что наши опасения относительно батарейки не оправдались. Наоборот, потратив немного процессорной мощности телефона на сжатие данных, мы экономим намного больше электричества на передаче этих данных в эфир, как на Wi-Fi, так и по сотовой сети.

Просто что-то на грани безумия, отправлять тонны трафика, выжирая батарейку, переживать, что сжатие будет тратить батарейку.
Видимо что-то из серии «а вдруг батарейка сядет раньше, чем мы узнаем, что он в носу чесал и поэтому ленту не крутил».
Еще небось и доступ к камере обязателен, чтобы раз в секунду делать фотку, чтобы «убедиться, что это действительно пользователь смотрит ленту и смайлы ставит, а не бот».
Про Nginx — начали и не закончили, поясните, пожалуйста, распаковкой сейчас занимается отдельный сервис, который стоит за Nginx (стоял, условно, некий элемент «старого» backend) — кто распаковывает, и как «архитектурно» это выглядит.

Декомпрессией занимается сервис агрегации аналитики, который стоит за nginx, выполняющим роль балансировщика нагрузки. Я сначала думал, что nginx умеет сам разжимать тело запроса, но оказалось, что это не так.

То есть раньше он(этот сервис) этих функций не осуществлял, сейчас на него возникла нагрузка по декомпрессии. Насколько возросла? И всё-таки, через nginx-lua были ли попытки реализовать? Интересно очень.

Мы не заметили возросшей нагрузки на сервис, масштабировать кластер не пришлось. Ну то есть рост на проценты, в рамках погрешности измерения. Об этом в том числе я пишу в статье: то, что казалось CPU-интенсивной задачей в 80-е годы прошлого века — практически незаметно на фоне современных вычислительных задач сегодня.

Декомпрессия не так сильно нагружает CPU, как компрессия. Но если интересно как сделать совсем быстро, то можно декомпрессию выгружать на железный ускоритель. На Intel QuickAssist, например, или на что-нибудь из FPGA. Я сделал рабочий proof-of-concept декомпрессии на Envoy и QATzip. Но мне неизвестны случаи, чтобы кто-то действительно пользовался декомпрессией на сервере. Эта статья — первое встреченное мной подтверждение, что кому-то это действительно нужно.

Посмотрите ещё в сторону Keep-Alive, правильная настройка которого может существенно сократить ещё и время запросов.

У нас используется протокол http/2, он сам по себе keep-alive, если можно так выразиться)

На графике круто, но не понял что это реально дало дата-центру или вам.

У дата-центров входящий трафик и так ни о чём. Его в разы меньше, чем исходящего.

Ну сократили вы входящий за счёт сжатия, возросла нагрузка на клиента и на сервер. А могла бы и не возрастать.

Если бы вы исходящий трафик в разы сократили, то да. Но исходящий http и так жмётся почти у всех.

Резонный вопрос. Мы перестали оплачивать traffic spikes и некоторое время можем не думать об увеличении пропускной способности наших каналов.

А сколько у вас полоса и сколько платите? Посмотрите у нас цены на каналы с резервированием очень даже демократические.

Если у вас преимущественно входящий трафик, то может и чуть дешевле уступим.
Спасибо за статью, интересно было читать
Вопрос, этот огромный трафик вообще носит какую-то полезную нагрузку?
Здесь уже не работает закон больших чисел? Показания мониторинга от 1го, 3х, 10ти процентов пользователей не будут являться статистически достоверными и достаточными для диагностики поведения приложения? Нельзя проредить пользователей в 10-100 раз, просто исходя из закона больших чисел?

Мы все свои гипотезы проверяем а/б-экспериментами, и чтобы их результаты были статистически значимыми — нам нужно максимум данных, иначе эксперименты будут длиться месяцами.

А что если собирать данные с подопытных — в полном объеме, а с обычных пользователей — только с каждого энного? Те самые 10%?
Так и эксперименты не пострадают, и с основной версии будет меньше трафика литься.

Своими советами вы им брейншторм совете. Не мешайте людям раздувать щеки и восхищаятся собой.

Всегда удивлялся достижениям в решении проблем которую создали из за не компетентности разработчиков.
Так как доля Android среди нашей аудитории больше, чем iOS, падение составило ещё 45%. Итого, если считать от исходного уровня, мы выиграли суммарно 70% от, напомню, всего входящего трафика в ДЦ.

А будь у вас клиенты еще на одной ОС, смогли бы сложить и выиграть сумарно больше 100% ))

был не прав. Грамотно написано про проценты все

Я еще давно использовал LZ4 он похож, побыстрее и похуже жмет. Я тогда строил интересные графики не только по ratio, но и по соотношению ratio/time для разных алгоритмов. Из-за очень высокой скорости lz4 с ним выходило быстрее передать данные чем без него. То есть он сжимал, передавал и распаковывал быстрее, чем просто передать несжаные данные. Это притом было внутри ДЦ, то есть не было проблем с каналом.

Не зря серверы по умолчанию не принимают сжатые данные от клиента. Теперь ваши сервера уязвимы к DDoS атакам с помощью zip бомб. Или вы до распаковки тела проверяете подпись запроса с помощью url параметров?

Мы проверяем авторизацию.

Вопрос в том делаете ли вы это до или после распаковки?

Sign up to leave a comment.

Articles