Обновить

Как законы механики и математики помогли нам с балансировкой нагрузки в 300K RPS

Время на прочтение11 мин
Охват и читатели9.6K
Всего голосов 53: ↑53 и ↓0+69
Комментарии37

Комментарии 37

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

С какой-то точки зрения да, сейчас мы смотрим и понимаем – так это же типичная задача теории управления, и конечно совершенно необязательно останавливаться на 19 веке – тут можно и перерегулирование учесть, и обратную связь эффективнее обрабатывать, тут вы совершенно правы.

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

Есть несколько способов, каким можно повысить эффективность. Можно пытаться улучшать управление, а можно, скажем, ускорить воркер, в том числе, сократить разницу в интенсивности обслуживания между "прогретым" и "холодным" воркером (она всегда будет, но её можно отыгрывать – оптимизировать критические секции, алгоритмы, походы в базу и т.п.), тогда и "дропов" будет меньше. В данный момент нам скорее выгоднее заниматься этой частью, но ничто не мешает нам в будущем прикрутить и более оптимальный регулятор, если понадобится.

причём тут 19 век?
ТАУ в принципе универсальная дисциплина для создания замкнутых систем. да и разбора как системы любые работают.
без ТАУ не появилось бы ни одного современного устройства, от драйверов транзисторов до космических аппаратов, не говоря уж о моделях для ai
но тут дело ваше к подходу, сами моменты реализации интересны и познавательны у вас в любом случае.

К сожалению, считается, что ИТ - это молодая и уникальная область. И этот миф культивируется уже который десяток лет, что позволяет иметь постоянный заработок. 99% автоматизируемых задач просто копирует человеческое поведение и решение, чаще всего не инженерное и не оптимальное, а в лоб. Даже ребят с инженерных специальностей и прикладным опытом это быстро расхолаживает.

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

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

Либо второй вариант, нет понимания когда развалится, ибо надо ещё быстрее. Продается гарантия на 5 лет, и затем бизнес терпит убытки, но деньги уже получены и пущены в оборот, скорее всего уже приумножены. Если нет - на ремонтах разорятся, но скорее всего уже все учтено и к некоторым придут с "плановым обслуживанием" после того как будет точно известен дефект.

Есть и третий вариант - строим дом, продаем квартиры, потом банкротим застройщика.

Спасибо!

Приведенный в статье сюжет это буквально то, с чего ТАУ и берёт своё начало – с теории устойчивости). Поинт в том, что для начала нам не нужно погружаться прям в неё достаточно сильно, что-то простое вполне может нас устроить и на этом можно достаточно долго жить.

не соглашусь
теория устойчивости - это чистая механика, более прикладное

тау - это абстракциями выше, часть кибернетики.

извините, но именно такая подмена понятий приводит к тому, что разработкой систем\архитектур (любых) занимаются разработчики (математики в сути), а не системотехники
в итоге изобретается велосипед

Это мне напоминает такой прием из вычислительной математики (а именно в теории решения уравнений газовой динамики), как "искусственная вязкость" - очень малые вязкостные члены вводится в уравнения движения и энергии, которые не содержат членов для учёта вязкости.  Это позволяет погасить осцилляции - нефизические колебания в решении. Фокус был придуман не кем иным, как самим Джоном (Яношем) фон Нейманом.

Можно было изначально обратиться к ТАУ и на управление каждым воркером "повесить" по PID-регулятору. С управляющим выходом также как у вас больше-меньше, или, что было бы продуктивнее, с ШИМ-сигналом. Оценивая скважность можно регулировать нагрузку на воркер более тонко.

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

Интересно, спасибо. Уже в XIX веке знали толк в highload’е (турбин).

Есть несколько вопросов, если позволите.

Fanout обрабатывает очень высокую нагрузку — несколько десятков серверов совместно обслуживают более 300 тысяч RPS.

  • Сколько серверов отведено под воркеры?

  • Сервер серверу рознь: можно уточнить конфигурацию железа, в частности, количество ядер CPU?

  • Как обеспечивается HA при outage уровня датацентра?

