Click here to load reader
Upload
toshihiro-suzuki
View
1.995
Download
1
Embed Size (px)
DESCRIPTION
第2回 Hadoop 輪読会の発表資料
Citation preview
第2回
Hadoop本 輪読会3章 Hadoop分散ファイルシステム
3章 Hadoop分散ファイルシステム
• 分散ファイルシステム- ネットワーク上のマシン群にまたがるストレージ
- ネットワークプログラミングに関するあらゆる複雑性
- ノードの障害に対してもデータの損失を被らない耐久性を持つファイルシステムを作ることは、最も困難な挑戦の一つ
• HDFS(Hadoop Distributed Filesystem)
HDFSの設計
• 得意- 非常に大きなファイル
‣ 数百MB, GB, TB
- ストリーミング型のデータアクセス
‣ 書き込みを1度だけ行い、読み出しを何度も行う処理
- コモディティハードウェア
‣ 高価な高可用性をもったハードウェアは必要ない
‣ 普通に手に入るハードウェアで構成されるクラスタ
HDFSの設計
• 不得意- 低レイテンシのデータアクセス
‣ 高スループットの実現のため、レイテンシを犠牲にしている
- 大量の小さなファイル
‣ 保管できるファイル数はネームノードのメモリ量に制限される
- 複数のライターからの書き込みや、任意のファイルの修正
‣ 1つのライターからのみ書き込むことができる
‣ 書き込みは常にファイルの末尾
HDFSに関する概念
• ブロック- デフォルトで64MB
- メリット
‣ 大きいファイルが作れる
‣ サブシステムが単純になる
‣ レプリケーションと相性がよい
HDFSに関する概念
• ネームノードとデータノード- マスター/ワーカーパターン
- ネームノード(マスター)
- データノード(ワーカー)
HDFSに関する概念
• ネームノード- ファイルシステムのツリーと、ツリー内の全ファイルおよびディレクトリのメタデータを管理(ローカルディスクにイメージ、編集ログ)
- すべてのファイルの全ブロックがどこにあるかを管理(ローカルディスクには保存されない、起動時にデータノード群から再構築)
HDFSに関する概念
• データノード- 実際に、ブロックを保存
- クライアントあるいはネームノードからの要求に応じて、ブロックの読み書きを行う
- 定期的にネームノードに自分が保存しているブロックのリストを報告
HDFSに関する概念
• ネームノードがなければ、ファイルシステムを利用できない
- ネームノードの情報のバックアップ(イメージ, 編集ログ)
- セカンダリネームノード
HDFSに関する概念
• セカンダリネームノード- イメージと編集ログのマージ
NameNode SecondaryNameNode
メモリ ローカルディスク
イメージ
編集ログイメージ
HDFSに関する概念
• セカンダリネームノード- イメージと編集ログのマージ
NameNode SecondaryNameNode
メモリ ローカルディスク
イメージ
編集ログイメージ
open()append()write()
HDFSに関する概念
• セカンダリネームノード- イメージと編集ログのマージ
NameNode SecondaryNameNode
メモリ ローカルディスク
イメージ
編集ログイメージ
open()append()write()
更新
HDFSに関する概念
• セカンダリネームノード- イメージと編集ログのマージ
NameNode SecondaryNameNode
メモリ ローカルディスク
イメージ
編集ログイメージ
open()append()write()
更新 追加
HDFSに関する概念
• セカンダリネームノード- イメージと編集ログのマージ
NameNode SecondaryNameNode
メモリ ローカルディスク
イメージ
編集ログイメージ
HDFSに関する概念
• セカンダリネームノード- イメージと編集ログのマージ
NameNode SecondaryNameNode
メモリ ローカルディスクイメージ
編集ログ
イメージ
HDFSに関する概念
• セカンダリネームノード- イメージと編集ログのマージ
NameNode SecondaryNameNode
メモリ ローカルディスク
イメージ
マージされたイメージ
マージされたイメージ
HDFSに関する概念
• セカンダリネームノード- イメージと編集ログのマージ
NameNode SecondaryNameNode
メモリ ローカルディスク
イメージ
マージされたイメージ
マージされたイメージ
コマンドラインインタフェース
• hadoop fs -copyFromLocal <localsrc> ... <dst>
• hadoop fs -copyToLocal <src> <localdst>
• hadoop fs -ls <path>
• hadoop fs -mkdir <path>
• hadoop fs -help
Hadoopのファイルシステム群
ファイルシステム
URIスキーム java実装
local file org.apache.hadoop.fs.localFileSystem
HDFS hdfs org.apache.hadoop.hdfs.DistributesFileSystem
HFTP hftp org.apache.hadoop.hdfs.HftpFileSystem
HSFTP hsftp org.apache.hadoop.hdfs.HsftpFileSystem
HAR har org.apache.hadoop.fs.HarFileSystem
KFS kfs org.apache.hadoop.fs.kfs.KosmosFileSystem
FTP ftp org.apache.hadoop.fs.ftp.FTPFileSystem
S3(ネイティブ)
s3n org.apache.hadoop.fs.s3native.NativeS3FileSystem
S3(ブロックベース)
s3 org.apache.hadoop.fs.S3FileSystem
•hadoop fs -ls file:///•hadoop fs -ls hdfs:///•hadoop fs -ls hftp:///
インターフェース
• Thrift
• C
- libhdfs
• FUSE(FileSystem in Userspace)
• WebDAV
• その他- HTTP, FTP(まだ、完成していない)
Javaインターフェース
• Hadoop URLからのデータ読み出し
public class URLCat { static { URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory()); }
public static void main(String[] args) throws Exception { InputStream in = null; try { in = new URL(args[0]).openStream(); IOUtils.copyBytes(in, System.out, 4096, false); } finally { IOUtils.closeStream(in); } }}
Javaインターフェース
• FileSystem APIを使ったデータの読み出し
public class FileSystemCat { public static void main(String[] args) throws Exception { String uri = args[0]; Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), conf); InputStream in = null; try { in = fs.open(new Path(uri)); IOUtils.copyBytes(in, System.out, 4096, false); } finally { IOUtils.closeStream(in); } }
Javaインターフェース
• FSDataInputStream
public class FSDataInputStream extends DataInputStream implements Seekable, PositionedReadable {
// 実装は省略}
public interface Seekable { void seek(long pos) throws IOException; long getPos() throws IOException; boolean seekToNewSource(long targetPos) throws IOException;}
Javaインターフェース
• FSDataInputStream
public class FileSystemDoubleCat { public static void main(String[] args) throws Exception { String uri = args[0]; FileSystem fs = FileSystem.get(URI.create(uri), new Configuration()); FSDataInputStream in = null; try { in = fs.open(new Path(uri)); IOUtils.copyBytes(in, System.out, 4096, false); in.seek(0); IOUtils.copyBytes(in, System.out, 4096, false); } finally { IOUtils.closeStream(in); } }}
Javaインターフェース
• FSDataInputStream
public class FSDataInputStream extends DataInputStream implements Seekable, PositionedReadable {
// 実装は省略}
public interface PositionedReadable { int read(long position, byte buffer[], int offset, int length) throws IOException; void readFully(long position, byte buffer[], int offset, int length) throws IOException; void readFully(long position, byte buffer[]) throws IOException;}
Javaインターフェース
• データの書き込み- public FSDataOutputStream create(Path f)
throws IOException
- public FSDataOutputStream append(Path f) throws IOException
Javaインターフェース
• FSDateOutputStream
- FileSystemのcreate(), append()が返す
- シークは許されてない
public class FSDataOutputStream extends DataOutputStream implements Syncable { public long getPos() throws IOException { // 実装は省略 }
// 実装は省略}
Javaインターフェース
• ディレクトリ- public boolean mkdirs(Path f) throws IOException
Javaインターフェース
• ファイルのメタデータFileStatus status = fs.getFileStatus(new Path("hdfs://localhost/hogehoge"));
status.isDir(); // ディレクトリかどうかstatus.getLen(); // ファイルサイズstatus.getModificationTime(); // 更新時間status.getReplication(); // レプリケーションサイズstatus.getBlockSize(); // ブロックサイズ(デフォルト64MB)status.getOwner(); // オーナstatus.getGroup(); // グループstatus.getPermission().toString(); // パーミッション情報
Javaインターフェース
• ファイルのリスト- public FileStatus[] listStatus(Path f) throws IOException;
- public FileStatus[] listStatus(Path f, PathFilter filter) throws IOException;
- public FileStatus[] listStatus(Path[] files) throws IOException;
- public FileStatus[] listStatus(Path[] files, PathFilter filter) throws IOException;
Javaインターフェース
• ファイルのリストpublic class ListStatus { public static void main(String[] args) throws Exception { String uri = args[0]; Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), conf); Path[] paths = new Path[args.length]; for (int i = 0; i < paths.length; i++) { paths[i] = new Path(args[i]); } FileStatus[] status = fs.listStatus(paths); for (FileStatus stat : status) { System.out.println(stat.getPath().toUri().getPath()); } }}
Javaインターフェース
• ファイルパターン- public FileStatus[] globStatus(Path pathPattern) throws IOException
- public FileStatus[] globStatus(Path pathPattern, PathFilter filter) throws IOException
Javaインターフェース
• ファイルパターン
グロブ 名称 マッチする対象* アスタリスク 0個以上の文字
? クエスチョンマーク 1文字
[ab] 文字クラス 集合{a,b}のいずれかに1文字
[^ab] 否定文字クラス 集合{a,b}に含まれない1文字
[a-b] 文字範囲 集合{a,b}内の1文字(aとbを含む)。aは辞書の並び順でbに等しいか、それより前でなければならない
[^a-b] 否定文字範囲 集合{a,b}に含まれない1文字(aとbもマッチしない)。aは辞書の並び順でb
に等しいか、それより前でなければならない
{a,b} 選択 aあるいはb
¥c エスケープ文字 cがメタ文字の場合、文字c
Javaインターフェース
• パスフィルタ
public interface PathFilter { boolean accept(Path path);}
Javaインターフェース
• パスフィルタ 例public class RegexExcludePathFilter implements PathFilter {
private final String regex; public RegexExcludePathFilter(String regex) { this.regex = regex; } @Override public boolean accept(Path path) { return !path.toString().matches(regex); }}
fs.globStatus(new Path("/2007/*/*"), new RegexExcludePathFilter("^.*/2007/12/31$"));
Javaインターフェース
• データの削除- public boolean delete(Path f, boolean recursive)
throws IOException;
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
close()
block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
次からは接続しない
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
次からは接続しない
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
報告
クライアント
データフロー
• ファイル読み込みの解剖学
HDFSクライアント DistributedFileSystem
FSDataInputStream
NameNode
DateNode1 DateNode2 DateNode3 DateNode4
block1 block1
block2 block3
block3 block2
block4block4
open(new Path(“/aaa.txt”))
“/aaa.txt”のブロック情報の取得(先頭の数ブロック)
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4 aaa.txt : block1, block2. block3, block4
block1 : DataNode1, DataNode3block2 : DataNode3, DataNode4block3 : DataNode2, DataNode3block4 : DataNode1, DataNode2
read()
報告
クライアント
データフロー
• ファイル読み込みの解剖学- クライアントに対して透過的
- データのトラフィックはクラスタ内の全データノードに分散される
- クライアント数の増加に連れて、ネームノードがボトルネックになることはない
データフロー
• ネットワークの近さについて- ネットワークをツリー構造で表し、2つのノード間の距離をそれらのノードの最も近い共通祖先への距離の合計
- 設定の詳細は「9.1.1 ネットワークトポロジ」
- デフォルトはフラット
距離(/d1/r1/n1, /d1/r1/n1) = 0
距離(/d1/r1/n1, /d1/r1/n2) = 2
距離(/d1/r1/n1, /d1/r2/n3) = 4
距離(/d1/r1/n1, /d2/r3/n4) = 6
d1 d2
r1 r2 r3
n1 n2 n3 n4
FSDataOutputStream
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
クライアント
FSDataOutputStream
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
クライアント
FSDataOutputStream
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”)) 作成クライアント
FSDataOutputStream
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
作成クライアント
FSDataOutputStream
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
block1 : DataNode1, DataNode2, DataNode3
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
block1 : DataNode1, DataNode2, DataNode3
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
block1 : DataNode1, DataNode2, DataNode3
block1
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
block1 : DataNode1, DataNode2, DataNode3
block1 block1
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
block1 : DataNode1, DataNode2, DataNode3
block1 block1 block1
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
block1 : DataNode1, DataNode2, DataNode3
block1 block1 block1
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
block1 : DataNode1, DataNode2, DataNode3
block1 block1 block1
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
block1 : DataNode1, DataNode2, DataNode3
block1 block1 block1
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
block1 : DataNode1, DataNode2, DataNode3
block1 block1 block1
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
block1 : DataNode1, DataNode2, DataNode3
block1 block1 block1
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
block1 : DataNode1, DataNode2, DataNode3
block1 block1 block1
close()
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
既にファイルが存在しないかパーミッションのチェック
write()
DataStreamer
block1 : DataNode1, DataNode2, DataNode3
block1 block1 block1
close()
作成
完了
クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1 block1
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1 block1
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1 block1
作成クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1 block1
作成
block2
クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1 block1
作成
block2
クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1 block1
作成
block2
クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1 block1
作成
block2 block2
クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1 block1
作成
block2 block2
クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1 block1
作成
block2 block2
クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1 block1
作成
block2 block2
クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1 block1
作成
block2 block2
クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1
作成
block2 block2
クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1
作成
block2 block2
クライアント
ackキュー
FSDataOutputStream
データキュー
データフロー
• ファイル書き込みの解剖学
HDFSクライアント DistributedFileSystem NameNode
DateNode1 DateNode2 DateNode3
create(new Path(“/aaa.txt”))
write()
DataStreamer
block1
作成
block2 block2block2
クライアント
データフロー
• ファイル書き込みの解剖学- 同時に複数台で障害を起こすと、dfs.replication.min(デフォルトは1)で指定された、個数が書き込まれる限り、書き込みは成功
- 目標の複製数(dfs.replicationで指定された数、デフォルトは3)に到達するまで、非同期的にクラスタ上に複製されていく
- クライアントに対して透過的
データフロー
• レプリカの配置1. クライアントと同じノード(クライアントがクラスタ外ならランダム)
2. 1つ目のレプリカとは異なるラックをランダムに選んでその中のノード
3. 2つ目のレプリカと同じラックの中の別のノード
4. それ以降はランダム(同じラックに偏らないように)
データフロー
• 一貫性モデル- ファイルを作成すると、そのファイルはファイルシステムの名前空間内で見えるようになる
- ファイルに書き込まれた内容は、ストリームがフラッシュされたあとでも見えるとは限らない
fs.create(new Path("p"));
OutputStream out = fs.create(new Path("p"));out.write("content".getBytes("UTF-8"));out.flush();
データフロー
• 一貫性モデル- FSDataOutputStreamのsync()が呼ばれたあとは、見えるようになる
- sync()はclose()時にも呼ばれる
FSDataOutputStream out = fs.create(new Path("p"));out.write("content".getBytes("UTF-8"));out.flush();out.sync();
データフロー
• 一貫性モデル- アプリケーションの設計への影響
‣ sync()を呼ばないなら、障害時に最大1ブロックのデータが失われる
‣ これを許容できないなら、適切なタイミングでsync()を呼んでおくべき
‣ sync()は過度の負荷にはならないが、オーバヘッドは存在するので注意
distcpによる並列コピー
• 2つのHDFS間でのデータ転送
- hadoop distcp hdfs://namenode1/foo hdfs://namenode2/bar
- hadoop distcp -overwrite hdfs://namenode1/foo hdfs://namenode2/bar/foo
- hadoop distcp -update hdfs://namenode1/foo hdfs://namenode2/bar/foo
• MapReduceのジョブとして実装
- 各マップは最低256MBをコピーする(1GBのファイルには4つのマップ)
- ファイルが非常に大きい場合はmap数を制限(ネットワーク帯域、クラスタの利用度合い)
- デフォルトのmap数は、1ノード(tasktraker)につき最大20map
Hadoopアーカイブ
• 小さいファイル群を効率よく保存するための仕組み
• HAR
• hadoop archive -archiveName files.har /my/files /my
Hadoopアーカイブ
• 制限事項- アーカイブを作成するとき、アーカイブを作成しようとしているファイル群の同じだけのディスク容量が必要(アーカイブ圧縮はサポートされてない)
- アーカイブはいったん作成されたら修正できない
- HARファイルはMapReduceへの入力として使えるが、依然として大量の小さいファイルの処理は非効率(「7.2.1.4 小さいファイル郡とCombineFileInputFormat」)
まとめ
• HDFS
- ブロック
- ネームノードとデータノード
- いろいろなインターフェース
- 読み込みと書き込みの詳細
• distcp
• HAR
• ご清聴ありがとうございました
• 質疑応答