Как Яндекс создал свою шину данных, чтобы передавать сотни гигабайт в секунду
10 лет назад сотни серверов Яндекса работали на Apache Kafka®, но в этом продукте нам нравилось далеко не всё. Наши задачи требовали единой шины для передачи всех видов данных: от биллинговых до журналов приложений. Сегодня объёмы достигли уже десятков тысяч именованных наборов сообщений.
При таком количестве данных в Apache Kafka® становилось сложно управлять правами доступа, организовывать распределённую работу нескольких команд и многое другое. Проблемы роста и отсутствие подходящего решения в открытом доступе привели к тому, что мы разработали своё решение YDB Topics и выложили его в опенсорс в составе платформы данных YDB. В этом посте расскажу о предпосылках создания продукта, нашей архитектуре передачи данных, возникающих задачах и возможностях, которые появились вместе с YDB Topics.
Зачем нам собственная шина
Вот лишь несколько трудностей, которые возникали при использовании Apache Kafka®:
Отсутствие квот. Команде нельзя было выделить маленький кусочек кластера. Были возможны только два решения: большой кластер, что дорого, или общий кластер на несколько команд, что возможностями Kafka не очень поддерживалось. Сами кластеры вели себя не очень стабильно: иногда мы наблюдали потерю некоторых частей передаваемых данных.
Запрет пользователям прямого доступа к общим кластерам. Из‑за этого целой команде сисадминов приходилось разгребать заявки по настройке прав, которые пользователи оставляли в Yandex Tracker.
В первую очередь эти неудобства и подтолкнули нас задуматься о собственной шине передачи данных. К тому моменту платформа YDB позволяла надёжно хранить данные и в ней уже были реализованы такие механизмы, как распределённый консенсус и failover. Так что мы решили воспользоваться готовыми технологиями и просто создать собственную шину на основе YDB — так и появился продукт YDB Topics. Мы надеялись, что если такое решение будет общедоступным, это привлечёт сообщество к совместному развитию экосистемы обработки данных. Поэтому решили выложить его в опенсорс и помочь закрыть потребности крупных компаний и гиперскейлеров. Покажу, для каких задач это может быть актуально.
Архитектура передачи данных в Яндексе
Архитектура передачи данных в Яндексе строится вокруг трёх типовых сценариев:
Передача данных между приложениями, которые размещены в нескольких дата‑центрах (ДЦ). Приложения сами генерируют трафик и сами координируют нагрузку. При этом приложения знают, что дата‑центров несколько, что дата‑центры могут отказывать, и учитывают это в своей работе. При работе наш модуль управления следит за нагрузкой и может попросить клиента перебалансировать поток между различными ДЦ.
Передача биллинговых данных. Такие данные нельзя терять, дублировать или менять их порядок (например, в банковских системах важна последовательность пополнения и списания средств со счетов). Пользователи передают данные биллинга в шину передачи, а мы реплицируем их по трём зонам доступности в рамках единого кросс‑дата‑центрового кластера. Такая система выдерживает одновременное отключение целого дата‑центра и серверной стойки в другом ДЦ и гарантирует высокую доступность чтения и записи данных.
Передача журналов работы приложений и данных в реальном времени. Это почти то же самое, что и передача данных приложений, только гарантии скорости передачи данных в реальном времени ниже.
Сценарий, когда пользователи знают, с каким дата‑центром происходит работа, называется «федерация»: это объединение отдельных дата‑центров. Федерация значительно дешевле кросс‑ДЦ: для хранения используется Erasure‑кодирование, аналогичное кодам Reed — Solomon, а не полная репликация данных. А так как не нужно гарантировать порядок данных при чтении между дата‑центрами, допускаются дубли и ниже доступность для чтения, к чему приложения изначально готовы. При отключении одного дата‑центра трафик распределяется между остальными.
Что такое коды Reed — Solomon? Если у вас четыре блока данных, вы можете добавить к ним два блока контрольной суммы и пережить остановку любых двух узлов этой системы. В отличие от репликации в режиме кросс‑ДЦ, при котором мы хранили три копии данных, в случае Erasure‑кодирования мы храним данные с избыточностью всего с коэффициентом 1,5, и это очень значительно на наших объёмах данных. Такая система гарантирует устойчивость: даже если два из шести узлов откажут, она продолжает работать, и пользователи ничего не замечают. В зависимости от конфигурации мы либо даём полные гарантии exactly‑once с порядком, высокой доступностью и транзакционной обработкой, либо гарантии пониже, которые точно позволят доставлять ваши данные, но могут приводить к редким дублям, плюс иногда немножко снижается доступность для чтения. При этом SLA обеих систем в любом случае будет высоким в рамках их моделей отказов.
Чем здесь полезно решение YDB Topics
Шина данных YDB Topics умеет передавать разнородную информацию с высокой гарантией сохранности. Развернуть её можно где угодно: на кластерах Kubernetes®, виртуальных машинах и в Docker‑контейнере для разработчиков. YDB Topics входит в состав опенсорсной платформы данных YDB — катастрофоустойчивой и масштабируемой на тысячи узлов базы данных.
Вот как выглядит шина данных в цифрах:
Этим огромным потоком данных может управлять всего один дежурный SRE‑специалист. Расскажу чуть подробнее.
Архитектура YDB Topics, Kafka и Pulsar
В сообществе активно используются шины данных Apache Kafka®, Apache Pulsar™, так что стоит верхнеуровнево сравнить их архитектуру и архитектуру YDB Topics.
В Apache Kafka® и Apache Pulsar™ есть модули управления, которые объясняют пользователям, с каким из серверов нужно работать. Зачастую в этой роли используется система типа Apache ZooKeeper™, которая отвечает за выбор лидера, а затем поступившие данные переносятся на узел хранения с помощью внутренних механизмов репликации.
Apache Kafka® работает именно по такой схеме: ZooKeeper™ выбирает лидера, и данные реплицируются.
Apache Pulsar™ использует другой подход: хранение данных здесь реализовано с помощью отдельного сервиса Apache BookKeeper. Pulsar™ передает в него данные, просит их надёжно разместить, а рядом использует серверы ZooKeeper™, которые помогают Pulsar™ выбирать, какой из серверов будет лидером, и обеспечивают отказоустойчивость.
YDB Topics чем‑то похожа на эти системы, а чем‑то отличается. Мы тоже храним данные не локально, а в отдельной системе, которая называется YDB BlobStorage. Этот компонент принимает потоки данных и надёжно размещает их на узлах хранения в зависимости от доступности дата‑центров, серверов и узлов, информацией о которых он полностью владеет. BlobStorage обрабатывает выход узлов из строя — обеспечивает постоянную доступность данных. В зависимости от настроек он может либо хранить данные в трёх ДЦ, выполняя полные копии, либо с помощью Erasure‑кодирования уменьшать объём и физически хранить только полтора объёма данных.
Свойство | YDB Topics | Kafka® | Pulsar™ |
---|---|---|---|
Способ хранения | Выделенный, YDB BlobStorage | Локальное хранение данных | Выделенный, Apache BookKeeper |
Способ репликации и коэффициент хранения | Block-4-2, 1,5x | Репликация, 3x | Репликация, 3x |
Особенности хранения данных в YDB Topics:
Минимально разрешённое время хранения в инсталляциях YDB Topics в Яндексе — 18 часов.
Данные самых критичных сервисов хранятся 36+ часов.
Основной ограничивающий фактор — объём дисков. Мы перешли с жёстких дисков на NVME, выиграли по числу I/O‑операций, что позволило уменьшить количество серверов с тысячи до нескольких сотен, но объёма дисков стало не хватать.
Общий объём хранения: федерация — более 20 ПБ, кросс‑ДЦ — более 1 ПБ.
Стандартный кластер в YDB Topics состоит из нескольких сотен гетерогенных хостов, в каждом из которых:
56 ядер;
256 ГБ памяти;
2 HDD (система, логи);
4 NVME (данные).
Это типовая конфигурация: некоторые серверы мощнее, другие слабее. Поскольку мы храним системный софт и логи отдельно от данных, то можем определить количество доступных ядер и объём свободного места и перебалансировать систему. Более мощным серверам мы доверяем больше вычислительной нагрузки, на серверах с большим количеством дисков храним больше данных.
А вообще в самых больших кластерах YDB‑платформы больше 10 тысяч узлов. Следить за всем силами одного дежурного SRE‑специалиста удаётся в основном за счёт того, что все операции взаимодействия с сущностями платформы YDB переданы самим пользователям. В случае топиков пользователи сами управляют всем нужным для работы: заводят топики и удаляют их, меняют настройки и управляют ACL, получают новые мощности и отдают старые. При этом они могут делать это в любой момент, даже если команда YDB Topics в это же время выкатывает новый релиз на тот же кластер. В других сервисах платформы YDB тоже все операции отданы пользователям. Именно это позволяет нам фокусироваться на других задачах.
Протоколы, безопасность и мониторинг
Опенсорсное решение поддерживает собственный протокол YDB Topics и Apache Kafka®, а решение для Yandex Cloud — ещё и протокол Amazon Kinesis.
Все данные внутри Яндекса передаются в зашифрованном виде. Мы проводим регулярные аудиты безопасности, проверяем качество кода. Отслеживаем состояние системы и управляем ею с помощью веб‑консоли и посредством SQL‑запросов.
Что дальше
В наших планах:
Оптимизация скорости и сетевого обмена.
Схематизация данных. Исторически в Яндексе передавали и обрабатывали бинарные массивы данных, но с ростом компании стало сложнее понимать, какие данные где обрабатываются. Вот почему мы движемся в сторону каталогизации данных.
Увеличение поддержки Apache Kafka® API. Уже сейчас данные можно поставлять и считывать по протоколу Apache Kafka®, проделана большая работа по интеграции с Kafka Connect, где мы поддерживаем работу в Kafka Connect standalone-режиме. При этом мы активно занимаемся увеличением степени интеграции и планируем поддержать ещё и работу через KSQL.
Мы открыты предложениям! Если у вас появятся идеи, как улучшить YDB Topics, пожалуйста, приходите и делитесь: создавайте feature requests в Issues на Github или пишите нам в чат community.