Практика архитектуры высокой доступности в Билибили
Практика архитектуры высокой доступности в Билибили

В условиях пикового трафика сложно построить высококачественную сервисную архитектуру. Эта статья опубликована и составлена ​​г-ном Мао Цзяном, техническим директором Bilibili, в «Онлайн-салоне сообщества разработчиков облачных технологий Tencent». Google SRE Начиная с методологии и фактического процесса реагирования бизнеса, выполняется систематическое проектирование удобства использования. Это также поможет нам понять общую картину системы и совместную защиту между верхним и нижним потоком.

1. Балансировка нагрузки

Балансировка нагрузки конкретно разделена на два направления: одно — внешняя балансировка нагрузки, а другое — балансировка нагрузки внутри центра обработки данных.

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

Если взять приведенный выше рисунок в качестве примера, пользовательский трафик сначала будет поступать на внешний уровень доступа BFE. BFE первого уровня фактически действует как маршрутизатор. Он выбирает компьютерную комнату как можно ближе к узлу доступа для ускорения. запросы пользователей. Затем он пересылается на нижестоящий уровень обслуживания через шлюз API, которым могут быть какие-то внутренние микросервисы или уровень бизнес-агрегации и т. д., и, наконец, формирует полную структуру трафика.

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

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

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

Таким образом, основными соображениями по балансировке нагрузки в центре обработки данных являются:

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

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

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

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

Первый вопрос заключается в том, что для каждого qps, по сути, каждого запроса, запроса и запроса API, их стоимость различна. Различия между узлами очень велики. Даже если вы сделаете сбалансированное распределение трафика, с точки зрения нагрузки оно все равно будет неравномерным.

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

Основываясь на этом, обратившись к проблемам, вызванным алгоритмом балансировки нагрузки JSQ (обучение наименьшей ротации), мы обнаружили, что нам не хватает глобального представления о сервере, поэтому наша цель должна всесторонне учитывать нагрузку и доступность. Мы обратились к идее «Сила двух вариантов в рандомизированной балансировке нагрузки» и использовали алгоритм выбора-2 для оценки двух случайно выбранных узлов и выбора лучшего узла:

  • Выберите серверную часть: ЦП, клиент: работоспособность, полет, задержку в качестве индикаторов и используйте простое линейное уравнение для оценки;
  • Используйте постоянное значение штрафа (штрафа) для вновь запускаемых узлов и используйте методы зондирования для минимизации объема и прогрева;
  • Узлы с относительно низкими баллами могут избежать попадания в «постоянный черный список» и не смогут восстановиться. Используйте статистическое затухание для постепенного восстановления показателей узла до исходного состояния (то есть значения по умолчанию).

После оптимизации алгоритма балансировки нагрузки мы добились относительно хорошей отдачи.

2. Ограничение тока

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

Когда дело доходит до ограничения тока, мы считаем, что нам следует сосредоточиться на следующих моментах:

  • Одним из них является ограничение количества запросов в секунду, которое приводит к проблемам различной стоимости запросов и сложной настройке статических порогов;
  • Второй — отказаться от API по его приоритету в соответствии с его важностью;
  • Третий — установить ограничения для каждого пользователя. При возникновении глобальной перегрузки очень важно контролировать определенные «аномалии»;
  • В-четвертых, отклонение запроса также влечет за собой расходы;
  • В-пятых, каждая услуга настроена с учетом затрат на эксплуатацию и обслуживание, вызванных ограничением тока.

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

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

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

Мы узнали в Google SRE интересную формулу max(0, (запросы- K*accepts) / (запросы + 1)). С помощью этой формулы мы можем позволить клиенту отправлять запросы напрямую, и как только лимит будет превышен, поток будет перехвачен в зависимости от вероятности.

С точки зрения защиты от перегрузки основная идея состоит в том, чтобы отбросить определенный объем трафика, когда служба перегружена, чтобы обеспечить пиковый трафик, когда система близка к перегрузке, чтобы защитить себя. Распространенные практики включают отбрасывание трафика на основе использования процессора и памяти, использование очередей для управления алгоритмами управляемой задержки: CoDel и т. д.

