TL;DR
В Uber работает свыше 2300 кластеров MySQL; цель — 99,99% доступности.
Архитектура разделена на плоскости: данных, управления и обнаружения — каждая со своей зоной ответственности.
Плоскость управления держит «желаемое состояние» кластера (Odin) и исполняет устойчивые рабочие процессы (Cadence): переключение primary, замена узлов, изменения схемы.
Контроллер по правилам следит за здоровьем кластеров и запускает автоматические действия, включая аварийное переключение.
Плоскость обнаружения даёт стабильную точку входа (VIP): топология хранится в etcd, реверс-прокси обновляется автоматически при изменениях.
Узел MySQL — это набор контейнеров: база, воркер для приведения к «желаемому состоянию», метрики, проверки здоровья, бэкап.
Наблюдаемость строится на метриках и зондами; настроены оповещения по лагам, отказам записи и аномалиям.
CDC читает binlog и отправляет изменения в Kafka, далее — в хранилище на Hive.
Резервное копирование — Percona XtraBackup, RPO ~4 часа, RTO от минут до часов.
Итог: управление крупным парком баз без ручной магии за счёт строгого состояния, автоматизации и изоляции плоскостей.
В Uber наш парк MySQL® — основа нашей дата-инфраструктуры, поддерживающая широкий спектр операций, критически важных для платформы. Uber эксплуатирует обширный парк MySQL, включающий свыше 2 300 независимых кластеров. Создать плоскость управления для такого масштаба, обеспечив нулевые простои и отсутствие потерь данных, — одна из самых сложных задач в отрасли.
За последние годы мы взялись за повышение доступности парка MySQL с 99,9% до 99,99% за счёт ряда оптимизаций и переработки плоскости управления. Это первая публикация в серии постов о развёртывании и эксплуатации MySQL в Uber. В этом материале мы поговорим об архитектуре парка MySQL в Uber, операциях плоскости управления и некоторых улучшениях, внесённых за последние пару лет на уровне плоскости управления.
Архитектура
Парк MySQL в Uber состоит из множества кластеров, каждый — из нескольких узлов. Есть два основных потока: поток данных, в котором клиенты/сервисы взаимодействуют с кластером MySQL, и поток управления, который отвечает за жизненный цикл кластеров.
В потоке данных stateless-сервисы, размещённые в Kubernetes®, подключаются к своему кластеру MySQL через стандартный клиент. На каждом сервере работает обратный прокси, в котором хранится схема маршрутизации к узлам MySQL по ролям (primary/replica/batch). Это позволяет клиенту через протокол JDBC™ обнаруживать и подключаться к нужному кластеру в зависимости от выполняемого запроса.
Поток управления занимается развёртыванием, обслуживанием и выводом из эксплуатации кластеров и узлов, при этом обеспечивая требования к безопасности и интеграцию с экосис��емой Uber.
Парк MySQL в Uber включает следующие основные компоненты (см. рисунок 1):
Плоскость управления (Control plane)
Плоскость данных (Data plane)
Плоскость обнаружения (Discovery plane)
Наблюдаемость (Observability)
Фиксация изменений данных (CDC) и загрузка в хранилище данных
Резервное копирование/восстановление (Backup/restore)

