Архитектура платформы больших данных с триллионным трафиком на основе языка Go

Архитектура Kafka Эксплуатация и техническое обслуживание дизайн

党合萱
Данг Хексуан
Он окончил Сидяньский университет со степенью магистра и работал в отделе хранения данных Alibaba Cloud, в основном занимаясь проектированием и разработкой функций, связанных с услугами хранения. Он присоединился к Qiniu Cloud в 2016 году и в основном отвечает за архитектуру и разработку конвейера услуг потоковых вычислений и автономных вычислений. В настоящее время конвейер осуществляет обработку данных компании объемом более 100 миллиардов и более 100 ТБ в день.


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

сцена продукт

Для эксплуатационного и ремонтного персонала при проведении ежедневной плановой онлайн-эксплуатации и обслуживания такие данные, как колебания количества посещений в течение дня, распределение онлайн-ошибок и другие бизнес-показатели в журнале, непрозрачны для эксплуатационного и ремонтного персонала. процесс, то как визуализировать эти вещи или собрать эти данные для унифицированной обработки и анализа, на самом деле является более сложным и труднодостижимым процессом. Это так называемый анализ журнала операций и обслуживания, и это также сценарий, о котором мы упоминали ранее. Детали сценариев наших продуктовых решений будут дополнительно проанализированы ниже. Мы используем Nginx-log в качестве примера для описания нашего продукта Pandora.

Доступ к данным Pandora — конфигурация и работа с логкитом

Первым шагом в любом анализе данных является доступ к данным. Logkit инструмента доступа к данным, разработанный Pandora, может помочь пользователям вводить данные в платформу Pandora; вначале необходимо загрузить, настроить и запустить logkit (рис. 1).

图1
Рисунок 1

Инструмент logkit поддерживает различные источники данных, такие как журнал Nginx, сбор данных kafka и нашу платформу обработки данных. Ниже приведено подробное объяснение рисунка 1. Во-первых, нам нужно посмотреть на формат журнала, включая название формата журнала. На рисунке 1 мы указываем путь и формат хранения журнала. Наконец, войдите в файл конфигурации, настройте информацию, которую необходимо настроить, и укажите путь, где должны храниться данные.Если вам нужно войти в очередь сообщений, вам нужно настроить ключ и запустить его, затем эти данные будут собраны и записаны на нашей платформе.

поиск журнала

图2
фигура 2

На рисунке 2 показан относительно интуитивно понятный визуальный интерфейс, который поддерживает перетаскивание. В левой части страницы вы можете увидеть два содержимого: «Источник данных» и «Поиск журнала». После запуска настроенного набора журналов все данные будут введен в "" источник данных". В правой части страницы отображаются имя, формат и другая информация о каждом поле в источнике данных.

图3
изображение 3

На рисунке 3 показан страница отображения содержимого «Retroval Log». Через «поиск журнала» мы можем четко просмотреть какую-то бизнес-логику. Заполните ваши условия запроса в поле поиска, а затем вы можете выполнить полное текстовое извлечение. Если вы отвечаете Для всех запросов, которые превышают 3-х одновременно, вы также можете четко запросить и отображать их через страницу «Retroval Log». На рисунке 3 показано только состояние полнотекстового поиска. Вы также можете просматривать гистограмму распределения связанных данных на странице функции.

агрегация журналов

图4
Рисунок 4

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

Данные возвращаются на платформу

图5
Рисунок 5

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

Отображение и мониторинг данных в режиме реального времени

图6
Изображение 6

Наша страница мониторинга интуитивно показана на рисунке 6. Службу мониторинга необходимо активировать перед настройкой страницы Grafana. Базовая конфигурация страницы представлена ​​в нашей официальной документации, и пользователи могут загрузить и импортировать ее напрямую.

图7
Рисунок 7

На рис. 7 показано отображение данных после анализа журнала Nginx. Оранжевое поле в верхнем левом углу (посещения равно 0) показывает общее количество посещений, зеленая гистограмма в правом верхнем углу показывает количество запросов и время ответа за прошедший период времени, а круговая диаграмма в правом нижнем углу показана доля связанных посещений пользователей. Стиль и положение этих графиков можно настроить.

Архитектурный дизайн

图8
Рисунок 8

На рис. 8 показана бизнес-архитектура Pandora. Данные можно импортировать в нашу платформу через Portal/Logkit/SDK/API и в очередь сообщений.Данные в очереди сообщений можно повторно вычислять и передавать между вычислительной задачей и очередью сообщений.Конечно, эти данные также можно непосредственно экспортируется. Экспортированные данные могут быть обработаны нижестоящей системой (извлечение журнала/последовательные данные и т. д.) и, наконец, может быть сгенерирован отчет о данных.Выше приведен весь поток данных.

