18P by xguru 10달전 | favorite | 댓글 1개
  • Apple은 iCloud와 CloudKit을 위해 Cassandra와 FoundationDB를 사용함
  • 이들 데이터베이스는 극단적인 멀티테넌시 아키텍처에서 수십억 개의 데이터베이스를 저장

시대를 초월한 실제 세계의 교훈

  • Meta와 Apple 모두 사용자 기능을 원활하게 하기 위해 비동기 처리를 사용
  • 두 회사 모두 상태 비저장(stateless) 아키텍처를 사용하여 확장성 문제를 해결
  • 자원을 논리적으로 격리하여 신뢰성과 가용성을 확보
  • 다양한 요구 사항을 단순하게 처리
  • 개발자 경험을 개선하기 위해 추상화 계층을 구축
  • 사용자를 알고 각 계층, API, 디자인을 결정

Cassandra

  • Cassandra는 광범위한 컬럼 기반의 NoSQL 데이터베이스 관리 시스템임
  • 원래 Facebook에서 Facebook 인박스 검색 기능을 위해 개발됨
    • 흥미롭게도 Meta 자체는 Cassandra 사용의 대부분을 ZippyDB ZippyDB로 대체
  • iCloud는 부분적으로 Cassandra를 사용하며, Apple은 세계에서 가장 큰 Cassandra 배포 중 하나를 운영
    • 30만개가 넘는 인스턴스/노드
    • 수백 페타바이트의 데이터
    • 클러스터당 2페타바이스 이상
    • 초당 수백만개의 쿼리
    • 수천개의 애플리케이션
  • Cassandra는 Apple에서 여전히 활발히 개선되고 있음
  • 그러나 CloudKit + Cassandra는 확장성 제한에 부딪혀 FoundationDB를 채택함

FoundationDB

  • Apple은 FoundationDB를 공개적으로 사용하며 2015년에 인수
  • FoundationDB는 대규모 데이터를 처리하도록 설계된 오픈 소스 분산 트랜잭션 키-값 저장소
    • 읽기/쓰기 워크로드와 쓰기가 많은 워크로드 모두에 적합
  • Apple은 CloudKit에 FoundationDB Record Layer를 광범위하게 사용
  • FoundationDB 레코드 레이어는 구조화된 데이터 저장을 위한 자바 API를 제공
  • 레코드 레이어는 극단적인 멀티테넌시를 지원

FoundationDB에 레코드 레이어 사용 이유

  • FoundationDB는 분산 시스템과 동시성 제어 작업을 처리함.
  • 레코드 레이어는 FoundationDB를 사용하기 쉽게 만드는 관계형 데이터베이스 역할을 함.
  • CloudKit은 가장 상위 계층에 있으며 애플리케이션 개발자를 위한 기능과 API를 제공함.
  • 레코드 레이어를 통해 Apple은 대규모 멀티테넌시를 지원
    • 각 애플리케이션의 각 사용자에게 독립적인 레코드 저장소를 제공하는 극단적인 멀티테넌시에 사용
    • 수천 개의 스키마를 공유하는 수십억 개의 독립적인 데이터베이스를 호스팅

CloudKit이 FoundationDB와 레코드 레이어를 사용하는 방법

  • CloudKit에서 애플리케이션은 정의된 스키마를 따르는 '논리적 컨테이너'로 표현됨
    • 이 스키마는 효율적인 데이터 검색 및 쿼리를 위해 필요한 레코드 유형, 필드 및 인덱스를 간략하게 설명
    • 애플리케이션은 CloudKit 내에서 데이터를 '영역'으로 구성하여 클라이언트 장치와 선택적으로 동기화할 수 있도록 레코드를 논리적으로 그룹화 가능
  • 각 사용자에게는 FoundationDB 내에서 고유한 서브스페이스가 지정되며, 사용자가 상호 작용하는 각 애플리케이션에 대한 레코드 저장소가 생성됨
    • 기본적으로 CloudKit은 사용자 수에 애플리케이션 수를 곱한 수만큼의 방대한 수의 논리적 데이터베이스를 관리
    • 각 데이터베이스에는 자체 레코드, 인덱스, 메타데이터 세트가 포함되어 수십억 개의 데이터베이스에 달합
  • CloudKit은 클라이언트 기기에서 요청을 받으면 로드 밸런싱을 통해 이 요청을 사용 가능한 CloudKit 서비스 프로세스로 전달
    • 프로세스는 특정 레코드 레이어 레코드 저장소와 상호 작용하여 요청을 처리
  • CloudKit은 정의된 애플리케이션 스키마를 별도의 메타데이터 스토어에 저장되는 레코드 레이어 내의 메타데이터 정의로 변환
    • 이 메타데이터는 레코드 생성, 수정 시간 및 레코드가 저장된 영역을 추적하는 CloudKit 전용 시스템 필드에 의해 보강
    • 각 영역 내의 레코드에 효율적으로 액세스할 수 있도록 영역 이름 앞에 기본 키가 접두사로 붙음
    • 사용자가 정의한 인덱스와 함께, CloudKit은 레코드의 유형별 크기를 추적하는 인덱스를 유지하여 스토리지 할당량 관리와 같은 내부 용도로 '시스템 인덱스'도 관리

