HDFS上のファイルに追記する

18日目です
HDFSは当初Write Onceなファイルシステムでした。これは設計思想によるものです。Apache HDFSのドキュメントから引用します。

HDFS applications need a write-once-read-many access model for files. A file once created, written, and closed need not be changed. This assumption simplifies data coherency issues and enables high throughput data access. A Map/Reduce application or a web crawler application fits perfectly with this model. There is a plan to support appending-writes to files in the future.

ここには将来的に追記をサポート云々と書いてありますが、追記の機能はhadoop 0.20-appendブランチで開発が進められ、既にメインラインに取り込まれています。

HDFSにhadoop fsで追記する

今までHDFSのファイルに追記するためには、Javaでプログラムを書くしかありませんでした(ひょっとすると別の方法があるのかもしれませんが、、、知りません)。最新のHadoop 2.2では、hdfsのシェルコマンド(hadoop fs または hdfs dfs)からappendToFile を引数に指定して、HDFS上にある既存のファイルに追記できるようになっています。
http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/FileSystemShell.html#appendToFile

appendToFileを使ってみる

CDH5 beta1はHadoop 2.2.Xベースになっています。以前用意したCDH5b1の環境に2つのテキストファイルを用意して、簡単に追記機能をテストしてみました。

ディレクトリ作成
[training@huetest ~]$ hdfs dfs -mkdir appendtest
ファイルをコピー
[training@huetest ~]$ hadoop fs -put data1.txt appendtest
表示
[training@huetest ~]$ hdfs dfs -cat appendtest/data1.txt
This is a dog.
念のためHDFSのブロックを確認。
[training@huetest ~]$ hdfs fsck /user/training/appendtest/data1.txt -files -blocks
Connecting to namenode via http://localhost:50070
FSCK started by training (auth:SIMPLE) from /127.0.0.1 for path /user/training/appendtest/data1.txt at Mon Dec 16 11:48:28 EST 2013
/user/training/appendtest/data1.txt 15 bytes, 1 block(s):  OK
0. BP-657221560-127.0.0.1-1383040674176:blk_1073742136_1316 len=15 repl=1
Status: HEALTHY
 Total size:	15 B
 Total dirs:	0
 Total files:	1
 Total symlinks:		0
 Total blocks (validated):	1 (avg. block size 15 B)
 Minimally replicated blocks:	1 (100.0 %)
 Over-replicated blocks:	0 (0.0 %)
 Under-replicated blocks:	0 (0.0 %)
 Mis-replicated blocks:		0 (0.0 %)
 Default replication factor:	1
 Average block replication:	1.0
 Corrupt blocks:		0
 Missing replicas:		0 (0.0 %)
 Number of data-nodes:		1
 Number of racks:		1
FSCK ended at Mon Dec 16 11:48:28 EST 2013 in 1 milliseconds
The filesystem under path '/user/training/appendtest/data1.txt' is HEALTHY
ファイルを追記
[training@huetest ~]$ hdfs dfs -appendToFile data2.txt appendtest/data1.txt
結果を表示
[training@huetest ~]$ hdfs dfs -cat appendtest/data1.txt
This is a dog.
That is a cat.
ブロックを確認
[training@huetest ~]$ hdfs fsck /user/training/appendtest/data1.txt -files -blocks
Connecting to namenode via http://localhost:50070
FSCK started by training (auth:SIMPLE) from /127.0.0.1 for path /user/training/appendtest/data1.txt at Mon Dec 16 11:49:16 EST 2013
/user/training/appendtest/data1.txt 30 bytes, 1 block(s):  OK
0. BP-657221560-127.0.0.1-1383040674176:blk_1073742136_1317 len=30 repl=1
Status: HEALTHY
 Total size:	30 B
 Total dirs:	0
 Total files:	1
 Total symlinks:		0
 Total blocks (validated):	1 (avg. block size 30 B)
 Minimally replicated blocks:	1 (100.0 %)
 Over-replicated blocks:	0 (0.0 %)
 Under-replicated blocks:	0 (0.0 %)
 Mis-replicated blocks:		0 (0.0 %)
 Default replication factor:	1
 Average block replication:	1.0
 Corrupt blocks:		0
 Missing replicas:		0 (0.0 %)
 Number of data-nodes:		1
 Number of racks:		1
FSCK ended at Mon Dec 16 11:49:16 EST 2013 in 1 milliseconds
The filesystem under path '/user/training/appendtest/data1.txt' is HEALTHY
[training@huetest ~]$

このように簡単に追記できるのは便利ですね。
なお、赤字にあるように、追記してもblock idは変わっていませんが、タイムスタンプ(と内容)は変更されています。
もちろん、追記してディスク上に書き込まれるデータは、デバイスに書き込まれる時に隣接しない可能性があります。パフォーマンスの観点から言うと隣接している方が望ましいわけですが、このあたりは利便性とのトレードオフになりますね。

コメント