Цели проектирования трубопровода и выбор технологии

Каждая система изначально проектируется с расчетными целями и соответствующими задачами, которые необходимо решить. Давайте сначала поговорим о наших проектных целях. Во-первых, система должна поддерживать быстрый доступ к данным, высокую пропускную способность и малую задержку, во-вторых, как облачная служба, она должна поддерживать одновременный доступ большого числа пользователей и должна поддерживать большое количество очереди сообщений, для обеспечения вычислений в реальном времени Платформа с автономными вычислениями отвечает вычислительным потребностям, в конечном счете, это должна быть визуальная операция для удовлетворения операционных потребностей пользователя. После того, как цель проектирования предложена, нам нужно спланировать выбор.Нам нужно выбрать СХД с высокой пропускной способностью.Конечно, текущая СХД Qiniu, несомненно, является наиболее подходящей для нужд, во-вторых, нам нужна мощная и гибкий механизм обработки больших данных; наконец, разработчики должны гарантировать, что окончательный разработанный продукт может быть быстро итеративно разработан. Исходя из этих требований, мы легко выбрали соответствующую техническую поддержку, используя Kafka для удовлетворения наших потребностей в проектировании очередей массовых сообщений, используя Spark в качестве вычислительного движка, для выбора языка мы выбрали Golang, который имеет глубокое наследие. из этих технологий мы начали строить систему.

图9
Рисунок 9

На рисунке 9 показан общий дизайн архитектуры нашего конвейера, который отвечает за доступ и обработку данных в пандоре. Данные импортируются на уровень доступа к данным через Logkit и другие методы, то есть apiserver. Данные через apiserver будут поступать в очередь сообщений, а затем через операции чтения и записи вычислительного механизма и, наконец, импортироваться в нижестоящую систему (облачное хранилище LogDB/TSDB/HTTP/Qiniu).Сегодня мы сосредоточимся на данные, указанные зеленой стрелкой.В направлении потока будут подробно упомянуты соответствующие ключевые моменты. В потоке потоков данных несколько факторов могут определять эффективность этой системы, такие как стабильность, производительность и т. д. Итак, я объясню весь процесс от пользователя до очереди сообщений, через задачу расчета, а затем обратно в очередь сообщений и, наконец, экспорт данных.

уровень доступа к данным

图10
Рисунок 10

На рис. 10 показан уровень доступа к данным. Данные импортируются через apiserver, а планировщик используется для управления исходными данными некоторых пользовательских очередей сообщений, включая форму, в которой данные записываются в очередь сообщений. Причина, по которой logkit здесь, не в том, что данные будут поступать в logkit через apisever и, наконец, в очередь сообщений, а в том, что он может собирать различные формы данных.Здесь мы используем его для сбора журналов системного аудита и информации мониторинга. Он прост в управлении и настройке.

контейнерный

图11
Рисунок 11

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

Оптимизация записи данных

图12
Рисунок 12

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

рассчитать

图13
Рисунок 13

Как показано на рис. 13, наш расчет реализован на основе Spark, который предоставляет относительно простой SQL, скрывающий от пользователей низкоуровневые детали.

Оптимизация экспорта

图14
Рисунок 14

Данные поступают во всю систему.Будь то для расчета или хранения в системе, если обработанные данные должны играть роль, они должны поступать в нижестоящую систему.Поэтому процесс «экспорта данных» служит связующим звеном между восходящий и нисходящий, связующая роль. Общая схема архитектуры этой системы представлена ​​на рисунке 14. Поскольку в то время служба экспорта не была разделена на мелкие задачи, а один сервер не мог обрабатывать слишком большие пользовательские задачи, это приводило к увеличению задержки в периоды пиковой нагрузки. на этом мы, наконец, запустили новую версию после месяца разработки.

图15
Рисунок 15

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

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

Назначение задачи

图16
Рисунок 16

Рисунок 16 представляет собой диаграмму процесса назначения задач. Предполагая, что начальные задачи (T1-T7) относительно равномерно распределены по трем машинам, а в это время поступают две другие задачи (T8-T9), то нам нужно найти несколько относительно простаивающих машин (S1 или S2) Приоритет этих двух задания к ним. Это всего лишь поправка на относительно сбалансированную ситуацию.

Автонастройка

图17
Рисунок 17

图18
Рисунок 18

Конечно, будут неравномерные ситуации (рис. 17-18), тогда нам нужно сделать некоторые автоматические настройки в это время, например, если пользователь удаляет много своих задач, то S1 и S2 будут относительно простаивать по сравнению с S3 в это время. В это время нам нужно сообщить мастеру через сервер сердцебиение. Это содержимое включает в себя занятие ресурсов и распределение задач. По результатам внесите коррективы в простаивающие машины для поддержания относительного уравновешенное состояние.

