HDFSの新しい機能を確認 (5) – HDFSキャッシング

Hadoop 2.3.0 以降には「HDFSキャッシング」と呼ばれる、HDFSにキャッシュ機構が搭載されています。(参考: HDFSが高速に?キャッシュメカニズムの追加
さっそく手元のCDH5の環境で試してみました。Centraized Cache Management in HDFS

概要

※ここから上記のドキュメントを概要を抜粋してみます(間違いを発見した方はご指摘下さい)
HDFSの中央キャッシュ管理は、ユーザが明示的に指定したパスを、HDFSによって明示的にキャッシュする仕組みです。ネームノードはブロックをディスクに持つデータノードと通信して、そのブロックを「オフピーク (off-heap)」キャッシュにキャッシュします。
オフピークキャッシュは各データノードにある、JVMのVMヒープ対象外のメモリ領域です。ユーザーがコマンドからキャッシュに登録するパスを指定することにより、ブロックがこの領域にキャッシュされます。

hdfs_caching1hdfs_caching2登録の流れ

全てのデータノードのキャッシュの管理はネームノードで行われます。一旦キャッシュに登録されれば、以降のアクセスの際にはディスクから読み出す必要がなくなります。また、読み出す際に新しいAPIを使用することで、ゼロコピーでオーバーヘッドなしに読み出すことができます。(DISK->OSのページキャッシュ->mmap()かな?)キャッシュされるブロックのレプリカ数も指定できます(詳細はドキュメントをご覧下さい)
ネームノードは各データノードから「キャッシュレポート」を定期的に受け取ります。ブロックレポートみたいなものですね。また、ネームノードはデータノードとのハートビートを用いてキャッシュの管理(追加と削除)を行うようです。
HDFSキャッシングのアーキテクチャ

cachingアーキテクチャの図(ドキュメントから引用)

結果、HDFSから繰り返し読み出すようなユースケース(Hiveでジョインに使うファクトテーブルなど)では、ディスクアクセスが最初の一回だけになり効果的ですね。

HDFSキャッシングを使ってみる

それでは実際に試してみましょう。キャッシュの操作は hdfs cacheadmin コマンドで行います。最初に Cache Pool を作成し、作成した Pool にCache Directive 操作でパスを指定します。

プールの作成

hdfs cacheadmin -addpool <プール名>  -owner <所有者> -group <グループ> -mode <mode>] [-limit <limit>] [-maxTtl <maxTtl>]

プールの作成は管理者権限が必要です。
[code]
kawasaki@hadoop11:~$ hdfs cacheadmin -addPool testpool -owner kawasaki -group kawasaki
AccessControlException: Access denied for user kawasaki. Superuser privilege is required
kawasaki@hadoop11:~$ sudo -u hdfs hdfs cacheadmin -addPool testpool -owner kawasaki -group kawasaki
Successfully added cache pool testpool.
[/code]

プールの確認

hdfs cacheadmin -listPools [-stats]

プールの状態を確認することができます。
[code]
kawasaki@hadoop11:~$ hdfs cacheadmin -listPools -stats
Found 1 result.
NAME OWNER GROUP MODE LIMIT MAXTTL BYTES_NEEDED BYTES_CACHED BYTES_OVERLIMIT FILES_NEEDED FILES_CACHED
testpool kawasaki kawasaki rwxr-xr-x unlimited never 0 0 0 0 0
[/code]

キャッシュの確認

hdfs cacheadmin -listDirectives [-stats]

キャッシュの状態を確認することができます。この時点ではプールの作成しかしていないので、何も入っていないですね。
[code]
kawasaki@hadoop11:~$ hdfs cacheadmin -listDirectives -stats
Found 0 entries
[/code]

キャッシュに追加する

hdfs cacheadmin -addDirective -path <path> -pool <pool-name> [-force] [-replication <replication>] [-ttl <time-to-live>]

