Reading: Ceph: A Scalable, High-Performance Distributed File System

1. Introduction

  • Ceph は peta-byte スケールに対応するための file system(と Object Storage)

  • Object Storage Device(OSD), Metadata Server(MDS)があって、クライアントは中央集権的な MDS とやり取りした後に実際のデータは各 OSD から取得するというモデルがよく採用される。

  • この従来のアーキテクチャでは metadata ワークロードの分散がない、あるいは足りていないのでスケーラビリティが制限され続けてきた。

  • Ceph では metadata へのアクセスをクラスタ全体で分散できるようにしているため、スケーラビリティを劇的に向上させている。

2. System Overview

  • 主に3つのコンポーネントに分けられる。

    • POSIX にほぼ近いインターフェースを提供するクライアント(ライブラリのこと)

    • 実データとメタデータを保存するための OSD クラスタ

    • 名前空間を管理するためのメタデータクラスタ

  • Ceph の主要なゴールは以下。

    • スケーラビリティ

    • パフォーマンス

    • 信頼性

  • Ceph の特徴

    • データとメタデータの分離

      • メタデータの操作(open, rename, etc)は MDS に対する処理。

      • 一方で I/O(reads and writes) は OSD と直接やり取りする。

      • CRUSH と呼ばれる分布関数でオブジェクトを striping する。

    • 動的な分散メタデータ管理

      • Dynamic Subtree Partitioning によって賢くメタデータを MDS 間に分散させる。

    • 信頼できる自律的な分散オブジェクトストレージ

      • OSD クラスタにデータのレプリケーション、故障検知、障害復旧の責務を任せている。

3. Client Operation

  • クライアントの処理はユーザースペースで実行される。FUSE も利用可能。

File I/O and Capabilities

  • ファイルをオープンする場合

    • クライアントは MDS にリクエストを投げる。

    • MDS はファイルシステムをトラバースしてファイル名を inode に変換する。

    • inode と striping 戦略を含む各種メタデータをクライアントに返す。

  • クライアントには capability も返される。capability はどの操作が許可されるかを表すもの。

  • ファイルの実データは striping 戦略によって複数のオブジェクトにマップされる。

    • この時 stripe 番号を記録しておく。

  • file allocation metadata を避けるために、オブジェクト名は file inode 番号と stripe 番号の組み合わせ。

  • オブジェクトのレプリカは CRUSH を使って OSD に割り振られる。

  • あるファイルのどのオフセットへの書き込みも適切な OSD上の適切なオブジェクトに書き込まれる。

3.2 Client Synchronization

  • 書き込みや読み込みが競合したら書き込みを同期するために OSD へ書き込みが終わるまでクライアントはブロックされる。

  • 書き込みがオブジェクトの境界をまたがる場合、オブジェクトに対する排他的なロックが取得される。

  • 同期 IO はパフォーマンスを制限するので、Ceph は global switch で consistency を制御できる。

  • HPC コミュニティによって POSIX の I/O インターフェイスに拡張が加えられているわけだが、Ceph のそのインターフェイスのサブセットを実装している。

  • 最も顕著なものは、O_LAZY で open する時のフラグ指定。

3.3 Namespace Operation

  • MDS への read や update 操作は同期的に適用される。

  • 単純化のために、ロックやリースなどは使わない。

  • 性能が出るように典型的なファイルアクセスパターンに対して(内部的に)専用の処理を実装している。

4. Dynamically Distributed Metadata

  • 各ファイルとディレクトリの metadata は 80 bytes で表現される。

  • オブジェクト名は inode で構成されていて、CRUSH により OSD に分散される。

  • two tiered storage strategy で metadata に関わる I/O を最小化する。

4.1 Metadata Storage

  • short term なストレージ(journal)と long term なストレージを別に管理する。

  • 通常の書き込みはジャーナルに書き込まれる。定期的に long term なストレージにデータを移す。

  • journal へは sequential に書き込む。

  • ディレクトリ内の inode はディレクトリ情報に埋め込まれている。

  • journal への metadata 書き込みとファイルの実データは同じ striping 方法を使って OSD に永続化される。

4.2 Dynamic Subtree Partitioning

  • Ceph の primary-copy caching 戦略によって、単一の権威的な MDS が metadata の更新を直列化する責務を持つ。

  • metadata 以下の2つの戦略がよくある。

    • static subtree ベースの partitioning

      • 動的なワークロードに対応できない。

    • ディレクトリとファイルのmetadataを hash 関数で分散する

      • hash 化することで metadata の locality や prefetch の機会が失なわれる。

  • Ceph の MDS クラスタは dynamic subtree partitioning 戦略を使う。

    • ワークロードに応じて cached metadata をノード群をヒエラルキ的に横断して分散させる。

    • ワークロードを測るために popularity を計測する。

    • 適当なサイズの subtree はワークロードが均等に分散するように migrate される。

    • shared long-term storage と注意深く作られた namespace ロックによって migration は達成される。

    • metadata を転送では、ノード双方に追加の journal entry を書くことで、ノード間の障害があっても壊れない(two-phase commit に似ている)。

  • metadata が複数の MDS にレプリケーションされる時に3つのグループに分割される。

    • security (owner, mode)

    • file (size, mtime)

    • immutable (inode number, ctime, layout)

  • security と file のロックはそれぞれ別の有限状態機械で管理される。

