cluster-automation

1 개의 포스트

discord

Discord가 대규모로 ScyllaDB 클러스터를 자동화하는 방법 (새 탭에서 열림)

Discord는 수백 개의 ScyllaDB 노드를 소수의 인원이 운영하기 위해, 취약한 스크립트 모음 대신 Scylla Control Plane(SCP)을 구축했다. SCP는 실제 트래픽을 복제하는 shadow cluster를 자동으로 생성·검증해 ScyllaDB 업그레이드와 인프라 변경을 운영 환경에 적용하기 전에 안전하게 테스트한다. 작업을 태스크와 워크플로로 구조화하고, 사전 조건·재시도·상태 저장·병렬성 제어를 제공함으로써 클러스터 구축 시간을 크게 줄이고 실패 시 처음부터 다시 시작해야 하는 문제를 해결하는 것이 핵심이다. ## 대규모 ScyllaDB 운영의 어려움 - Discord의 Persistence Infrastructure 팀은 7명으로 Elasticsearch, Postgres, ScyllaDB 클러스터를 운영한다. - ScyllaDB는 메시지, 채널, 서버, 사용자 데이터 대부분을 저장하며, 수십 개 클러스터와 수백 개 노드로 구성된다. - 주요 운영 작업에는 다음이 포함된다. - 설정 변경 후 롤링 재시작 - 트래픽 증가에 따른 클러스터 확장 - 무중단 운영을 유지한 운영체제 업그레이드 - 새 ScyllaDB 버전을 검증하기 위한 신규 클러스터 생성 - 작업 간 순서와 검증이 중요하기 때문에 단순한 일회성 자동화만으로는 부족하다. ## 기존 스크립트의 한계 - Python과 Bash 스크립트를 점진적으로 추가해 왔지만, 운영 규모가 커지면서 도구가 취약해졌다. - 스크립트가 제공하던 문제점은 다음과 같다. - **안전하지 않음:** 잘못된 순서나 대상 노드에 실행할 수 있고, 실행 전 조건 확인이 부족했다. - **복구 불가능:** 여러 단계 중간에 실패하면 완료한 작업까지 되돌리거나 전체 작업을 처음부터 다시 해야 했다. - **확장하기 어려움:** 새 작업을 추가할 때 기존 스크립트를 복사하고 수정하는 방식이 필요했다. - 운영에 필요한 절차와 노하우가 개별 엔지니어의 경험에 의존했다. ## Shadow Cluster를 통한 안전한 업그레이드 검증 - Shadow cluster는 운영 클러스터의 전체 복제본으로, 짧은 기간 동안 실제 운영 트래픽의 읽기와 쓰기를 함께 처리한다. - 운영 환경에 영향을 주기 전에 다음과 같은 문제를 실제 부하에서 발견할 수 있다. - 특정 ScyllaDB 버전의 예외적인 동작 - 대규모 클러스터에서만 발생하는 버그 - 모든 노드 업그레이드 후에야 나타나는 문제 - 신규 shadow cluster를 수동으로 만들려면 다음 절차를 반복해야 했다. - 노드 프로비저닝 및 설정 - 노드를 클러스터에 순차적으로 조인 - 복제 상태 검증 - dual-write 파이프라인 구성 - 테스트 후 리소스 제거 - Discord는 ScyllaDB 버전뿐 아니라 운영체제와 하드웨어 변경 전에도 shadow cluster를 표준 검증 절차로 활용한다. ## SCP 설계 목표 SCP는 기존 운영 경험에서 얻은 문제를 바탕으로 다음 네 가지 목표를 세웠다. - **확장 가능한 태스크 프레임워크** - 작업의 입력과 실행 로직만 정의하면 기존 오케스트레이션 환경에서 동작하도록 설계한다. - 새로운 개발자가 내부 실행 구조를 모두 이해하지 않아도 새 작업을 추가할 수 있어야 한다. - **설정 가능한 병렬성** - 여러 노드에서 동시에 실행해도 되는 작업과 순차 실행이 필요한 작업을 구분한다. - 예를 들어 서로 다른 availability zone의 노드에서 특정 작업을 동시에 실행하지 않도록 제약을 표현할 수 있다. - **기본적으로 안전한 실행** - 태스크가 실행 전제 조건을 직접 선언한다. - 일시적 오류는 자동으로 재시도한다. - 실행 상태를 저장해 중단된 작업을 완료 지점부터 재개한다. - **점진적 개발과 배포** - 처음부터 거대한 시스템을 만들기보다 사용할 수 있는 기능부터 배포한다. - 실제 클러스터에서 사용하며 온보딩과 사용성 문제를 조기에 발견하고 개선한다. - 사용되지 않는 복잡한 프레임워크를 만드는 일을 피한다. ## SCP의 기본 구조 SCP는 **태스크(task)**, **워크플로(workflow)**, **잡(job)**이라는 계층적 개념을 중심으로 구성된다. - **태스크** - 하나의 구체적인 작업 단위다. - 예: 노드 drain, repair 상태 확인, 정리 작업 실행 - 단일 노드에서 실행되는 **노드 태스크**와 클러스터 전체를 조정하는 **클러스터 태스크**로 나뉜다. - 클러스터 태스크는 여러 노드에서 노드 태스크를 실행하는 역할도 담당한다. - **조건(condition)** - 다음 태스크로 넘어가기 전에 클러스터가 특정 상태에 도달했는지 확인하는 특수한 태스크다. - Scylla API나 Prometheus 메트릭을 주기적으로 조회한다. - 조건이 충족되면 진행하고, 제한 시간 안에 충족되지 않으면 오류를 발생시킨다. - **명시적인 상태 대기** - 노드 재시작 후에는 compaction이 안정될 때까지 기다려야 한다. - 고정된 `sleep`만 사용하면 대기 시간이 너무 짧아 장애를 일으키거나, 너무 길어 전체 롤링 재시작이 불필요하게 느려질 수 있다. - 조건 태스크는 대기 과정을 관찰 가능하고 조정 가능하게 만든다. ## 실용적인 결론 대규모 데이터베이스 운영에서는 개별 스크립트를 계속 늘리기보다, 작업의 선행 조건·재시도·상태 저장·병렬 실행 규칙을 표준화한 오케스트레이션 계층이 필요하다. 특히 운영 트래픽을 재현하는 shadow cluster와 재개 가능한 태스크 프레임워크를 결합하면, 위험한 업그레이드를 자동화하면서도 실패 복구 비용을 크게 줄일 수 있다.