Ровно эти контуры и отрабатываются на курсе «Инфраструктура высоконагруженных систем» — проектирование control/data/discovery, L4/L7-балансировка, Kubernetes/Nomad, Ceph/Gluster, репликация и failover, наблюдаемость и DR, обновления без простоя.
Плоскость управления
Плоскость управления MySQL — это система, управляемая состоянием, которая включает несколько компонентов/сервисов и хранилищ. В её ядре находится менеджер технологии, отвечающий за оркестрацию остальных компонентов плоскости управления. Одна из его ключевых задач — публикация желаемого состояния кластера в Odin — внутреннюю платформу Uber, технологически нейтральную и предназначенную для управления технологиями с сохранением состояния; Odin также управляет размещением узлов. Менеджер публикует целевое состояние в Odin. Целевое состояние включает ключевые параметры конфигурации, такие как профили ресурсов, количество узлов, роли (Primary/Follower), сайдкар-контейнеры, которые должны запускаться на узлах данных, серверные настройки (например, формат бинарного лога, режим SQL (SQL_MODE)) и многое другое. Плоскость управления гарантирует, что фактическое состояние кластера MySQL или узла MySQL на любой стадии будет приводиться к определённому желаемому состоянию.
Другая важная роль менеджера технологии — обеспечивать изменение состояния системы через рабочие процессы (workflow). Workflow — это отказоустойчивый длительно работающий процесс на базе Cadence. Примеры рабочего процесса: добавление нового узла в существующий кластер, переключение первичного узла в кластере, применение некоторых переменных MySQL на узле, смена источника репликации для реплики MySQL и т. п. Другие ключевые функции менеджера технологии:
Управление кластерами: операции создания, обновления и удаления кластеров.
Переключение первичного узла: смена первичного узла кластера.
Управление жизненным циклом узлов: добавление, замена и удаление серверных узлов MySQL.
Сбалансированное размещение: передача сигналов планировщику Odin для равномерного распределения серверных узлов по всем географическим локациям, где развёрнута инфраструктура Uber. Это обеспечивает устойчивость к сбоям оборудования и даже к отказам дата-центров.
Операции БД: управление операциями, специфичными для базы данных, такими как настройка системных переменных, настройка репликации и операции масштабирования.
Изначально плоскость управления MySQL была жёстко связана с инфраструктурными процессами. По мере роста парка MySQL это приводило к проблемам: операции по размещению в инфраструктуре блокировались из-за отказов на стороне MySQL. Команда MySQL тратила много времени на отладку этих инцидентов. Такая связность ухудшала операционную надёжность более чем 60 рабочих процессов, включая переключение первичного узла, замену узлов и др. Кроме того, для хранения состояния кластеров MySQL использовалась система конфигураций на базе Git — решение, не оптимизированное под подобные сценарии. Всё это создавало проблемы с надёжностью и масштабируемостью, что потребовало переработки архитектуры всей плоскости управления.
Контроллер
В рамках переработки плоскости управления мы добавили компонент «контроллер» (controller). Контроллер выступает внешним наблюдателем для всех кластеров MySQL, собирая сигналы из базы данных и других компонентов плоскости управления. В состав контроллера входит модуль оценки правил, который отслеживает эти сигналы и предпринимает действия при нарушении заданных правил в любом кластере. Одна из ключевых ролей контроллера — мониторинг «здоровья» первичных узлов MySQL и автоматическое переключение первичного узла при возникновении проблем у текущего первичного. Кроме того, контроллер обеспечивает балансировку в кластерах, входящих в консенсусные группы в топологиях Group Replication.
Оркестрация критически важных потоков
Основным способом взаимодействия с плоскостью управления являются рабочие (workflow) процессы. Workflow — это асинхронные, событийно-ориентированные процессы, определённые как последовательность шагов для оркестрации сложных долгоживущих задач. В плоскости управления MySQL для исполнения рабочего процесса используется Cadence™, обеспечивающий долговечность, отказоустойчивость и масштабируемость. На рисунке 2 показан типичный рабочий процесс в плоскости управления MySQL.

Этот редизайн обновил все операции плоскости управления. Ниже рассмотрена оркестрация некоторых критически важных потоков.
Переключение первичного узла
В Uber используется схема «один первичный узел (primary) — несколько реплик». Записи обрабатывает первичный узел, а данные реплицируются на реплики посредством стандартной репликации MySQL на основе бинарного лога (binlog).