FoundationDB와 레코드 레이어를 함께 사용하면 Cassandra만으로는 해결할 수 없던 Apple의 4가지 주요 문제를 해결할 수 있음

1. 개인화된 전체 텍스트 검색 문제 해결

  • FoundationDB는 사용자가 자신의 데이터에 빠르게 액세스할 수 있도록 개인화된 전체 텍스트 검색을 지원
  • FoundationDB의 키 순서를 활용하여 텍스트 시작 부분(접두사 매칭)을 빠르게 검색할 수 있을 뿐만 아니라, 추가 오버헤드 없이도 더 복잡한 검색(근접 검색 및 구문 검색과 같이 서로 가깝거나 특정 순서에 있는 단어 찾기 등)을 수행할 수 있음
  • 기존 검색 시스템에서는 검색 색인을 최신 상태로 유지하기 위해 백그라운드에서 추가 프로세스를 실행해야 하는 경우가 많지만, Apple의 시스템은 모든 작업을 실시간으로 처리하므로 데이터가 변경되는 즉시 검색 색인이 즉시 업데이트되므로 추가 단계가 필요하지 않음

2. 고동시성 영역 문제 해결

  • CloudKit은 FoundationDB를 사용하여 동시에 발생하는 많은 업데이트를 원활하게 처리
  • 이전에는 Cassandra를 사용하면서 CloudKit은 각 영역의 변경 사항을 추적하는 특수 인덱스에 의존하여 여러 기기에서 데이터를 동기화
    • 디바이스가 데이터를 업데이트해야 할 때 이 인덱스를 확인하여 새로운 내용을 확인
    • 하지만 여러 업데이트가 동시에 발생할 경우 충돌이 발생할 수 있다는 단점이 있었음
  • FoundationDB를 사용하면 CloudKit은 충돌을 일으키지 않고 각 변경의 정확한 순서를 추적하는 특수한 종류의 인덱스를 사용
    • 이는 모든 변경 사항에 고유한 '버전'을 할당하여 수행되며, CloudKit은 동기화가 필요할 때 이러한 버전을 확인하여 장치가 놓친 업데이트가 무엇인지 파악
  • 부하를 보다 균등하게 분산하기 위해 CloudKit이 여러 스토리지 클러스터 간에 데이터를 이동해야 하는 경우, 각 클러스터의 버전 번호가 일치하지 않기 때문에 상황이 까다로워짐
    • 이 문제를 해결하기 위해 CloudKit은 각 사용자의 데이터에 '이동 횟수'('incarnation/화신'이라고 함)를 부여하며, 이는 데이터가 새 클러스터로 전송될 때마다 증가
    • 각 레코드 업데이트에는 사용자의 현재 '화신' 번호가 포함되므로, 이동 후에도 CloudKit은 화신과 버전 번호를 모두 확인하여 올바른 업데이트 순서를 파악할 수 있음
  • 새로운 시스템으로 전환했을 때 CloudKit은 이러한 버전 번호가 없는 이전 데이터를 처리해야 하는 문제에 직면
    • 하지만 이전 시스템을 사용한 이전 업데이트를 새 시스템보다 먼저 정렬하는 특수 기능을 사용하여 이 문제를 현명하게 극복
    • 덕분에 앱을 복잡하게 변경하거나 오래된 코드를 남기지 않아도 되었음
    • 올바른 기록 순서를 유지하기 위해 화신, 버전 및 이전 업데이트 카운터 값을 고려

3. 고지연성 쿼리 문제 해결

  • FoundationDB는 낮은 지연 시간이 아닌 높은 동시성을 위해 설계. 즉, 개별 작업의 속도에 집중하기보다는 동시에 많은 작업을 처리할 수 있음
  • 이러한 설계를 최대한 활용하기 위해 레코드 레이어는 많은 작업을 '비동기적으로' 수행
    • 향후 완료할 작업을 대기열에 올려두고 그 사이에 다른 작업을 수행할 수 있도록 함
    • 이 접근 방식은 이러한 작업 중에 발생할 수 있는 지연을 커버하는 데 도움이 됨
  • 그러나 FoundationDB가 데이터베이스와 통신하는 데 사용하는 도구는 네트워킹을 위해 단일 스레드를 사용하여 한 번에 한 가지 작업을 수행하도록 설계
    • 이전 버전에서는 이 설정으로 인해 모든 작업이 이 네트워크 스레드에서 차례를 기다리고 있었기 때문에 시스템에서 트래픽 정체가 발생
    • 레코드 레이어는 이 단일 스레드 접근 방식을 사용하고 있었기 때문에 병목 현상이 발생함
  • 이를 개선하기 위해 Apple은 이 네트워크 스레드의 작업 부하를 줄임
    • 이제 시스템이 대기열을 형성하지 않고 동시에 여러 측면에서 데이터베이스와 작업하기 때문에 복잡한 작업이 더 빨라짐
    • 이렇게 하면 시스템이 다른 작업을 시작하기 전에 한 작업이 완료될 때까지 기다리지 않기 때문에 지연 시간 또는 겉으로 드러나는 느림이 숨겨짐

