HDFS(Hadoop Distributed File System)とは

(2017-08-14)

HDFSとは

Hadoopの分散ファイルシステム。 Hadoopの抽象化されたファイルシステム実装の一つで、他の実装にはLocal fileやS3などがある。 データのサイズが大きい場合に特に問題になるディスクI/Oを分散させ、 読み書きする最小の単位であるブロックサイズを大きくしシークのコストを減らすことで スループットを高めている。 ディスクI/Oがどれくらい遅いかというと、 シークがデータセンター内での往復の通信の20倍(10ms)、 1MBの読み込みが40倍の時間(20ms)かかる

一方、小さなデータに低レイテンシでアクセスするというのは得意でなく、 また、1ファイルあたり150バイトのメタデータがNameNodeのメモリ上に乗っかるため大量のファイルを扱うのは大変。 あとデータは追記しかできない。

NameNodeとDataNode

クラスタの中にはおおよそ2種類のノードがあって、 ブロックがあるいくらかのDataNodeと、

  • ファイルの階層とメタデータ
  • どのDataNodeにそのファイルのブロックがあるか

の情報が含まれる

  • fsimage(メタデータのスナップショット)
  • edit log(fsimageに含まれていない変更ログ)

を保存する、名前空間に単一のNameNodeがある。 もう一つSecondary NameNodeというのがあって、これはedit logが大きくならないよう 定期的にedit logをfsimageにマージするもの。

NameNodeが機能停止すると読み書きできなくなってしまうので、 新しいNameNodeを立てる必要がある。 その際fsimageにedit logを適用して状態を復元するため これらのファイルを別のファイルシステムにバックアップなどして失われないようにする。

巨大なクラスタだとNameNodeを立ち上げるのに30分以上かかることもあるため、 Secondary NameNodeの代わりにStandby NameNodeを立ててHigh Availabilityにすることもできる。 Standby NameNodeはNameNodeと共有ストレージでedit logを共有し、最新の状態がメモリ上に乗っているので NameNodeが死んだと判断されてから数十秒ほどで切り替えることができる。

書き込みと読み込み

書き込み

ファイルシステムがNameNodeとやりとりして、ファイルが存在しているか、パーミッションがあるかを確認し、問題なければFSDataOutputStreamをクライアントに返す。 書き込むデータはdata queueにまず入って、 どのDataNodeに書き込むかはDataStreamerというのがNameNodeとやりとりして決める。 レプリカの設定数分DataNodeが選ばれ、順に書き込まれるようDataNode間でパイプラインを作る。 正常に書き込まれたDetaNodeからはack packetが返ってくるのでこれはack queryに入れて 全て正しく書き込まれたことが確認できたら消す。 失敗したDataNodeがあったら、そこに中途半端に書き込まれた分を復活したら消すようにして、パイプラインから除き 新しいパイプラインを作る。

読み込み

ファイルシステムがNameNodeにファイルのブロックがどこにあるかを聞く。 NameNodeは、ブロックがあるDataNodeをクライアントからネットワークトポロジ的に近い順にソートしてアドレスを返す。 ファイルシステムはそのアドレスが含まれたFSDataInputStreamをクライアントに返して、クライアントが順にreadしていく。

SingleNode Clusterで動かす

$ yum --enablerepo=epel -y install pdsh
$ echo $JAVA_HOME
/usr/lib/jvm/jre
$ wget http://ftp.jaist.ac.jp/pub/apache/hadoop/common/hadoop-2.7.3/hadoop-2.7.3.tar.gz
$ tar xvzf hadoop-2.7.3.tar.gz 
$ cd hadoop-2.7.3
$ bin/hadoop version
Hadoop 2.7.3

デフォルトのファイルシステムをHDFSにしてレプリカを1にする。

$ vi etc/hadoop/core-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
...
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://localhost:9000</value>
    </property>
</configuration>

$ vi etc/hadoop/hdfs-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
...
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
</configuration>

Hadoopデーモンを起動/終了させるためにsshできるようにする。

$ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
$ chmod 0600 ~/.ssh/authorized_keys
$ ssh localhost

起動。

$ bin/hdfs namenode -format
$ sbin/start-dfs.sh
localhost: starting namenode, ...
localhost: starting datanode, ...
0.0.0.0: starting secondarynamenode, ...

ディレクトリやファイルを作成して参照する。

$ bin/hdfs dfs -mkdir /home
$ bin/hdfs dfs -mkdir /user/ec2-user
$ echo 'aaaaa' > hoge
$ bin/hdfs dfs -put hoge ./
$ bin/hdfs dfs -put hoge ./
put: `hoge': File exists

$ bin/hdfs dfs -appendToFile hoge hoge
$ bin/hdfs dfs -ls ./
Found 1 items
-rw-r--r--   1 ec2-user supergroup         12 2017-08-14 13:44 hoge

$ bin/hdfs dfs -cat hoge
aaaaa
aaaaa

Filesystem check utilityを実行する。

$ bin/hdfs fsck ./ -files -blocks
Connecting to namenode via http://localhost:50070/fsck?ugi=ec2-user&files=1&blocks=1&path=%2Fuser%2Fec2-user
FSCK started by ec2-user (auth:SIMPLE) from /127.0.0.1 for path /user/ec2-user at Mon Aug 14 13:44:48 UTC 2017
/user/ec2-user <dir>
/user/ec2-user/hoge 12 bytes, 1 block(s):  OK
0. BP-478671077-172.31.3.159-1502715364675:blk_1073741825_1002 len=12 repl=1

Status: HEALTHY
 Total size:	12 B
 Total dirs:	1
 Total files:	1
 Total symlinks:		0
 Total blocks (validated):	1 (avg. block size 12 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 Aug 14 13:44:48 UTC 2017 in 2 milliseconds

参考

Hadoop: The Definitive Guide, 4th Edition

A Guide to Checkpointing in Hadoop – Cloudera Engineering Blog