HDFS Snapshot + distcp と MapR-FS Volume Mirroring の違い

MapR は HDFS の代わりに MapR-FS を使用している Hadoop ディストリビューションです。性能の向上信頼性の向上ランダムリードライト可能なNFSNoSQL データベースとの統合メッセージングキューとの統合、・・・と MapR-FS のメリットは挙げればきりがないのですが、HDFS API はそのまま利用できるため、すべての Hadoop アプリケーションやライブラリは違いを意識することなく動作します。

さて、Hadoop クラスタを運用する際に、データ更新を行う業務アプリケーションと、参照がメインの分析アプリケーション間で同じデータを共有したい、というケースはよくあると思います。ただし、分析アプリはデータセットの特定の時点の一貫性のあるスナップショットに対して処理を行うべきであるため、任意の時点で更新が発生する業務アプリのデータセットにそのままアクセスするわけにはいきません。また、分析アプリが業務アプリと同時に動作した場合、負荷の増大により業務アプリの処理時間に影響を与えてしまうリスクもあります。

このような場合に、 Hadoop では特定のディレクトリのスナップショットを取得する HDFS Snapshot 機能と、分散データコピーツール distcp を使い、物理的なコピーをクラスタ内、もしくは別クラスタに作成し、特定の時点のスナップショットの複製に対してアクセスを行うことで、上記の課題を解決する方法があります。

しかし MapR にはこれと同じことをより簡単に、より効率良く行なうための Volume Mirroring 機能があります。しかもこの機能は MapR の 2011 年の最初のリリースから存在しており、安定して運用に利用されてきた実績があります。

以下では、それぞれの動作の違いについて比較してみましょう。

HDFS Snapshot + distcp の場合

手順の詳細は上記の記事を見ていただければと思いますが、同じ例を使って説明します。まず、source ディレクトリに Data.txt が存在します。

f:id:nagixx:20160410152218j:plain

hdfs コマンドで source ディレクトリのスナップショットを作ります。 

f:id:nagixx:20160410152407j:plain

distcp ツールでスナップショット s1 を target ディレクトリにコピーします。このコマンドは MapReduce ジョブを起動し、クラスタ内で並列にデータコピーが行われます。

f:id:nagixx:20160410152516j:plain

hdfs コマンドで target ディレクトリのスナップショットを作ります。これで 1 世代目のスナップショットの複製が全体コピーで作成されました。

f:id:nagixx:20160410152846j:plain

次に source ディレクトリに Data2.txt が更新データとして書き込まれました。

f:id:nagixx:20160410153010j:plain

hdfs コマンドで source ディレクトリの 2 世代目のスナップショットを作ります。

f:id:nagixx:20160410153317j:plain

distcp ツールでコピーを行いますが、今度はスナップショット s1 と s2 の内容を比較し、ファイル間で更新があったものだけの差分コピーが行われます。

f:id:nagixx:20160410153449j:plain

hdfs コマンドで target ディレクトリのスナップショットを作ります。これで 2 世代目のスナップショットの複製が差分コピーで作成されました。3 世代目以降はこれの繰り返しです。

f:id:nagixx:20160410153802j:plain

MapR-FS Volume Mirroring の場合

上記のようなデータの差分更新のサイクルを回す場合、MapR-FS では Volume という論理的な管理単位を作成しておき、ファイルシステム上に配置しておくことで運用をシンプルにできます。

Volume Mirroring 機能では、コピーの単位は Volume 全体ですので、source 側、mirror 側それぞれにあらかじめ Volume を作成しておきます。Volume を作成するには次の管理コマンドを実行します。mirror 側には <source ボリューム名>@<source クラスタ名> の形でコピー元となる Volume を指定します。

$ maprcli volume create -name source -path /user/hadoop/source
$ maprcli volume create -name target -path /user/hadoop/target -source source@demo.mapr.com -type mirror

先ほどの例と同様に、はじめに source ディレクトリに Data.txt が存在します。

f:id:nagixx:20160410154632j:plain

さて、スナップショットを取りたいタイミングで、MapR の場合は次のコマンド 1 つを実行するだけで、Mirror Volume にスナップショットのコピーが作られるところまで完了します。シンプルですね。

$ maprcli volume mirror start -name target

内部では、まず source 側では一時的なスナップショット、target 側ではタイムスタンプのついたスナップショットが同時に作成されます。その後、source の一時的なスナップショットの内容が target ボリュームにコピーされます。ここでのポイントは、コピーはバックグラウンドで非同期に行われること、コピー処理は MapReduce を起動せず、MapR-FS プロセスが行うこと、target 側ではコピー途中のファイルは見えず、完了した時点で初めてアクセスできるようになることです。コピー完了時に、source 側の一時的なスナップショットは削除されます。

f:id:nagixx:20160410160242j:plain

次に source ディレクトリに Data2.txt が更新データとして書き込まれました。

f:id:nagixx:20160410172243j:plain

2 世代目のスナップショットを作成する場合も、1 世代目とまったく同じコマンドを実行します。シンプルですね。

$ maprcli volume mirror start -name target

両方の Volume 内にスナップショットが作られるところまでは同じですが、今度は前回のコピー時から差分のあったデータだけをコピーします。HDFS ではファイル単位でしか差分を比較していませんが、MapR-FS では 8KB のデータブロック単位で更新履歴を管理しているため、実際に変更のあったファイルの一部分のみのコピーが行われます。

第 3 世代以降もこれの繰り返しです。

f:id:nagixx:20160410161843j:plain

さらに、この Mirroring のコピーのタイミングはスケジューリング設定によって完全に自動化できるため(target 側に残るスナップショットの有効期限も設定できる)、マニュアル操作不要の運用が行えます。

MapR-FS だと何がいいのか

まとめると、MapR-FS Volume Mirroring では下記のようなメリットがあり、運用上の複数の課題の解決に役立ちます。

  • 運用に必要な手順が少ないため、運用設計及び実行の負担が減る
    • オペレーションミスのリスクも減らせる
  • HDFS + MapReduce という 2 つのレイヤにまたがる処理ではなく、MapR-FS で完結する処理であるためシンプルで効率的
    • コピーで MapReduce ジョブが起動しないため、クラスタのリソースの消費を最低限に押さえられる
    • 他の業務のアプリケーションへの影響が少ない
    • 障害時の内部的な挙動もシンプルになりリスクを減らせる
  • MapR-FS の粒度の細かいデータブロック管理を最大限に活用し、短時間でコピーを完了
    • 8KBデータブロック単位の差分管理
    • MapR-FS の圧縮、チェックサムが適用された状態で信頼性が高く効率の良いコピーが可能
  • アトミックな操作で一貫性のあるスナップショットを利用可能
    • HDFS のスナップショットは NameNode 上のメタデータを利用したイメージの取得であるため、構造上データそのものとの完全な一貫性が保証できない。一方、MapR-FS ではデータとメタデータが同期された一貫性のあるスナップショットを取得できる
    • MapR-FS Volume Mirroring のコピーはアトミックな動作であるため、バックグラウンドでコピー処理実行中でも、source 側、target 側双方で Point-in-Time の一貫性のあるデータセットへのアクセスができる