4. 충돌하는 트랜잭션 문제 해결

  • FoundationDB에서는 한 트랜잭션이 특정 키를 읽는 동시에 다른 트랜잭션이 동일한 키를 수정하는 경우 '트랜잭션 충돌'이 발생
    • FoundationDB는 읽기 또는 쓰기 시 이러한 충돌을 일으킬 수 있는 키 집합에 대한 제어 기능을 제공하여 이러한 충돌을 정밀하게 관리할 수 있음
  • 불필요한 충돌을 피하는 일반적인 방법은 충돌을 일으키지 않는 특수한 종류의 읽기, 즉 '스냅샷' 읽기를 다양한 키에 대해 수행하는 것
    • 이 읽기에서 중요한 키를 발견하면 트랜잭션은 전체 범위가 아니라 잠재적 충돌이 있는 특정 키에만 플래그를 지정
    • 이렇게 하면 트랜잭션이 실제로 결과에 중요한 변경 사항의 영향만 받도록 할 수 있음
  • 레코드 레이어는 이 전략을 사용하여 순위 인덱스 시스템의 일부인 건너뛰기 목록이라는 구조를 효율적으로 관리
    • 그러나 이러한 충돌 범위를 수동으로 설정하는 것은 까다로울 수 있으며, 특히 애플리케이션의 주요 로직과 혼합되어 있는 경우 식별하기 어려운 버그로 이어질 수 있음
    • 따라서 FoundationDB를 기반으로 구축된 시스템에서는 이러한 패턴을 처리하기 위해 사용자 정의 인덱스와 같은 상위 수준의 도구를 만드는 것이 좋음
    • 이 접근 방식은 충돌 규칙을 완화하는 책임을 각 클라이언트 애플리케이션에 맡겨 실수와 불일치를 초래할 수 있는 상황을 방지하는 데 도움이 됨

Hacker News 의견

  • 한 해커뉴스 사용자는 애플에서 일할 때 데이터베이스와 파일 시스템 간의 차이점에 대한 통찰을 공유함. 데이터베이스와 파일 시스템이 근본적으로 같은 기능을 하며, 특정 문제를 해결하기 위한 최적화라고 언급함. 예를 들어, iCloud는 데이터베이스를 기반으로 파일 시스템을 정의하는 방법을 보여줌. 이 사용자는 비디오 저장을 위해 Cassandra를 사용한 경험을 공유함.

  • 또 다른 사용자는 이전 회사에서 FoundationDB와 RecordLayer를 사용하여 트랜잭셔널 카탈로그 시스템을 구축한 경험을 언급함. 이 시스템은 매우 효과적이었으며, gRPC와 Protobuf를 사용하는 것이 자연스러웠음. 그러나 FoundationDB를 대규모로 운영하기 위한 진입 장벽이 높다는 단점을 지적함.

  • 한 사용자는 Apple Notes의 동기화 기능이 마크다운 기반 노트 애플리케이션보다 충돌을 잘 처리한다고 평가함. 이로 인해 결국 Apple Notes로 이동했다고 언급함.

  • FoundationDB에 관한 이전 게시물들이 언급됨. 이는 FoundationDB의 분산 키-값 저장소, 레코드 레이어, 애플의 인수, 그리고 FoundationDB의 작동 원리와 특징에 대한 링크를 포함함.

  • 클라우드 기반 저장소와 협업으로 점진적으로 이동하는 네이티브 데스크톱 소프트웨어의 아키텍처에 대한 흥미로운 점이 언급됨. 스키마 변경과 버전 마이그레이션을 잘 처리하는 것이 중요하며, 이는 관리자 개입 없이 대규모로 발생함.

  • 한 사용자는 iCloud가 Time Machine 백업을 저장할 수 있기를 바람.

  • FoundationDB가 SQLite를 기반으로 하고 있기 때문에, HCTree 엔진이 FoundationDB에 적용될 가능성에 대한 궁금증이 제기됨. HCTree는 SQLite의 읽기/쓰기 성능을 10배 향상시킬 수 있는 잠재력을 가지고 있음.

  • iCloud가 사용자의 파일을 어떻게 관리하는지에 대한 불만이 있음. iCloud가 최근에 사용한 파일, 앱, 사진을 자동으로 클라우드로 옮겨 공간을 확보하는 것이 문제가 될 때가 있음.

  • 한 사용자는 과거 은행에서 일할 때 사용했던 Hyperion이라는 보고 시스템에 대해 회상함. 이 시스템은 각 보고서마다 새로운 데이터베이스를 생성했으며, 당시에는 이상하게 여겨졌지만, 지금 생각해보면 시대를 앞서가는 방식이었음을 언급함.