Проще говоря, когда наш процессор достигает 80%, это можно считать близким к перегрузке в это время. Если пропускная способность в это время достигает 100, а запрос мгновенного значения равен 110, я могу потерять эти 10 потоков. Случай Служба может выполнять самозащиту. Основываясь на этой идее, мы наконец реализовали алгоритм защиты от перегрузки. 

Мы используем скользящее среднее значение CPU (CPU > 800 ) как порог просветления, при срабатывании он переходит в стадию защиты от перегрузки. Алгоритм такой: (MaxPass * AvgRT) < InFlight. Среди них MaxPass и AvgRT — статистические значения скользящего временного окна до срабатывания.

После того, как эффект ограничения тока вступит в силу, дрожание ЦП будет приближаться к критическому значению (800). Если время охлаждения не используется, кратковременное падение ЦП может привести к высвобождению большого количества запросов, а в серьезных случаях - к высвобождению большого количества запросов. процессор будет переполнен. По истечении времени охлаждения повторно определите пороговое значение (ЦП > 800 ), продолжать ли вводить защиту от перегрузки.

3. Попробуйте еще раз

Направление трафика обычно идет от BFE к SLB, а затем через шлюз API к BFF, микросервисам и, наконец, к базе данных. Этот процесс проходит через множество уровней. В нашей повседневной работе, когда запрос возвращает ошибку и некоторые серверные узлы перегружены, что нам делать?

  • Сначала нам нужно ограничить количество повторных попыток и использовать стратегию, основанную на распределении повторных попыток;
  • Во-вторых, нам следует повторять попытку только на уровне сбоя. Если повторная попытка по-прежнему не удалась, нам необходимо согласовать код ошибки глобально, чтобы избежать каскадных повторов;
  • Кроме того, нам нужно использовать циклы рандомизации и экспоненциального увеличения. Здесь вы можете обратиться к экспоненциальному отставанию и джиттеру;
  • Наконец, нам нужно установить показатель частоты повторов для устранения неполадок.

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

4. Тайм-аут

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

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

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

Ключом к контролю тайм-аута в процессе является проверка того, достаточно ли осталось для обработки запроса перед началом каждого этапа (сетевого запроса) запроса. Кроме того, внутри процесса могут быть какие-то логические расчеты. Обычно мы думаем, что это время относительно невелико, поэтому обычно его не контролируем.

Многие платформы RPC теперь реализуют межпроцессный контроль тайм-аута. Почему мы это делаем? Межпроцессное управление тайм-аутом может также относиться к идее управления тайм-аутом в процессе, посредством передачи исходных данных RPC, передачи их в нижестоящую службу, а затем использования квоты для продолжения передачи, в конечном итоге делая восходящие и нисходящие каналы не длиннее, чем одна секунда.

5. Борьба с каскадными сбоями

Объединив четыре упомянутых выше аспекта для борьбы с каскадными сбоями, мы должны учитывать следующие ключевые моменты.

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

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

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

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

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

В-шестых, испытания на экстремальное давление и тренировки по устранению неисправностей. При выполнении стресс-теста он может остановиться при сообщении об ошибке. Я полагаю, что лучше продолжать оказывать давление, даже если сообщается об ошибке, чтобы увидеть, как работает ваша служба? Может ли он предоставлять услуги в ситуации перегрузки? После установки алгоритма защиты от перегрузки продолжайте создавать давление, активно отклонять его, а затем комбинировать его с предохранителями для создания трехмерного защитного эффекта. Частые тренировки по устранению ошибок могут создать руководство по контролю качества, из которого каждый может извлечь уроки. Частые тренировки уменьшат вероятность паники. Когда проблемы действительно возникают в производственной среде, их можно быстро найти.

В-седьмых, рассмотрите возможность расширения, перезапуска и устранения вредного трафика.

Референс, показанный на картинке выше, является классическим дополнением к вышеизложенным стратегиям, а также является метафизикой решения различных сервисных задач.