Далее. Судя по RPS, можно предположить, что количество активных пользователей не менее миллиона. При таком объёме пользователей возникает вопрос: откуда берётся выраженный дисбаланс, требующий регулярной ребалансировки партиций? Казалось бы, статистически должно обеспечиваться более-менее равномерное распределение нагрузки.

Привет! К сожалению, я не смогу раскрыть детали, касающиеся конфигурации железа. По поводу outage ДЦ – имеется в виду случай, когда “трактор кабель переехал” или когда планово закрыли на ремонт?) Если что, первое случается крайне-крайне редко, мы проводили исследование — конечно, происходит сравнительно жёсткая ребалансировка, однако ручное вмешательство не требуется, алгоритм всё разруливает. Если же ремонт, то у нас теперь есть инструмент закрытия локации по кнопке – жмём её, и партиции плавно переносятся на другие ДЦ, тут никаких проблем не наблюдаем.

Что касается обеспечения равномерности: тут есть несколько факторов. Первое это то, что у нас есть partition map, который нас ограничивает в выборе машин – мы не можем всегда перекладывать нагрузку на самый ненагруженный воркер, увы. Что касается весов партиций, то, казалось бы, по ЗБЧ там они должны приходить на очень большой нагрузке к более-менее одному значению, но нет, такое не наблюдается как раз из-за отдельных больших чатов — тут нам мешает “тяжелый” хвост у распределения веса чатов.

Типичное событие, когда приходится переносить партиции — воркер “моргнул” по сети на какое-то небольшое время, причины могут быть разными, одна из них — контейнер выключили на некоторое время, чтобы поремонтировать сервер, на котором он работал, пока контейнер переносится – воркер недоступен. Или выкатка. Подобные события друг на друга последовательно накладываются, это всё приводит к заметному дизбалансу.

Если что, первое случается крайне редко

Спасибо за интересную ссылку 👍. Там, кстати, упоминается: «Мы регулярно проводим для команды учения с имитацией падения одного дата‑центра и, как правило, продолжаем совершенствовать систему эксплуатации по итогам таких учений.» Видимо, эти учения совсем не зря — у нас недавно в двух дата‑центрах Hetzner возникли серьёзные проблемы: ⚠️ Outage Load balancer: There are network problems at the LB host nodes in FSN1 and HEL1. Status: Investigating

Собственно, в основном меня интересует вопрос HA по отношению к данным. Понятно, что воркер можно "перетащить", а вот как с данными обстоит дело если из строя выходит один ДЦ, как это отрабатывается на "учениях с имитацией падения одного дата‑центра"?

«…тут нам мешает “тяжёлый” хвост у распределения веса чатов.»

Можно ли здесь подробнее показать модель с цифрами? Например, если имеются миллионы пользователей и десятки тысяч RPS на сервер, то как именно этот «тяжёлый хвост» приводит к ситуации, где на один сервер может внезапно приходить не 10 000, а, допустим 50 000 RPS (или сколько нужно чтобы потребовалась ребалансировка?

На вопрос про сохранность данных ответ достаточно простой: мы используем YDB как хранилище данных сообщений в чатах. Мы туда делаем самую обычную транзакцию на запись, в случае неудачи сообщения другим участникам не отправляем. Таким образом поддерживается консистентность. YDB как раз устроена так, чтобы переживать подобного рода проблемы, как они это делают – это уже внутренняя кухня этой команды =). Статей про YDB на Хабре много.

Статистической модели нет, а если бы она была, то я точно не смог бы ей поделиться. На пальцах как-то так: большинство чатов мелкие, но есть заметный хвост, в котором чат может быть достаточно большим, и он открыт у многих людей сразу. Такой чат может порождать большой поток запросов из-за этого, но всё работает моментально, пока стейт этого чата прогрет; если же пытаемся отвечать на холодную (после переезда), то тут могут возникнуть проблемы. Постепенно прогрев подобных чатов оптимизируем.

мы используем YDB как хранилище данных сообщений в чатах.

Понятно, т.е. "несколько десятков серверов" не заняты работой по долгосрочному хранению данных ;)

Благодарю за ответы🤝, было интересно.

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

Статистический парадокс дней рождения говорит как раз о неравномерности нагрузки.

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

Тут же имеется парадокс другого характера - испытаний много, слотов мало и, казалось бы, должен работать ЗБЧ и распределение должно быть ранвомерным.

