scylladb

2 개의 포스트

discord4분 읽기큐레이션 요약

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와 재개 가능한 태스크 프레임워크를 결합하면, 위험한 업그레이드를 자동화하면서도 실패 복구 비용을 크게 줄일 수 있다.

원문 읽기(새 탭에서 열림)
datadog원문

Glommio 소개: Rust와 Linux를 위한 코어당 스레드 크레이트 (새 탭에서 열림)

현대적인 클라우드 비용 절감과 성능 최적화를 위해서는 단순히 코드의 병목점을 찾는 것을 넘어, 하드웨어 성능을 극대화할 수 있는 '코어당 스레드(thread-per-core)' 아키텍처로의 전환이 필요합니다. 이 아키텍처는 애플리케이션의 꼬리 지연 시간(tail latency)을 최대 71%까지 개선할 수 있지만, 구현이 복잡하고 개발 생산성을 떨어뜨릴 수 있다는 단점이 있습니다. Datadog은 이러한 문제를 해결하기 위해 Rust 개발자들이 코어당 스레드 모델을 쉽게 구현할 수 있도록 돕는 오픈소스 라이브러리 'Glommio'를 제안합니다. **기존 멀티스레드 모델의 한계와 비용** * 전통적인 멀티스레딩 방식은 여러 스레드가 동일한 데이터에 접근할 때 데이터 정합성을 보장하기 위해 락(Lock)을 사용하며, 이는 실행을 멈추고 대기하는 시간을 발생시켜 비용을 증가시킨다. * 스레드 간 컨텍스트 스위칭(Context Switching)은 약 5마이크로초의 비용이 드는데, 이는 io_uring과 같은 최신 커널 인프라의 I/O 처리 시간(4마이크로초 미만)보다 길다. 즉, 스레드 전환 비용이 실제 I/O 작업보다 비싸지는 역전 현상이 발생한다. * 기존의 비동기 프로그래밍 방식 또한 파일 I/O 등을 처리할 때 내부적으로 스레드 풀을 사용해야 하는 경우가 많아 완전한 효율성을 달성하기 어렵다. **코어당 스레드(Thread-per-core)의 동작 원리** * 각 CPU 코어에 단 하나의 스레드만 할당하고 이를 특정 코어에 고정(Pinning)함으로써, OS 스케줄러에 의한 스레드 이동과 컨텍스트 스위칭을 원천적으로 차단한다. * 하드웨어 인터럽트나 시스템 에이전트와 같은 외부 작업을 위해 특정 코어를 전용으로 분리하고, 나머지 코어를 애플리케이션 스레드에 할당하여 간섭을 최소화한다. * 모든 작업은 협력적 스케줄링(Cooperative Scheduling) 방식으로 동작하며, 실행 중인 작업이 명시적으로 제어권을 양보하거나 완료될 때까지 CPU를 점유하여 선점형 스케줄링의 오버헤드를 없앤다. **데이터 샤딩을 통한 락 프리(Lock-free) 구현** * 각 스레드가 전체 데이터의 특정 부분집합(Shard)만을 담당하도록 설계하여, 서로 다른 스레드가 동일한 데이터에 접근할 가능성을 차단한다. * 예를 들어 특정 카프카 파티션이나 데이터베이스 키 범위별로 담당 스레드를 지정함으로써, 스레드 간의 데이터 공유를 최소화한다. * 데이터 업데이트 작업이 해당 스레드 내에서 자연스럽게 직렬화(Serialized)되므로, 복잡하고 비용이 큰 락(Lock) 메커니즘 없이도 안전하게 데이터를 조작할 수 있다. **Glommio를 통한 Rust 애플리케이션 최적화** * Glommio는 C++의 Seastar 프레임워크와 유사한 철학을 Rust 환경에 가져와, 개발자가 코어당 스레드 아키텍처의 복잡한 세부 사항을 직접 다루지 않고도 고성능 애플리케이션을 작성할 수 있게 한다. * 성능 민감도가 높은 대규모 데이터 스토어(Datastores)나 고처리량 메트릭 수집 시스템을 운영하는 팀에게 Glommio는 하드웨어 효율성과 개발 편의성을 동시에 잡을 수 있는 실질적인 대안이 된다.