Горизонтальное расширение

图19
Рисунок 19

На рис. 19 показана проблема с горизонтальным масштабированием. Все машины в настоящее время находятся в состоянии относительной занятости.В это время, если приходит новая задача (Т13), но первые 12 задач были распределены на эти три машины для обработки, то нет свободной машины для обработки новой задачи.Тогда машина должна быть расширена в это время.

图20
Рисунок 20

Как показано на рисунке 20, когда первые три машины находятся в состоянии «занято», нам нужно добавить сервер 4. После запуска S4 он сообщит мастеру о пульсе, и тогда мастер обнаружит наличие этой задачи. и существование S4, переоцените все распределение и использование ресурсов, назначьте T13 относительно простаивающему S4 и даже назначьте задачи, ожидающие обработки в S1, S2 и S3, на S4.

Изоляция ресурсов

图21
Рисунок 21

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

освоить высокую доступность

图22
Рисунок 22

图23
Рисунок 23

Подводя итог, мы видим, что наша система находится в состоянии «один ко многим» (один мастер на несколько серверов), в таком случае как решить проблему обеспечения высокой доступности сервиса в случае единичного точка отказа. Как показано на рисунках с 22 по 23, это ядро ​​нашей разработки. На рисунке видно, что нижняя часть — это кластер zookeeper. , мастер, который успешно вытесняет, становится главным мастером, а мастер, который не может вытеснить его, будет использоваться в качестве резервного, который будет простаивать в обычное время, но как только S1 потеряет блокировку, мастер2 вытеснит блокировку и возьмет на себя управление. вся задача планирования и некоторые задачи управления кластером, в этом и заключается идея мастерской высокой доступности.

Высокая доступность сервера

图24
Рисунок 24

Сервер отличается высокой доступностью, и мы также придерживаемся аналогичной идеи. Мы рассматриваем мастер как узел высокой доступности.Каждый сервер должен сообщать мастеру пульс.Содержание пульса включает в себя выживание самой машины и выполнение соответствующих задач. Как показано на Рисунке 24, как только мастер обнаружит, что S3 не работает, он передаст обе задачи (T5-T6), выполняемые в это время на S3, и посчитает, что S1 и S2 являются относительно подходящими вариантами. быть переданы на соответствующий сервер, тем самым выполняя цель высокой доступности сервера.

Горизонтальное масштабирование на уровне системы

图25
Рисунок 25

图26
Рисунок 26

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

Оптимизация восходящего и нисходящего протоколов

图27
Рисунок 27

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

конвейерная обработка

图28
Рисунок 28

Что касается обработки конвейера, то первоначальный проект представляет собой последовательную операцию. Служба экспорта извлекает данные из очереди сообщений, делает отправку после обработки и продолжает этот процесс. Операция обработки выполняется очень быстро, но вытягивание и отправка относительно медленный В таком процессе эффективность выполнения на самом деле очень низкая, а поскольку время обработки каждой операции разное, некоторые из них выполняются быстро, а некоторые медленно, что приводит к мониторингу сети на карте мониторинга. график высокий и низкий, что приводит к уменьшению использования. Ввиду этого мы оптимизируем работу конвейера, и результаты операции распараллеливания (рисунок 28) показывают, что результатом этого является то, что и push, и pull более эффективны, чем описанный выше метод.

Golang GC

Вся наша языковая подборка основана на Golang, а это язык с GC.На самом деле ситуаций еще много.В системе 1/10 времени не работает и идет сборка мусора. Поэтому мы внесли некоторые улучшения на уровне кода: во-первых, использование sync.Pool позволяет снизить частоту сборки мусора, во-вторых, повторное использование объектов и максимальное повторное использование объекта, чтобы количество каждый GC будет уменьшен. После этого мы обновили версию Golang, а после обновления до версии 1.8 проверили время, затрачиваемое сборщиком мусора, и обнаружили, что оно увеличилось почти на два порядка. Это оптимизация на уровне кода.

предположение об ограниченных ресурсах

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

достижение

Выше мы упомянули о реализации нашей архитектуры и общей оптимизации.Текущие результаты таковы: мы поддерживаем триллионы точек данных и можем обрабатывать сотни терабайт данных каждый день, а также поддерживать большое количество пользователей. Наша система в настоящее время поддерживает очень низкую задержку и высокую эффективность обработки; поскольку мы реализовали автоматическую работу и обслуживание, затраты на рабочую силу также значительно снижены, и мы ожидаем, что мы сможем писать код, не отвлекаясь на работу и обслуживание; что касается удобства использования , На данный момент достигнуто три девятки (99,9%).