4.3 Traffic Control

  • ディレクトリツリーをパーティショニングしてもホットスポットが発生するのを完全に避けられるわけではない。

  • Ceph は metadata の popularity に関する知識(計測している統計データなど)を使って hotspot を分散させる。

  • 頻繁に読み出されるディレクトリ(open 数が多いなど)は選択的に複数のノードにレプリケーションされる。

  • 非常に大きかったり、頻繁に書き込まれるディレクトリは、その中身をファイル名でハッシュを取ってクラスタ内に分散させる。

  • MDS のレスポンスに権威情報やレプリケーション情報を含めて、クライアントに metadata のパーティショニングについて知識を与える。将来的なクライアントの操作はこの情報を使って directed される。

5. Distributed Object Storage

  • Reliable AUtonomic Distributed Object Store(RADOS)

  • Ceph のクライアントは RADOS を論理上は単一のオブジェクトストアとみなす。

5.1 Data Distribution with CRUSH

  • CRUSH(Controlled Replication Under Scalable Hashing)

  • オブジェクトをストアする OSD は以下の手順で選択される。

    • ハッシュ関数で (inode number, object number) を oid(object id) に変換する。

    • 次に hash(oid) と mask から placement group id(pgid) に変換する。

    • 最後に CRUSH(pgid) を計算することで OSD の一覧を得る。

  • オブジェクトと placement group のマッピングは常に更新され続ける。

  • CRUSH は placement rule を利用して placement group を OSD にマッピングする。

5.2 Replication

  • Lustre は RAIDJ のような仕組みで OSD の信頼性を担保している。

  • RADOS は primary-copy replication の変種を使う。

  • データは placement group 単位でレプリケートされる。n OSD の順序付きリストにマッピングされる。

  • クライアントはすべての書き込みをオブジェクトの属する primary な PG に送りつける。そしたら、その OSD はオブジェクトに新しいバージョン番号を割り振り、データを他の OSD レプリカに転送する。

  • すべてのレプリカが更新をローカル上で完了したら primary OSD にレスポンスを返す。その後 primary はローカルに変更を適用し、クライアントに ack を返す。

  • 読み込みは primary にコントロールされる。

5.3 Data Safety

  • 各レプリカ上で buffer cache に変更が適用された段階でクライアントに ack response を返し、その後各レプリカ上で disk への書き込みが完了した段階で commit response をクライアントに返す仕組み。

5.4 Failure Detection

  • RADOS は同じ PG をシェアするピアを監視する OSD monitor を持つことで、分散監視を実現する。

  • 通常は replication が monitoring を兼ねているが、ピアから通信がしばらく途絶えると明示的に ping を送って死活を確認する。

  • レスポンスを返さない OSD はまず down としてマークされ、すぐに復旧しない場合は out としてマークされる。その時別の OSD が PG に join してデータは再レプリケーションされる。

  • 監視機構は failure reports を集めて transient や systemic な問題を除外する。

  • 監視機構は election、active peer monitoring, short-term leases と two-phase commit を使って一貫性と可用性のあるアクセスを提供する。

5.5 Recovery and Cluster Updates

  • 高速なリカバリのために、OSD は各オブジェクトのバージョン番号と最近の変更ログを各 PG 毎に保持しておく。

  • active な OSD が cluster map の更新を受け取ったときに、ローカルに保存された placment group をイテレートし、どの PG では primary と replica のどちらとして振舞えばよいかを決めるために CRUSH のマッングを再計算する。

  • PG のメンバーシップ更新時、ないし、OSD の起動時に OSD はピアの OSD と通信しなければならない。

    • ある PG で primary な OSD は現在の PG バージョン番号を提供する。

    • primary は replica から PG 番号を集め、もしそれらの PG 番号が自分の PG 番号より進んでいた場合、replica からログを貰う。

    • その後、primary は各 replica にログ更新を通知する。

    • これらの手続きが完了し primary の PG の状態が確定した後になって初めて I/O が許可される。

5.6 Object Storage with EBOFS

  • ext3 がよく使われているが Ceph のワークロードには向いていないので OSD では EBOFS を filesystem に使う。

  • EBOFS は userspace で動作する filesystem で、B-tree ベース。

6 Performance and Scalability Evaluation

6 章以下省略

Comments

comments powered by Disqus