Публичный аккаунт Tencent Cloud Developer Community отвечает на «Интернет-салон», чтобы получить PPT ниже.ссылка для скачивания~

шесть、Q&A

Вопрос: Какие метрики основаны на балансировке нагрузки?

A:Если мы используем серверную часть,В основном с использованием процессора,Я думаю, что процессор — лучшее представление. С точки зрения клиента,Я использую здоровье,Здоровье относится к успешности соединения. Задержка также является очень важным показателем,Кроме того, мы должны учитывать, что каждый клиент обращается к разным адресам. Сколько запросов было отправлено?

Вопрос: Соединение BFE с SLB осуществляется через общедоступную сеть или выделенную линию?

A:На самом деле здесь есть общедоступная сеть и выделенная линия.。

Вопрос: Если количество клиентов порядка тысяч и пинг-понги происходят каждые 10 секунд, на самом деле это всего лишь несколько сотен запросов в секунду? Будет ли это вызывать довольно высокую нагрузку на процессор?

A:если твойclientЭто тысячи,Но различные сервисы, которые у вас есть, складываютсяclientНа самом деле это очень много, наверное, более 10 000.。 Таким образом, это приведет к довольно высокой нагрузке на процессор, поскольку существует множество различных приложений для проверки работоспособности, а это на самом деле очень большая сумма.

Вопрос: Как учитываются затраты на несколько кластеров?

A:Кластеризация。помещениеприезжать Мультикластеры — это скорее размещение нескольких кластеров в одном компьютерном зале.,Итак, этот кластер из нескольких наборов,Прежде всего, это подтверждает, что ресурсы избыточны и удвоены.。 Это требует определенных затрат, поэтому мы не будем делать такое резервирование для всех сервисов, а только для основных сервисов. По сути, нам нужно потратить немного денег и сделать некоторую избыточность, чтобы максимально повысить нашу доступность, потому что как только ваш базовый сервис выйдет из строя, поверхность его отказа действительно распространится очень широко. 

Вопрос: Не являются ли требования к доставке таймаутов слишком строгими? Если есть проблема с одним узлом, это не сработает?

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

Вопрос: Как сбалансировано качество и емкость узлов пользовательского доступа?

A:Зависит от стратегии планирования。Вообще говоря, вам нужно сначала посмотреть, для чего используется ваш сервис.,Если это тип ориентированный на пользовательский опыт,или функциональный,Я считаю, что качество является приоритетом. Во-вторых,При условии, что компьютерный зал, в который вы перенаправляете, не перегружен.,Доставить приезжать до ближайшего узла возможно,В крайних случаях ваш компьютерный зал может быть перегружен.,В этом случае фактически необходимо пересылать данные в другие центральные компьютерные помещения через узел доступа. 

Профиль преподавателя

Мао Цзянь,Технический директор билибили,Самый ценный профессионал Tencent Cloud (TVP)
Мао Цзянь,Технический директор билибили,Самый ценный профессионал Tencent Cloud (TVP)

Мао Цзянь, технический директор по билибили Tencent Cloud Most Valuable Professional (TVP). Отвечает за отдел платформы данных bilibili и имеет почти десятилетний опыт разработки серверов. Хорошо разбирается в разработке высокопроизводительных серверов с высокой доступностью, знаком с Go, Java, C и другими языками. Участвовал в полном переходе от монолитной архитектуры к микросервисам в Bilibili, включая управление микросервисами, проектирование доступности микросервисов, проектирование согласованности данных микросервисов, промежуточное программное обеспечение микросервисов, мониторинг микросервисов, сбор журналов микросервисов и балансировку нагрузки микросервисов, а также разработку инфраструктуры RPC микросервисов и т. д.

Наиболее влиятельные проекты в индустрии открытого исходного кода: goim https://github.com/Terry-Mao/goim Служба рассылки распределенных мгновенных сообщений с длинным соединением; распределенное хранилище небольших файлов bfs https://github.com/Terry-Mao/bfs;

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose