Uber의 MySQL 플릿(fleet) 관리: 컨트롤 플레인 재설계 이야기(원문 번역)

🕒 약 1분 읽는 데 소요됩니다


Uber의 MySQL 플릿(fleet) 관리: 컨트롤 플레인 재설계 이야기

Uber에서 MySQL 플릿은 데이터 인프라의 핵심으로, 플랫폼의 다양한 중요 작업을 지원합니다. Uber는 2,300개 이상의 독립 클러스터로 구성된 대규모 MySQL 플릿을 운영하고 있으며, 이 방대한 규모를 관리하면서 무중단과 무데이터 손실을 보장하는 컨트롤 플레인 구축은 업계에서도 가장 까다로운 문제 중 하나입니다.

최근 몇 년간, 우리는 다양한 최적화와 컨트롤 플레인의 재설계를 통해 MySQL 플릿의 가용성을 99.9%에서 99.99%로 향상시키기 위한 여정을 시작했습니다. 이 글은 Uber에서 MySQL의 배포 및 운영에 대해 다룰 시리즈 블로그의 첫 번째 편입니다. 이번 포스트에서는 Uber의 MySQL 플릿 아키텍처, 컨트롤 플레인 운영, 그리고 지난 몇 년 동안 개선된 주요 사항들을 소개합니다.


아키텍처

Uber의 MySQL 플릿은 여러 개의 클러스터와 수많은 노드로 구성되어 있습니다. 데이터 흐름과 컨트롤 흐름, 두 가지 주요 흐름이 존재합니다.

  • 데이터 흐름: Kubernetes에 호스팅된 무상태 서비스는 표준 클라이언트를 통해 MySQL 클러스터와 연결됩니다. 각 서버에는 리버스 프록시가 있으며, MySQL 노드의 역할(Primary/Replica/Batch)에 따른 라우팅 맵을 저장합니다. 이는 클라이언트가 JDBC 프로토콜을 사용하여 적절한 클러스터를 탐색하고 연결할 수 있도록 합니다.
  • 컨트롤 흐름: 클러스터와 노드의 프로비저닝, 유지관리, 폐기를 관리하며, 보안과 Uber 생태계 통합을 보장합니다.

MySQL 플릿의 주요 구성 요소는 다음과 같습니다:

  • 컨트롤 플레인
  • 데이터 플레인
  • 디스커버리 플레인
  • 관측성
  • 변경 데이터 캡처 및 데이터 웨어하우스 적재
  • 백업/복원

컨트롤 플레인

MySQL 컨트롤 플레인은 여러 컴포넌트/서비스와 저장소로 구성된 상태 기반 시스템입니다. 중심에는 기술 관리자(Technology Manager)가 있으며, 이 관리자는 다른 컨트롤 플레인 컴포넌트들의 오케스트레이션을 담당합니다.

주요 기능:

  • Odin에 목표 상태(Priority State) 게시: Odin은 Uber의 자체 상태 기반 기술 관리 플랫폼입니다. 게시되는 목표 상태에는 리소스 프로파일, 노드 수, 역할, 사이드 컨테이너, 서버 설정 등이 포함됩니다.
  • 워크플로우 실행: Cadence 기반의 워크플로우를 통해 상태 변경이 가능합니다. 예시로는 노드 추가, Primary Failover, MySQL 변수 적용 등이 있습니다.
  • 클러스터/노드 수명 주기 관리
  • 지리적 분산을 고려한 균형 배치
  • DB 설정 및 스케일링 작업 처리

기존 시스템은 인프라와 밀접하게 결합되어 있었으며, 이는 MySQL 오류로 인해 인프라 작업이 차단되는 문제를 야기했습니다. 또한 Git 기반 설정 저장소는 대규모 운영에 적합하지 않았고, 이는 전체 컨트롤 플레인의 재설계를 불러왔습니다.


컨트롤러

새로운 아키텍처에서 컨트롤러는 모든 MySQL 클러스터를 관찰하는 외부 옵저버 역할을 합니다. 규칙 평가자를 포함하고 있으며, 규칙 위반이 감지되면 조치를 취합니다.