Переключение первичного узла — это автоматизированный процесс, при котором первичный узел кластера переводится с одного хоста на другой. Поскольку узел только один, поддержание его здоровья и работоспособности критично для высокой доступности операций записи и минимизации простоев. Рабочий процесс для переключения первичного узла используются как мера реагирования компонентами, которые постоянно мониторят состояние первичного узла и запускают переключение при признаках деградации.
В зависимости от состояния текущего первичного узла выполняются два типа переключений: плановое и аварийное.
Плановые переключения требуются при регламентных работах на текущем первичном узле, например, когда хост первичного узла нуждается в ремонте. Процедура включает выбор кандидата в первичный узел и аккуратную передачу нагрузки на запись со старого узла на новый. Предполагается, что текущий первичный ключ доступен и здоров. Это применимо к конфигурациям с асинхронной и полусинхронной репликацией. Есть ещё один этап развёртывания, связанный с Group Replication, но он выходит за рамки этой статьи.
Плавное переключение выполняет следующие шаги:
Переводит текущий первичный узел в режим только для чтения.
Останавливает трафик на текущем первичном узле.
Выбирает новый первичный узел. По умолчанию рабочий процесс выбирает кандидата из того же дата-центра. Учитывается лаг репликации: приоритет полу��ает узел с наиболее продвинутой позицией в бинарном логе.
Получает позиции бинарного лога на предыдущем первичном узле и ожидает применения этих транзакций на кандидате.
Включает возможность записи на новом первичном узле.
Если текущий первичный узел недоступен (например, из-за отказа зоны дата-центра или сетевой изоляции), MySQL выполняет аварийное переключение. Шаги те же, что и при плавном переключении, за исключением того, что система не полагается на текущий первичный узел для передачи всех данных на новый, поскольку он считается недоступным.
Мы гарантируем доступность 99,99% для нижестоящих сервисов, и переключение первичного узла — критически важный процесс, который помогает нам выполнять условия данного SLA.
Замена узла
Замена узла в плоскости управления подразумевает перенос узла MySQL (вместе со всеми его данными) с одного хоста на другой без какого-либо влияния на пользователей этой базы данных.
Аппаратная инфраструктура Uber распределена между несколькими облачными провайдерами и собственным дата-центрами и включает сотни тысяч машин, а также иные аппаратные и сетевые компоненты. Замена узла критична для плоскости управления MySQL: она защищает парк от сбоев в столь обширной инфраструктуре и сохраняет его гибкость. Рабочий процесс замены узла — это регламентная операция, при которой узел на затронутом хосте корректно останавливается, а на другом хосте с сопоставимыми ресурсами и географическим расположением создаётся идентичный узел — полностью прозрачно для пользователей базы, которые даже не замечают этого перемещения.
Хотя внешне это просто операция переноса данных, замена узла имеет ряд нюансов:
Аппаратный профиль: новый узел должен иметь тот же профиль оборудования, что и заменяемый. Это означает одинаковое число ядер CPU, объём диска и памяти, порты и т. п.
Размещение: новый узел должен быть размещён на хосте с тем же уровнем отказоустойчивости, что и заменяемый, чтобы обеспечить идентичные сетевые задержки. Клиентам важно лишь, чтобы задержки запросов оставались стабильными вне зависимости от физического местоположения узла.
Зависимости: если текущий узел является источником репликации для других узлов в топологии, его дочерние узлы должны либо переключиться на новый узел-замену, либо подключиться к другому узлу кластера.
Повышение до первичного: если заменяемый узел — это первичный узел кластера, до его вывода из эксплуатации или снятия с трафика необходимо выполнить «плавное» переназначение роли первичного узла на другой узел.
Внутренне замена узла состоит из двух независимых операций: добавления узла и удаления узла.
Добавление узла — это процесс начальной инициализации, который включает размещение и подготовку данных. Размещение — это выбор локации узла: требуется определить хост с необходимыми ресурсами для нового узла. Синхронизация данных включает установку процесса MySQL на выбранный узел и запуск передачи данных с одного из существующих узлов (предпочтительно с первичного) на новый узел. Процесс добавления узла поддерживает параллельное добавление нескольких узлов, что особенно полезно в сценариях восстановления после аварий.
Удаление узла — это процедура аккуратного удаления хоста после того, как все описанные выше зависимости узла корректно обработаны.
Изменения схемы
Плоскость управления MySQL автоматизирует изменения схемы через самообслуживаемый рабочий процесс. В процессе используются «мгновенный ALTER» MySQL (instant alter) или Percona™ pt-online-schema-change (ptosc) для безопасного и неблокирующего обновления схемы на первичном узле. Рабочий процесс интеллектуально подбирает стратегию применения изменений схемы в зависимости от типа изменения и объёма данных. Например, для быстрых и безопасных добавлений столбцов используется «мгновенный ALTER» (INSTANT ALTER), а для смены типов данных — неблокирующие онлайн-методы, такие как pt-online-schema-change (ptosc).
Рабочий процесс изменений схемы также поддерживает режим «dry run». Он позволяет применить изменение схемы на изолированной реплике до применения на первичном узле (и в остальной части кластера). Это даёт дополнительную уверенность, что изменение обратно совместимо, неразрушающе и безопасно.
Рабочий процесс изменений схемы интегрирован с конвейерами CI/CD Uber, поэтому процесс полностью автоматизирован и проходит через ревью. Разработчики вносят изменения в файл схемы, который коммитится в репозиторий вместе с остальным исходным кодом. После утверждения и слияния с основной веткой CI-система обнаруживает это и запускает соответствующий рабочий процесс. Это даёт разработчикам полный контроль над своей схемой и гарантирует, что развёрнутый код всегда согласован со схемой базы данных.
Плоскость данных
Работающий узел MySQL состоит из нескольких контейнеров, запущенных на одном хосте. Контейнер базы данных запускает процесс MySQL и ряд вспомогательных компонентов, выполняющих чётко определённые задачи. Эти компоненты изолированы в контейнерах Docker®, работающих на одном хосте и взаимодействующих друг с другом по сети Docker. Строение узла MySQL показано на рисунке 4.

