(OSDI'06) Ceph

골덕·2024년 11월 28일

Introduction

  • Traditional distributed file system

    • NFS(Network File System)
      • cross-platform, secure data sharing 지원
      • 파일 대상 block allocation 관리를 통해 글로벌 파일 자료 구조를 유지해야 함
      • 각 head들이 하나의 컨센서스를 이루는데 확장성에 큰 문제가 있음
  • Object based storage based architecture
    ( https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=1222722)

    • low-level block management를 storage device에 위임하고 block이 아닌 object 단위로 관리
    • 단순히 scalable, cross-platform, secure data sharing을 가능하게 하는 것을 넘어서 특별한 intelligence를 구현할 수 있게 됨
      • self-configuration, self-protection, self-optimization, self-healing, and self-management
      • intelligent object storage devices(OSDs) = CPU + network interface + local cache

  • 일반적인 OSD 기반 분산 파일 시스템의 구조 (lustre, gfs)
    • 클라이언트는 메타데이터 작업(open, rename 등)을 처리하기 위한 메타데이터 서버(MDS)와 상호작용하며, 파일 I/O 작업(읽기, 쓰기)은 OSD와 직접 통신
    • 작업을 분산시켜 전체 시스템의 확장성을 크게 향상시킴
  • 그러나 기존의 분산 파일 시스템은 여전히 MDS가 object배치를 직접 관리(allocation lists and inode tables)하는 전통적인 파일 시스템 원칙을 따르고 있으며, 확장성, 성능, 신뢰성을 극대화하기 위해 OSD의 지능과 자원(CPU, 메모리)을 충분히 활용하지 못함.

System Overview

Main Components

  • client
    • 애플리케이션 코드가 실행되는 각 호스트에서 동작
    • user-space에서 FUSE(user-space file system interface)를 통해 파일 시스템으로 마운트하여 사용
    • exposing a near-POSIX file system interface to a host or process (selectively relax consistency semantics)
    • 클라이언트는 파일 데이터 캐시를 유지하며, 애플리케이션이 해당 캐시에 접근할 수 있도록 함.
  • cluster of OSDs
    • a single logical object store for all data and metadata from clients and metadata servers
  • metadata server(MDS) cluster
    • manages the namespace (file names and directories) while coordinating security, consistency and coherence

Goal

  • Scalability, Performance, Reliability
    • to hundreds of petabytes and beyond
    • including the overall storage capacity and throughput of the system, and performance in terms of individual clients, directories, or files
    • Target workload may include such extreme cases,
      • scientific applications ~ tens or hundreds of thousands of hosts concurrently reading from or writing to the same file or creating files in the same directory.

Three fundamental design features

  • Decoupled Data and Metadata
    • 기존 object 기반 파일 시스템에서도 MDS가 파일의 object 위치를 결정하고 관리 (object allocation list)
    • Ceph는 CRUSH 알고리즘을 통해 각 주체(e.g. client)가 직접 object 위치를 계산 가능하도록 설계함
    • MDS의 역할을 최소화하고 시스템의 확장성과 효율성을 극대화
  • Dynamic Distributed Metadata Management
    • Dynamic Subtree Partitioning은 수십, 수백 개의 MDS에 메타데이터 워크로드를 current access patterns 기반으로 적응적으로 분배
    • locality를 보존하면서 MDS 자원을 효과적으로 활용할 수 있도록 함
    • 이 또한, 메타데이터 시스템의 확장성과 효율성을 극대화
  • Reliable Autonomic Distributed Object Storage(RADOS)
    • data migration, replication, failure detection, failure recovery의 역할을 cluster of OSDs에 위임(self-managment)
    • 리소스를 효율적으로 활용, 선형 확장성과 높은 가용성

Client Operation

File I/O and Capabilities

  • 프로세스가 파일을 열 때, 클라이언트는 MDS(Metadata Server) 클러스터에 요청을 보냄.
  • MDS는 파일 이름으로 파일 시스템 계층 구조를 탐색해 파일 inode로 변환.
    • 이 inode에는 고유한 inode 번호, 파일 소유자, 모드, 크기 및 기타 파일별 메타데이터가 포함.
    • 파일이 존재하고 접근 권한이 있다면, inode 번호, 파일 크기, 오브젝트 매핑 정보를 클라이언트에 반환.
    • 또한, 클라이언트가 수행할 수 있는 작업을 명시한 capability도 발급(읽기, 읽기 캐시, 쓰기, 쓰기 버퍼).
    • 이 후 file i/o에 있어, MDS의 역할은 파일 일관성을 보장하기 위한 capability 관리로 제한됨.
  • Ceph는 파일을 일련의 오브젝트로 매핑하는 striping strategies을 일반화.
    • 파일 할당 메타데이터(file allocation metadata)가 필요 없도록, 오브젝트 이름은 파일의 inode 번호와 stripe 번호를 단순히 조합하여 생성
    • 각 Object의 OSD 위치는 CRUSH(mapping function)를 통해 확인(+ Cluster Map).
  • 클라이언트가 파일을 읽기 목적으로 열 경우,
    • MDS는 파일 내용을 읽고 캐싱할 수 있는 capability를 부여.
    • 클라이언트는 inode 번호, layout, 파일 크기를 활용하여 파일 데이터를 포함하는 모든 오브젝트의 이름을 생성하고, OSD 클러스터에서 데이터를 직접 읽어옴.
  • 클라이언트가 파일을 쓰기 목적으로 열면,
    • MDS는 데이터를 버퍼링하며 쓸 수 있는 capability를 부여.
    • 클라이언트는 파일 내 임의의 오프셋에서 생성한 데이터를 적절한 OSD의 적절한 오브젝트에 바로 기록
    • 파일을 닫을 때, 클라이언트는 capability를 반납하고, MDS에 새 파일 크기(가장 큰 오프셋)를 전달
      • 이를 통해 MDS는 데이터가 포함될 수 있는 오브젝트의 범위를 다시 정의.
rbd
  • 생성한 rbd 이미지를 4MB의 object들로 striping 됨
    • 10GB rbd image는 약 2560개 object로 구성됨
  • 한 object는 해당 rbd 이미지 일부의 offset을 담당하게 되는 것
  • librbd를 통해서 rbd volume(e.g. /dev/rbd0)에 특정 offset에 대해 write 요청(e.g. 10MB)이 들어왔을 때 이를 librbd가 계산
  • object_index = floor( 10 MB / 4 MB ) = 2
  • object_name = "rbd_data.<image_id>.00000000000002"
  • 최종적으로 주어진 object_name을 이용해 CRUSH 알고리즘을 통해 OSD 위치를 계산하고 저장
  • rbd에 필요한 관련 최소한의 메타데이터는 따로 rados pool로 저장

Client Synchronization

  • POSIX semantics은 클라이언트 간 읽기-쓰기와 공유 쓰기 작업에서 일관성을 보장을 요구
    • 읽기 작업은 항상 이전에 쓰여진 데이터를 반영해야 하고,
    • 쓰기 작업은 동시에 수행된 겹치는 쓰기 작업은 특정 순서를 따라야 함.
  • 이를 Ceph에서 구현한다면...
    • 한 파일이 여러 클라이언트에 의해 열려, 읽기와 쓰기가 수행될 경우,
      • MDS는 이전에 부여했던 읽기 캐싱과 쓰기 버퍼링 capability를 회수 → 해당 파일의 클라이언트 I/O 작업이 synchronous로 처리되도록 강제.
        • 이 방식에서는 각 애플리케이션의 읽기 또는 쓰기 작업이 OSD로부터 ack를 받을 때까지 대기
        • 업데이트 직렬화와 동기화의 부담은 해당 오브젝트를 저장하는 OSD로 전가
  • 클라이언트는 쓰기 작업에 영향을 받는 object에 대해 OSD로부터 exclusive lock을 획득하고, 쓰기 작업을 진행한 후 잠금을 해제하여 원하는 직렬화(serialization)를 달성
    → osd의 업데이트 직렬화와 동기화 부담을 제거
    • 대규모 쓰기 작업에서도 동일하게 lock을 사용하여, 데이터를 Asynchronous flush하면서 latency을 완화 (쓰기 작업은 비동기적으로 진행, 락 설정/해제는 동기적).
    • synchronous i/o(POSIX의 엄격한 동기화 요구)는 자체적으로 일관성을 관리하는 HPC와 같은 응용에 대해 불필요한 성능 저하를 유발
  • Ceph는 이러한 hpc 응용에 대한 일관성 완화(consistency relaxation) 옵션을 지원 (일관성과 성능 간의 trade-off)
    • O_LAZY 플래그 : 파일을 열 때 사용되는 새로운 플래그로, 일관성(coherency) 요구를 완화(relax)할 수 있도록 허용.
      • 공유 쓰기(shared-write)가 발생하더라도, 쓰기 버퍼링(write buffering) 및 읽기 캐싱(read caching)을 허용하여 동기화를 줄임.
    • O_LAZY를 통해 성능을 최적화하지만, 필요에 따라 특정 시점에서 동기화를 수행해야 할 수 있음.
      • lazyio_propagate
        • 특정 바이트 범위(byte range)에 대해 쓰기 버퍼의 데이터를 object store로 flush
      • lazyio_synchronize
        • 이전에 flush된 데이터가 읽기 작업에서 반영되도록 보장

Namespace Operations

  • 모든 메타 작업은 MDS가 직접 동기적으로 처리 (업데이트 직렬화)

    • 메타데이터 업데이트에 있어서는 클라이언트에게 lock 같은 동기화 메커니즘을 제공하지 않음
  • 대신 common metadata access를 최적화

    • readdir - caching inodes
      • 대규모 디렉터리에서 readdir(디렉터리 내용 조회)와 stat(각 파일의 상세 정보 조회)을 연속적으로 실행하는 패턴은 매우 흔함.
      • readdir 요청 한 번으로 디렉터리의 모든 항목과 각 파일의 inode 정보를 한꺼번에 가져옴.
      • stat 작업이 즉시 이어질 경우, inode 정보는 캐시에 저장되어 빠르게 반환(이후 stat 작업이 없으면 캐시는 폐기).
      • 다른 클라이언트에 의해 디렉터리 항목이나 inode가 수정되었더라도 캐시를 기반으로 반환될 수 있음(약간의 일관성 완화).
        • 성능 향상을 위해 의도적으로 감수하는 trade-off.
      • Ceph의 이 최적화 동작은 *readdirplus라는 표준 확장으로 정의됨.
  • 메타데이터를 더 오래 캐싱하여 성능을 향상시킬 수 있지만, 현실적으로 이는 파일 상태(stat) 정보의 일관성(coherency) 손실을 초래.

    • 파일 크기나 수정 시간(mtime)이 오래된 캐시값으로 반환되어 애플리케이션 동작이 잘못되거나, 캐시 만료를 기다리느라 지연 발생.
  • Ceph는 일관성은 유지하면서 성능을 개선하기 위해 아래와 같은 방식으로 인터페이스를 확장.

    • 파일이 여러 클라이언트에 의해 동시에 쓰이고 있는 상황에 stat 요청이 있는 경우:
      1. MDS가 모든 쓰기 권한(write capabilities)을 잠시 회수(revoke)하여 업데이트를 중지.
      2. 모든 클라이언트에서 최신 파일 크기와 수정 시간을 수집.
      3. 가장 큰 값(최신 상태)을 반환.
      4. 이후 쓰기 권한을 재발행하여 작업 재개.
    • 단일 클라이언트가 파일을 쓰는 경우에는 클라이언트로부터 정보를 바로 받아 중단 없이 처리.

Dynamically Distributed Metadata

  • 분산 파일 시스템에서 메타데이터 관리는 확장성 측면에서 Challenge.
    • 저장 장치 추가로 용량과 I/O 성능은 쉽게 확장 가능하지만, 메타데이터 작업은 높은 상호 의존성 때문에 일관성과 동기화 관리가 어려움.
      • 계층 구조에 의한 작업이 연쇄적으로 발생
  • Ceph의 metadata design features:
    • 메타데이터는 매우 작으며, 디렉토리 항목(파일 이름)과 80바이트 크기의 inode로 구성됨
      • 기존 파일 시스템과 달리 file allocation metadata가 필요하지 않음
        • 앞서 설명했듯, inode 번호를 기반으로 object 이름을 생성하고 CRUSH를 통해 OSD에 분배.
      • 메타데이터 워크로드 단순화, 대규모 파일 효율적으로 관리.
    • Two-tiered storage strategy로 디스크 I/O를 최소화 (mds journal & osd cluster).
    • Dynamic Subtree Partitioning을 통해 locality와 캐시 효율을 극대화.

Metadata Storage

  • 메타데이터 업데이트 :
    • MDS가 디렉토리나 파일의 메타데이터를 수정하면 이를 저널(대규모 수백 MB, sequential write)과 메모리 캐시에 먼저 빠르게 기록 → 초기 처리 속도 향상
      • 여러 번 수정된 메타데이터는 마지막 업데이트만 유지.
        • 중복 쓰기 흡수
      • 디스크로 바로 쓰지 않고, 게으른(flushed lazily) 방식으로 업데이트를 OSD 클러스터(long-term storage)로 전달 → I/O 효율화
  • 장애 복구:
    • MDS가 다운되면 (MON이 감지), 다른 MDS가 실패한 MDS의 저널을 읽어 중요 데이터를 복구하고 메모리 캐시를 재구성. 이를 통해 파일 시스템 상태를 빠르게 복원
  • on-disk storage layout
    • Inode(파일 메타데이터)가 디렉토리에 직접 포함되어 있어, MDS는 단일 OSD 읽기 요청으로 전체 디렉토리를 미리 로드(prefetch)할 수 있음
      • 이를 통해 대부분의 워크로드에서 디렉토리 locality(데이터의 물리적 근접성)를 최대한 활용
    • 디렉토리 내용(directory's content) 또한 메타데이터 저널 및 파일 데이터와 동일하게 CRUSH 통해 OSD 클러스터에 저장

Dynamic Subtree Partitioning

  • primary-copy caching strategy

    • 특정 메타데이터의 캐시 일관성 관리와 업데이트 직렬화를 단일 권한을 가진 MDS가 책임지도록 설계
  • dynamic subtree partitioning strategy

    • 기존 분산 파일 시스템은 directory와 file metadata 분산을 위해 static subtree-based partitioning(dynamic workloads에 취약) 또는 hash functions(locality에 손해)을 사용
    • 각 MDS는 디렉토리 계층 내 메타데이터의 인기를 카운터로 측정
      • 최근 워크로드 분포를 나타내는 Weighted Tree를 유지
  • MDS 간 부하를 비교해 특정 MDS가 과부하 상태인 경우, 작업량이 많은 서브트리를 다른 MDS 로 이전

    • 서브트리 크기는 부하에 따라 조정되며 locality를 유지하기 위해 가능한 큰 단위(coarse-grained)로 이동
    • 클라이언트 요청에 영향을 최소화하며 작업 처리
  • Long-Term Storage(OSD Cluster)와 Namespace Lock을 통해 안전한 마이그레이션 지원

    • Long-Term Storage를 활용해 MDS 간 데이터를 쉽게 이동
    • Namespace Lock은 디렉토리 트리 잠금을 통해 다른 클라이언트 요청을 제한 (?????)
      • 특정 디렉토리 트리를 관리하는 단일 권한의 MDS 외에는 변경 권한 없음
  • 기존 MDS(MDS1)의 메모리 캐시에 저장된 메타데이터를 새로운 MDS(MDS2)로 전송

    • 새로운 MDS는 전송받은 데이터를 자신의 저널에 기록
    • 양쪽(MDS1, MDS2)의 저널에 상태를 기록해 장애 시 복구 가능성 보장
  • 마이그레이션은 Two-Phase Commit 방식으로 진행

    • 준비 단계: MDS1이 데이터를 MDS2로 전송, MDS2는 저널에 기록 후 준비 완료를 알림
    • 클라이언트 요청이 여전히 MDS1으로 들어올 경우, MDS1은 작업을 처리하고 이를 MDS2로 동기화
    • 커밋 단계: MDS1이 소유권 이전 완료를 기록, MDS2는 Primary로 전환 후 클라이언트 요청 처리
  • The resulting subtree-based partition is kept coarse to preserve locality

    • 한 mds에 최대한 많은 디렉토리를 담으려 함
      • 유저 요청이 /dir3/dir4/dir5/file 이렇게오면 한개씩 다 확인해야 함 (트리 경로 전체 탐색)
  • minimize prefix replication overhead

    • 서브 트리가 새로운 MDS로 이동할 때, 해당 서브트리의 상위 디렉토리 어디에 속하는지 기본적인 정보를 함께 replication함

Traffic Control

  • 읽기 요청이 많은 디렉토리는 여러 노드에 선택적으로 복제하여 부하를 분산
    • 특정 MDS가 과부하 상태에 도달하면, Ceph는 메타데이터를 동적으로 다른 MDS로 이동하거나 복제.
  • 예외적으로 크기가 크고 쓰기 요청이 많은 디렉토리는 디렉토리의 locality를 희생하면서, 파일 이름을 기준으로 해싱하여 클러스터 전체에 내용을 분산해 부하를 균형 있게 분배.
  • 모든 MDS 응답은 클라이언트에게 권한, 관련 inode의 replication, ancestors 정보를 제공
    • 클라이언트가 특정 경로에서 작업을 수행할 때, 전체 파일 시스템에서 해당 metadata partition의 실시간 상태와 위치를 학습
      • MDS map은 클러스터 전체의 MDS 배치와 분할 상태를 전반적으로 설명하지만, 클라이언트가 상호작용하는 경로에 대한 세부적인 정보는 포함 않음.
  • 클라이언트가 /dir3/dir4/dir5/file.txt를 요청하는 경우:
    • 클라이언트가 /dir5에 대한 정보를 알고 있다면 바로 해당 MDS로 요청 가능.
    • 클라이언트가 /dir3까지만 알고 있다면, /dir3의 MDS에 요청을 보내 경로를 탐색해야 함.
  • 클라이언트는 위치를 학습(MDS Map & 경로 탐색)하며, 적절한 MDS에 직접 접근
    • 여러 MDS에 분산되어 있거나 다른 MDS에 위치하기도 한 경우에 대해서도 문제없이 동작

Distributed Object Storage

Data Distribution with CRUSH

  • Data Distribution

    • 불균형 또는 부하 비대칭을 방지하기 위해
      • 새로 배치된 장치가 대부분 유휴 상태이거나 비어 있는 경우, 새로운 장치에만 집중적으로 핫 데이터가 저장되는 경우
    • 새로운 데이터를 무작위로 분산, 기존 데이터의 무작위 샘플을 새 장치로 이동, 제거된 장치의 데이터를 균등하게 재분배하는 전략을 채택(CRUSH)
    • 먼저, ceph는 hash function(+ adjustable bit mask)을 이용해 object를 특정 수의 placement groups(PGs)로 매핑
      • object를 위치시키는 논리적 데이터 관리 단위. PG 단위로 OSD에 배치.
    • OSD별로 약 100개의 PG를 할당하여 OSD 사용률의 편차를 균형 있게 조정하고, 각 OSD가 유지해야 하는 replication 관련 메타데이터의 양을 관리.
  • CRUSH(Controlled Replication Under Scalable Hashing)

    • CRUSH를 통해 각 Placement Group(PG)를 정렬된 OSD 리스트(Primary & Replicas)에 매핑 (n-way replication)
    • Object를 찾기 위해 CRUSH는 PG와 OSD 클러스터 맵만 필요
      • 완전히 분산된 구조로, 클라이언트, OSD, 또는 MDS가 독립적으로 모든 오브젝트의 위치를 계산할 수 있음.
      • 클러스터 맵이 드물게 업데이트되므로, 분배 관련 메타데이터 교환이 거의 필요 없음.
    • CRUSH는 데이터 분배 문제("데이터를 어디에 저장해야 하는가")와 데이터 위치 문제("데이터를 어디에 저장했는가")를 동시에 해결
    • 설계상, 스토리지 클러스터에 작은 변경(장치 장애나 클러스터 확장 등)이 발생하더라도 기존 PG 매핑에 미치는 영향을 최소화하여 데이터 마이그레이션을 줄임.
  • cluster map hierarchy

    • OSD (Object Storage Daemon): 데이터를 저장하는 개별 디스크.
    • Row: 여러 OSD를 포함하는 서버.
    • Rack: 여러 서버로 구성된 랙.
    • Room: 여러 랙이 포함된 데이터 센터의 룸.
    • 이러한 계층은 장애 구역(failure domain)을 정의하여, 장애가 발생했을 때 영향을 최소화할 수 있도록 설계.
    • 각 OSD는 가중치 값(weight)을 가지고 있어, OSD에 할당되는 데이터 양을 제어.
  • CRUSH는 Placement Rule에 따라 PG를 OSD에 매핑하며, 이 규칙은 Replication 수준과 배치 제한(constraints on placement)을 정의.

    • Placement Rule의 예시:
      • 데이터 복제본(2개)은 동일한 Room에 배치하지만,
      • 각 복제본은 서로 다른 Rack(cabinet)에 배치하여 특정 장애(전원 문제나 네트워크 스위치 문제)를 방지.
  • cluster map 동기화

  • cluster map은 down 또는 inactive device 리스트와 함께 맵이 업데이트 될 때마다 증가하는 epoch number를 포함

  • 클라이언트는 OSD에 요청을 보낼 때, 자신이 현재 알고 있는 클러스터 맵의 에포크(epoch) 번호를 함께 전달해 OSD가 해당 맵이 최신 상태인지 확인.

    • 클라이언트의 맵이 최신이면 요청을 그대로 처리.
    • 클라이언트의 맵이 오래된 경우, OSD가 응답 메시지에 최신 맵의 증분 업데이트를 함께 포함시켜 piggy back으로 클라이언트를 업데이트.
  • 맵이 변경되면, 협업하는 OSD 간(cooperating OSDs)에 맵 증분 업데이트(Incremental map updates)가 공유.

    • 클러스터 맵 전체를 다시 전송하는 대신, 변경된 부분만 piggy back으로 전송.
    • 뒤에서 또 자세히 설명

Replication

  • Replication은 PG 단위로 진행
  • a variant of primary-copy replication
    • 클라이언트는 Object가 속한 PG의 Primary OSD에 쓰기 요청을 보냄.
    • Primary OSD는 해당 Object와 PG에 대한 새로운 버전 번호를 할당한 후, 쓰기 요청을 추가 복제본 OSD들에 전달.
    • 모든 복제본 OSD가 업데이트를 적용하고 Primary OSD에 응답하면, Primary OSD가 로컬에 업데이트를 적용하고 클라이언트에 쓰기 완료 신호를 보냄
    • 기본적으로 읽기 요청은 Primary OSD로 전달되어 처리.
  • Ceph의 데이터 복제 방식은 클라이언트에게 복잡한 동기화와 직렬화 문제를 떠넘기지 않고 OSD 클러스터가 이를 대신 처리
    • 클라이언트가 데이터를 Primary OSD에만 쓰면, 나머지 작업(복제, 동기화, 직렬화)은 OSD 클러스터가 수행
    • 복제를 위한 추가 네트워크 대역폭은 OSD 간 내부 네트워크에서 사용.

Data Safety

  • 여러 클라이언트가 동시에 작업(다중 쓰기)하거나, 읽기와 쓰기를 섞어서 사용하는 경우 실시간 데이터 일관성이 필요
  • 동시에, 클라이언트는 replication data가 모두 안전하게 저장되었는지 확인하고 싶음
  • Synchronization과 Safety를 분리
    • 클라이언트 A가 데이터를 씀.
    • Primary OSD가 데이터를 받고, 모든 Replica osd의 in-memory buffer cache에 update apply가 완료되면, 즉시 클라이언트 A에 우선 쓰기 성공 응답(ack).
    • 이 시점에서 클라이언트 B는 새로운 데이터를 읽을 수 있음(Synchronization).
    • 만약 모든 osd가 다죽어버리면 데이터 loss이기 때문에, 이 경우를 대비하여 디스크 커밋 전까진 클라이언트 A가 업데이트 요청에 대한 버퍼링을 해둠
    • 장애 발생시, 새로운 업데이트를 잠시 허용하지 않고, 버퍼링해둔 업데이트 요청을 replay함으로서 recovery 진행
    • Disk commit은 비동기적으로 그 이후에 진행되어(몇 초후), final noti. 를 클라이언트에 반환.

Failure Detection

  • Ceph는 분산 환경에서 발생할 수 있는 다양한 네트워크 이상(network anomalies)과 장애(failures)를 효과적으로 처리하기 위해 모니터 노드(MON)와 OSD 간 협력 메커니즘을 사용
  • OSD
    • OSD는 기본적으로 disk error또는 corrupted data와 같은 failure는 self-detect하고 MON에 report함
    • OSD가 네트워크에서 unreachable되는 경우를 감지하기 위해,
      • 기본적으론 기존 replication traffic을 활용해 Peer OSD의 상태를 확인(Passive Monitoring),
      • 일정 시간 동안 Peer OSD로부터 응답이 없으면, ping을 전송함을 결합하여 상태를 확인(Active Monitoring).
    • osd의 liveness
      • whether the OSD is reachable
        • 응답하지 않는 OSD는 먼저 down 상태로 표시되며, 해당 Placement Group(PG)의 Primary 주요 작업(업데이트 직렬화, 복제 등)은 임시로 다음 OSD로 이관
        • 일시적인 문제로 복구 가능성 있음
        • 클러스터 맵에서는 여전히 해당 OSD가 데이터를 담당하는 것으로 간주
      • whether it is assigned data by CRUSH
        • OSD가 빠르게 복구되지 않으면 out 상태로 전환되고, 다른 OSD가 PG에 추가되어 데이터를 재복제.
    • 실패한 OSD와의 작업이 대기 중인 클라이언트는 새로운 Primary OSD에 요청을 다시 보냄
  • MON
    • Ceph MON 클러스터는 OSD 연결 문제로 인한 장애 보고를 수집하고, 일시적 또는 시스템적 문제(예: 네트워크 분할)를 중앙에서 필터링 함.
    • 핵심은 장애를 분산 감지(OSD)를 분산 처리하면서도, 최종적으로는 중앙 집중식으로 상태를 정리(MON)하는 데 있음
      • 장애 상태로 판단된 OSD는 Mon의 클러스터 맵(Cluster Map)에 반영
      • 맵이 업데이트되면, 변경 사항이 해당되는 OSD들에게 증분 업데이트(incremental updates) 형식으로 전달
        • MON은 클러스터 맵의 변경 사항을 일부 OSD에만 증분 업데이트로 전달. 나머지는 OSD들 간의 상호작용을 통해 정보를 공유
        • 업데이트된 증분 맵 정보는 OSD 간 기존 통신(ex: 복제 트래픽)에 "얹혀서(piggyback)" 클러스터 내에 전파됩니다.
    • 분산된 감지 과정에서 불일치(inconsistency)가 발생할 가능성이 있음.
      • OSD1은 OSD2가 다운되었다고 판단했지만, 다른 OSD는 그렇게 판단하지 않을 수 있음.
    • MON이 중앙에서 이를 중재하여, 일관된 클러스터 맵을 제공합니다.
    • 또한, 시스템적인 문제(예: 전력 장애)로 많은 OSD가 동시에 비활성화되었을 때, 이를 "장애(failure)"로 간주하지 않고 "일시적인 문제"로 처리.
      • 불필요한 대규모 데이터 재복제를 방지

Recovery and Cluster Updates

  • cluster map
    • OSD 클러스터 맵은 장애, 복구, 새로운 스토리지 추가 등으로 변경
    • OSD는 fast recovery를 위해 각 PG에 대한 각 Object의 버전 번호와 최근 변경 로그(업데이트 또는 삭제된 Object의 이름 및 버전)를 유지
  • Active OSD가 MON으로부터 클러스터 맵 업데이트를 받으면 자신이 관리 중인 PG를 모두 확인하고 CRUSH 알고리즘을 사용해, 자신이 각 PG에서 Primary 역할을 할지, Replica 역할을 할지 계산.
  • PG membership이 변경되었거나 OSD가 부팅된 경우 해당 PG를 공유하는 다른 OSD들(peer)과 동기화(peering) 과정을 시작.
    • 복제된 PG(replica)의 경우, OSD는 자신이 보유한 해당 PG(replica)의 현재 버전 번호(PG version number)를 Primary OSD에 제공.
    • 반대로, OSD가 해당 PG의 Primary 역할을 맡는 경우, 현재 복제본과 이전 복제본의 PG 버전 번호를 수집.
    • Primary OSD가 최신 PG 상태를 보유하고 있지 않은 경우, 다른 Peer OSD로부터 최근 PG change log 또는 content summary를 받아 최신 상태의 PG 콘텐츠를 결정.
    • Primary OSD는 최종적으로 각 Peer OSD에 증분 로그 업데이트(incremental log update) 또는 전체 내용 요약을 보냄.
    • 이로써 모든 OSD가 동일한 PG 콘텐츠 상태를 알게 됨
    • Primary OSD가 올바른 PG 상태를 확인하고, 이를 복제본 OSD에 공유한 뒤에만, 해당 PG에 대한 I/O 요청 처리가 허용됨.
  • 각 OSD는 background에서 독립적으로 누락된 데이터나 구버전 데이터를 다른 Peer OSD로부터 복구.
    • 구버전 또는 누락된 object 요청 시 요청 처리를 지연시킨 후 누락된 object를 복구 큐(Recovery Queue)의 가장 앞에 배치하여 즉시 동기화

Object Storage with EBOFS

  • ext3와 같은 로컬 파일 시스템을 기반으로 설계된 분산 파일 시스템은 Object Workload에 부적합

    • 기존 kernel interface는 object update가 disk에 안전하게 commit되었는지 확인이 어려움.
    • 게다가, POSIX interface는 데이터와 메타데이터를 원자적으로 업데이트하지 못함.
      • Ceph의 RADOS는 강력한 일관성을 보장하기 위해 데이터와 메타데이터 업데이트가 항상 동기화되어야 함
    • 이를 해결하려면 동기식 쓰기(synchronous writes) 또는 저널링(journaling)을 사용해야 하지만, 이는 지연(latency)과 성능 손실을 초래.
  • Ceph OSD는 EBOFS를 통해 Local Object Storage를 관리

    • 위 커널의 제약을 제거하기 위해, user space에 raw block device와 직접 상호작용하는 새로운 오브젝트 스토리지 인터페이스와 업데이트 방식(update semantics)을 구현.
      • user space approach를 통해 리눅스 VFS(Virtual File System)와 page cache와의 interaction을 피해 오버헤드 제거.
      • 데이터 업데이트는 먼저 메모리 캐시에서 처리하여 빠른 반응 속도를 제공하며, 디스크 쓰기는 비동기로 수행하여 최적화된 I/O 스케줄링을 지원.
      • 이 방식은 업데이트 직렬화와 비동기 디스크 커밋을 분리함으로써 성능, 데이터 일관성, 그리고 안정성을 모두 확보.
    • atomic transactions을 지원
  • EBOFS는 적극적으로 디스크 쓰기를 스케줄링함

    • 대신, 디스크 스케줄러의 I/O 큐를 길게 구성하고, 지속되는 업데이트로 인해 무효화된 I/O작업들을 취소함으로서 디스크 I/O 효율성을 최대한 높임.
    • 스케줄링에 있어 워크로드에 따른 우선순위를 조정한다거나, QoS 보장을 제공할 수 있음.
      • 시스템 전체의 I/O를 관리하는 커널 스케줄러는 특정 워크로드 우선처리를 위한 정책 설정이나 QoS 설정이 어려움
  • EBOFS는 B-tree 서비스로서 디스크에서 오브젝트를 검색하고, 블록 할당을 관리하며, 컬렉션(Placement Group)을 인덱싱함.

    • 블록 할당은 Extent(시작 위치와 길이 pair) 단위로 수행
      • 기존 block list 방식보다 메타데이터를 더 압축
    • 빈 블록(Extent)은 크기별로 그룹화되고, 위치별로 정렬
      • 쓰기 위치 근처의 빈 공간을 빠르게 찾음
      • 관련 데이터와 가까운 위치에 데이터를 배치하여 데이터 지역성(locality)을 유지
      • 장기적으로 조각화(fragmentation)를 최소화
    • Object 별 block allocation 정보를 제외한 모든 메타데이터는 메모리에 유지
      • 메타데이터는 크기가 작아 대규모 볼륨에서도 충분히 메모리에 저장 가능하며, 액세스 속도를 높이고 설계를 단순화 함.
      • 메타데이터 : Object 인덱스, Placement Group 인덱스
  • EBOFS는 Copy-on-Write를 적극적으로 사용

    • 기존 데이터를 수정하지 않고, 항상 디스크의 미할당 영역에 copy한 후 새 데이터를 씀
    • 데이터의 일관성과 안전성을 높임
profile
다시 시작하는 개발자

0개의 댓글