これで指定したプールに追加します。一覧すると追加されていることがわかりますね。
[code]
kawasaki@hadoop11:~$ hdfs cacheadmin -addDirective -path dir1/bigfile -pool testpool -force -replication 3
Added cache directive 1
kawasaki@hadoop11:~$ hdfs cacheadmin -listDirectives -statsFound 1 entry
ID POOL REPL EXPIRY PATH BYTES_NEEDED BYTES_CACHED FILES_NEEDED FILES_CACHED
1 testpool 3 never /user/kawasaki/dir1/bigfile 225865965 0 1 0
[/code]
最初はキャッシュされていなかったようですが、ファイルを読み書きしたところキャッシュされたようです。
[code]
kawasaki@hadoop11:~$ hadoop fs -get dir1/bigfile xxx
kawasaki@hadoop11:~$ hdfs cacheadmin -listDirectives -stats
Found 1 entry
ID POOL REPL EXPIRY PATH BYTES_NEEDED BYTES_CACHED FILES_NEEDED FILES_CACHED
1 testpool 3 never /user/kawasaki/dir1/bigfile 225865965 225865965 1 1
[/code]
続いてほかのファイルも追加してみましょう。
[code]
kawasaki@hadoop11:~$ hdfs cacheadmin -addDirective -path dir1/bigfile2 -pool testpool -force -replication 3
Added cache directive 2
kawasaki@hadoop11:~$ hdfs cacheadmin -listPools -statsFound 1 result.
NAME OWNER GROUP MODE LIMIT MAXTTL BYTES_NEEDED BYTES_CACHED BYTES_OVERLIMIT FILES_NEEDED FILES_CACHED
testpool kawasaki kawasaki rwxr-xr-x unlimited never 451731930 225865965 0 2 1
kawasaki@hadoop11:~$ hdfs cacheadmin -listDirectives -statsFound 2 entries
ID POOL REPL EXPIRY PATH BYTES_NEEDED BYTES_CACHED FILES_NEEDED FILES_CACHED
1 testpool 3 never /user/kawasaki/dir1/bigfile 225865965 225865965 1 1
2 testpool 3 never /user/kawasaki/dir1/bigfile2 225865965 0 1 0
[/code]
TTL(存在時間)も指定できます。
[code]
kawasaki@hadoop11:~$ hdfs cacheadmin -addDirective -path dir1/bigfile3 -replication 3 -ttl 30m
You must specify a pool name with -pool.
kawasaki@hadoop11:~$ hdfs cacheadmin -addDirective -path dir1/bigfile3 -replication 3 -pool testpool -ttl 30m
Added cache directive 3
kawasaki@hadoop11:~$ hdfs cacheadmin -listDirectives -statsFound 3 entries
ID POOL REPL EXPIRY PATH BYTES_NEEDED BYTES_CACHED FILES_NEEDED FILES_CACHED
1 testpool 3 never /user/kawasaki/dir1/bigfile 225865965 225865965 1 1
2 testpool 3 never /user/kawasaki/dir1/bigfile2 225865965 225865965 1 1
3 testpool 3 2014-04-11T02:52:40+0000 /user/kawasaki/dir1/bigfile3 225865965 225865965 1 1
[/code]
上記の例では、4/11 02:52:40 になると消えるはずですね。
[code]
kawasaki@hadoop11:~$ date
Fri Apr 11 02:52:32 UTC 2014
kawasaki@hadoop11:~$ hdfs cacheadmin -listDirectives
Found 3 entries
ID POOL REPL EXPIRY PATH
1 testpool 3 never /user/kawasaki/dir1/bigfile
2 testpool 3 never /user/kawasaki/dir1/bigfile2
3 testpool 3 2014-04-11T02:52:40+0000 /user/kawasaki/dir1/bigfile3
kawasaki@hadoop11:~$ hdfs cacheadmin -listDirectives -stats
Found 3 entries
ID POOL REPL EXPIRY PATH BYTES_NEEDED BYTES_CACHED FILES_NEEDED FILES_CACHED
1 testpool 3 never /user/kawasaki/dir1/bigfile 225865965 225865965 1 1
2 testpool 3 never /user/kawasaki/dir1/bigfile2 225865965 225865965 1 1
3 testpool 3 2014-04-11T02:52:40+0000 /user/kawasaki/dir1/bigfile3 0 0 0 0
[/code]
時間が経過し、bigfile3が削除されました。(一覧には出ていますが、CACHEDがゼロになっている)
ほかの操作コマンドはドキュメントをご覧下さい。

コメント