netflix4분 읽기

큐레이션 요약

넷플릭스에서 카산드라 데이터 이동의 진화

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

넷플릭스는 하루 약 1,200건, 약 3PB의 Cassandra 데이터를 Iceberg로 옮기던 기존 Casspactor를 확장 가능한 계층형 엔진으로 교체했다. 기존 시스템은 여러 메타데이터 서비스에 의존하고 대규모 파티션과 다양한 Cassandra 데이터 모델을 제대로 처리하지 못해 안정성·비용·확장성 문제가 발생했다. 새 구조는 S3 백업을 단일 진실 공급원으로 사용하고, Spark DataFrame과 커넥터 팩토리를 기반으로 각 데이터 모델에 최적화된 커넥터를 구축한다.

Casspactor의 역할과 한계

  • Casspactor는 Cassandra의 SSTable과 메타데이터를 S3 백업에서 읽어 Iceberg 테이블로 변환했다.
  • 하루 약 1,200건의 데이터 이동과 약 3PB 규모의 전송을 처리하며 핵심 업무를 지원했다.
  • Cassandra 노드의 사이드카 프로세스가 SSTable과 메타데이터를 S3에 업로드하고, 작업 실행 시 엔진이 필요한 백업 구조를 구성했다.
  • 이후 SSTable을 다운로드하고 mutation compaction과 변환을 수행한 뒤 Iceberg에 기록했다.
  • 그러나 단일 커넥터로 설계되어 Key Value, Time Series, Graph 등 여러 데이터 추상화에 공통 기반을 제공하기 어려웠다.

분산된 메타데이터 의존성 문제

  • Casspactor는 백업의 존재 여부, 완전성, 포함 데이터를 여러 독립 시스템의 메타데이터를 조합해 판단했다.
  • 각 시스템의 갱신 주기와 정확도, 장애 방식이 달라 실제 백업 상태와 Casspactor의 인식이 불일치할 수 있었다.
  • 메타데이터가 실제 백업과 어긋나면 오래되거나 잘못된 데이터를 조용히 읽는 문제가 발생했다.
  • Cassandra 클러스터 유지보수 중 비동기 스냅샷이 만들어졌고, 한 리전에 있는 모든 노드가 같은 시각에 스냅샷을 생성해야 한다는 제약도 있었다.
  • 노드 하나가 교체되면 리전 전체의 데이터 이동이 실패할 수 있었다.
  • 새 구조에서는 백업 파일 자체의 메타데이터를 직접 읽어 S3를 백업 존재 여부와 완전성을 판단하는 단일 진실 공급원으로 사용한다.

모든 커넥터가 물려받은 제약

  • 대규모 파티션 처리 실패

    • Key Value와 Time Series에서 흔한 넓은 파티션을 처리하지 못했다.
    • 일부 작업은 메모리 부족으로 종료됐다.
  • 데이터 모델 인식 부족

    • 원시 Cassandra 테이블만 이동했기 때문에 Key Value 등의 커넥터가 별도의 후처리로 데이터 모델을 복원해야 했다.
    • 이로 인해 처리 비용과 복잡성, 장애 가능성이 증가했다.
  • 중간 테이블 증가

    • Casspactor는 최종 결과 전에 중간 Iceberg 테이블을 생성했다.
    • Key Value 커넥터는 추가 중간 테이블과 스냅샷 테이블까지 필요했다.
    • 상위 데이터 추상화가 추가될수록 중간 저장 공간과 비용이 누적됐다.
  • Time Travel 불가

    • 여러 서비스를 조합해 백업 단위를 구성했기 때문에 클러스터 토폴로지나 Keyspace 스키마가 변경된 뒤 과거 백업을 복원하기 어려웠다.
  • 모놀리식 구조

    • Casspactor는 재사용 가능한 엔진이 아니라 하나의 커넥터였다.
    • 데이터 모델별 목적형 커넥터를 공통 기반 위에 구축할 수 없었다.

새로운 계층형 아키텍처

  • 새 구조는 Apache Cassandra Analytics, 넷플릭스의 Move Data 프레임워크, 내부 백업 표현 방식과 S3 클라이언트를 결합한다.
  • 가장 아래 계층인 Cassandra Analytics Wrapper가 S3 백업에서 원시 데이터를 읽는다.
  • 읽은 결과는 표준 Spark DataFrame으로 변환된다.
  • 상위 계층의 Connector Factory는 Java UDF와 변환 로직을 통해 데이터 추상화별 커넥터를 생성한다.
  • Key Value나 Time Series 커넥터는 일반적인 DataFrame을 입력으로 받아 자체 데이터 모델에 맞게 처리한다.
  • 핵심 읽기 엔진의 개선 사항은 모든 커넥터에 적용되고, 각 커넥터는 변환 로직에 집중할 수 있다.

Spark 기반 처리와 운영 개선

  • mutation compaction과 데이터 처리를 Spark Executor 수준으로 이동했다.
  • 대규모 또는 편향된 파티션을 과도한 셔플 없이 처리해 메모리 부족 문제를 줄였다.
  • Cassandra 백업에서 바로 Spark DataFrame을 생성하므로 중간 Iceberg 테이블이 필요하지 않다.
  • 중간 저장 비용과 다단계 파이프라인의 운영 복잡성이 감소한다.
  • 소스 테이블의 특성에 따라 작업 리소스를 자동 조정하는 auto-sizing 기능을 제공한다.
  • 엔지니어가 작업별 리소스를 수동으로 조정하지 않아도 성능과 비용을 최적화할 수 있다.
  • S3의 백업 메타데이터를 직접 사용해 여러 외부 서비스에 대한 의존성을 제거하고 안정성을 높였다.

실용적인 결론

대규모 Cassandra 데이터 이동 시스템은 백업 메타데이터를 여러 서비스에서 조합하기보다 실제 저장소를 단일 진실 공급원으로 삼는 편이 안정적이다. 또한 원시 데이터 추출 엔진과 데이터 모델별 변환 커넥터를 분리하면, 공통 성능 개선을 재사용하면서도 Key Value·Time Series 같은 각 도메인에 최적화된 처리를 구현할 수 있다.

큐레이션 요약을 이어서 읽어보세요.