주요 기능:

  • Primary 노드 상태 감시 및 자동 Failover 수행
  • 그룹 복제 환경에서 클러스터 균형 유지

주요 흐름의 오케스트레이션

컨트롤 플레인의 주요 상호작용 방식은 워크플로우입니다. Cadence 기반으로 비동기 이벤트 기반으로 동작하며, 고가용성과 확장성을 제공합니다.

Primary Failover

  • Single Primary – Multiple Replica 구성
  • Graceful Failover: 유지보수 목적, Primary가 정상인 상태에서 새로운 Primary를 선정 후 역할 이전
  • Emergency Failover: Primary가 불가용할 경우 자동 수행

이 프로세스를 통해 99.99% 가용성을 달성할 수 있습니다.

노드 교체

노드 교체는 MySQL 노드를 한 호스트에서 다른 호스트로 옮기는 작업입니다.

조건:

  • 동일한 하드웨어 프로파일
  • 동일한 지리적 위치/장애 허용 수준
  • 자식 노드에 대한 의존성 관리
  • Primary 노드 교체 시 사전 Failover 수행

노드 추가(부트스트랩 및 데이터 동기화)와 노드 삭제(의존성 제거 후 제거) 두 단계를 거칩니다.


스키마 변경

  • 자체 워크플로우로 스키마 변경 자동화
  • Instant Alter 또는 Percona의 ptosc 사용
  • Dry-run 기능: 사전 테스트 가능
  • CI/CD 파이프라인과 통합되어 완전 자동화 및 코드 리뷰 연동

데이터 플레인

MySQL 노드는 단일 호스트 내 여러 Docker 컨테이너로 구성됩니다.

구성 요소:

  • Database 컨테이너: MySQL 프로세스를 실행
  • Worker 컨테이너: 상태 동기화 및 Odin 통합
  • Metrics 컨테이너: QPS, 쿼리 유형, 연결 수 등 수집
  • Health Prober: 주기적으로 상태 점검
  • Backup 컨테이너: 백업 수행 후 오브젝트 스토어 업로드

디스커버리 플레인

클라이언트와 MySQL 클러스터 간의 상호작용을 단순화하고 가상 IP를 통해 물리적 변경을 추상화합니다.

구성 요소:

  • Reverse Proxy: 로드 밸런싱 역할
  • Pooling 서비스: 프록시 설정 업데이트
  • 표준 클라이언트: 연결, 타임아웃, 요청 분기 등 처리

etcd 기반의 강력한 일관성 토폴로지 저장소를 사용하며, 프록시 구성이 자동으로 갱신됩니다.


관측성

  • 시스템 메트릭 및 로그 수집
  • Prober를 통해 시뮬레이션 및 상태 모니터링
  • 알림 구성: 쓰기 실패, 복제 지연, CPU 과다 사용 등 감지

변경 데이터 캡처 (CDC)

Storagetapper를 통해 binlog에서 변경 사항을 추출하여 Apache Kafka로 전송하고, 이후 Apache Hive로 적재합니다. 스키마 변경과 포맷 변환도 처리 가능합니다.


백업 및 복구

  • Percona XtraBackup 사용
  • 자동화된 백업 및 복원
  • 4시간 RPO, 수 분~수 시간 내 RTO 보장

결론

MySQL은 Uber의 핵심 서비스에 깊이 통합되어 있으며, 컨트롤 플레인은 안정적이고 확장 가능하며 고성능의 MySQL 플랫폼을 제공합니다. 이번 블로그에서는 MySQL 컨트롤 플레인의 주요 구성 요소, 아키텍처, 자동화된 운영 방식을 소개했습니다. 향후 블로그에서는 고가용성과 고처리량을 보장하는 구체적인 운영 방식을 더 깊이 다룰 예정입니다.

원문: MySQL at Uber: Scaling and Operational Excellence
작성일: 2025년 1월 30일
작성자: Uber Engineering

Uber 데이터 플랫폼 이미지