Интересно было бы взглянуть на более конкретную модельку. Когда и в каком виде появляется неравномерность, в числах.

Не понимаю, почему каждая вторая фирма гордится тем, как они круто переживают (пережевывают?) 300K RPS, 500K RPS, и т.п.? И дальше идёт описание крутых инженерных решений, направленных на решение этой проблемы.
Смотрите, тут какой-то сервис, которым пользуются 3 калеки, и он генерирует 300К запросов в секунду. За один час это 108 млрд запросов.
Может, стоит спросить иначе - как так получилось, что сервис с 3 калеками стал генерировать 300К запросов?

Хм, а яндекс-мессенджером точно пользуются три калеки?
Я думал, при всех прочих там не менее пяти миллионов пользователей будет.

Это такой очень тонкий намек на децентрализованные решения?

То есть, по сути, каждое поколение балансировщика замедляло процесс перемещения партиций. Сначала воркер целиком помечался сбойным и расселялся. Потом с воркера стали снимать партиции по одной. А потом замедлили её скачки по воркерам.

Кстати, а зачем переусложнение с " Если партицию P за последние T минут уже переносили L раз..."? Можно же просто сохранить в мету партиции когда она последний раз перемещалась, и не давать ей скакать чаще раза в час, например. (Хотя лучше привязать длину интервала к её активности.)

Не совсем. В первой версиях даже если воркер давал постоянные "сбои", мы его не расселяли – считали, что раз пингуется, значит, полностью живой (а на что он перманентно перегружен не обращали внимание). Замедлили мы специально только последнюю версию; при этом в случае, если воркер полностью недоступен, то мы обязаны его расселить несмотря ни на что.

Что касается последней доработки, то её реализация это был коммит строчек в десять :). Как вы и говорите – буквально пишем в мету партиции, когда в последние разы её трогали, просто кладём L таймстемпов вместо одного. Это позволяет нам подрегулировать "вязкость" при перемещении. А в остальном всё сделано ровно так, как вы и пишите)

Как у вас считаются количество непрочитанных сообщений по чатом в такой схеме? На каждый чат новый счётчик на каждое сообщение increment ? И когда вы подгружает только последнее сообщение вы вычитаете max user count - max chat msg ? Но тогда в этой схеме не учитываются удаленные сообщение .

Счётчик будет показывать 5 сообщений , вы заходите в чат а по факту 2, т.к. 3 штуки удалены

"state cashe" ? Смысл делать общие схемы на неродном языке?

А как правильно назвать state cache?

"буфер состояний"?

cashe != cache
Глаза ну очень сильно режет.

Это по фрейду просто опечатка

А время пинга к воркеру как то учитывается, или у Вас все воркеры в одном дата центре?

Вы пользовались LLM в разработке версий балансировщика?

Увы, нет)
Но LLM точно умеет давать хорошие советы для подобного рода задач, по крайней мере, подсказать направление, куда смотреть.

Я правильно понял, что партицию нельзя перенести на произвольный воркер? Интересно, почему так.

Привет! Да, всё верно. Проблема в том, что мы вынуждены на воркерах помимо данных о сообщений в чате (собственно, стейтов чатов) ещё и держать метаданные об этих чатах (название чатов, их тип, состав и т.п.), эти данные доезжают на воркеры заранее, чтобы не тратить всегда время на их подзагрузку при первом запросе в чат. Например, могут быть очень большие по числу участников чаты, и идти выгружать их только на запрос очень дорого, клиент просто не дождётся ответа. В целом чатов достаточно много, поэтому мы вынуждены использовать ту схему, что указана в докладе – чтобы не складировать эти данные на каждом из воркеров.

О, понятно. Звучит логично. С другой стороны, я думал, что небыстрый старт воркеров(описанный в статье) как раз и обусловлен подгрузкой этих данных.

Да, всё именно так). У нас есть отдельный механизм доставки "тяжелых" данных для подъёма воркеров, и воркеры подгружают ровно то, что им и нужно согласно partition map.

Отличная статья, спасибо!

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Информация

Сайт
www.ya.ru
Дата регистрации
Дата основания
Численность
свыше 10 000 человек
Местоположение
Россия