Узел MySQL включает:
Контейнер базы данных: запускает движок Oracle InnoDB® внутри процесса mysqld. Можно настроить использование и других движков MySQL, например Meta RocksDB™.
Контейнер-воркер: сайдкар-контейнер, отвечающий за приведение фактического состояния узла к целевому. Интегрирует узел MySQL с движком размещения Odin.
Контейнер метрик: опрашивает различные сигналы базы данных (например, QPS, типы запросов, время удержания блокировок, метрики соединений), которые излучает процесс MySQL, и публикует их для мониторинга.
Контейнер проверки работоспособности: периодически отслеживает состояние процесса MySQL и выдаёт сигналы о здоровье первичного узла. Эти сигналы потребляет контроллер, который предпринимает действия для предотвращения отказов первичного узла, обеспечивая строгие SLA по простоям записи для пользователей MySQL в Uber
Контейнер резервного копирования: временный контейнер, который периодически запускается для создания резервной копии базы и выгр��жает её в объектное хранилище.
Плоскость обнаружения
Плоскость маршрутизации и обнаружения упрощает взаимодействие клиентов с кластером MySQL, абстрагируя постоянно меняющуюся аппаратную инфраструктуру Uber. Она предоставляет единый виртуальный IP (VIP), по которому сервисы подключаются к своим кластерам MySQL, скрывая все изменения на уровне железа.

Плоскость маршрутизации и обнаружения состоит из трёх основных компонентов.
Реверс-прокси: выступает в роли балансировщика нагрузки и перенаправляет запросы клиентов на хосты с базой данных и ответы обратно.
Служба пуллинга: отвечает за обновление конфигурации прокси во время любых операций управления кластерами/узлами, таких как переключение первичного узла или замена узлов.
Стандартный клиент: предоставляет простые и удобные функции для установления соединений с первичным узлом и репликами в зависимости от типа запроса (чтение/запись), а также пул соединений, обработку таймаутов, метрики на стороне клиента и т. п.
В рамках переработки плоскости управления плоскость маршрутизации перевели на строго консистентное хранилище топологии на базе etcd™. Изменения топологии (например, добавление нового узла или обработка переключений первичного ключа) менеджер записывает в хранилище топологии. Затем эти обновления попадают в службу пуллинга через механизмы наблюдения etcd; служба на их основе корректирует конфигурацию обратного прокси, чтобы направлять трафик на новые узлы или снимать трафик с выводимых из эксплуатации узлов (при замене узла). Всё это полностью скрыто от клиентов: они подключаются к обратному прокси по статическому VIP. Конфигурация прокси генерируется так, чтобы направлять запросы на запись на первичный узел, а чтение — балансировать между всеми репликами, с приоритетом реплик в той же географической зоне.
Плоскость обнаружения поддерживает отключение трафика на отдельных узлах. Это удобно для отладки аппаратных или программных сбоёв на узлах MySQL без влияния на клиентский трафик. Эту возможность можно автоматизировать через контроллер — например, автоматически отключать трафик на узлах с лагом репликации.
Наблюдаемость
Помимо сбора системных метрик с контейнеро в и кластеров используются зонды (probers), которые имитируют поток данных и собирают метрики здоровья различных компонентов каждого кластера. Эти метрики и логи агрегируются в системе метрик и логирования Uber. Настраиваются оповещения для выявления сбоёв, таких как недоступность записи, лаг репликации, высокая загрузка CPU и аномальные подключения к первичному узлу. Эта экосистема наблюдаемости позволяет команде MySQL-as-a-Service держать под контролем здоровье всего парка MySQL. Команды, владеющие сервисами, использующими базы данных, также могут подписываться на эти оповещения.
Захват изменений данных
Для механизма захвата изменений данных (CDC) во флоте MySQL используется Storagetapper, который считывает изменения (вставки, обновления, удаления) из бинарного лога, передаёт их в Apache Kafka®, после чего они загружаются в хранилище данных на Apache Hive™. Эта система умеет обрабатывать изменения схемы на стороне источника, выполнять трансформации и преобразование форматов.
Резервное копирование и восстановление
Резервное копирование и восстановление в MySQL у Uber полностью автоматизированы. Для бэкапов используются возможности Percona XtraBackup™. Процессы резервного копирования и восстановления обеспечивают RPO в 4 часа и RTO от нескольких минут до часов — в зависимости от объёма данных.
Заключение
MySQL находится в основании многих критически важных сервисов Uber. Плоскость управления обеспечивает надёжную, масштабируемую и высокопроизводительную платформу MySQL для этих сервисов, снимая операционные накладные расходы по сопровождению такого парка в масштабах Uber.
В этом вводном материале мы рассмотрели основные компоненты плоскости управления MySQL, их архитектуру и роль, а также ключевые операции и автоматизации в плоскости управления. Они поддерживают парк в здоровом и гибком состоянии без необходимости ручного вмешательства, позволяя обслуживать множество клиентов и сценариев использования. В следующих публикациях мы подробнее разберём эксплуатацию MySQL для обеспечения высокой доступности и высокой пропускной способности.
Слабые места бьют по SLA одинаково: дрейф конфигураций, ручные переключения и «медленные» пайплайны данных. Если это про ваши контуры — ниже два открытых урока, которые преподаватели Otus проведут бесплатно в рамках курсов. Приходите:
21 октября в 18:30 — Apache Kafka для DWH: как потоковые данные усиливают хранилище. Записаться
21 октября в 20:00 — Идемпотентность и консистентность декларативной иммутабельной инфраструктуры. GitOps на практике. Записаться