HDFS(Hadoop Distributed FIle System)
- 易于扩展的分布式文件系统
- 运行在大量普通廉价的机器上,提供容错机制
- 为大量的用户提供性能不错的文件存取服务
NameNode
- 负责管理文件系统的名字空间以及客户端对文件的访问
- namenode负责文件元数据的操作,datanode负责处理文件内容的读写请求,跟文件内容相关的数据流不经过namenode,只会询问namenode请求的内容和哪个datanode相关联,否则namenode会成为系统的瓶颈。
- 副本存放在哪些datanode上由namenode进行控制(可以通过hdfs -balancer命令,实际中通过多个因素进行控制),根据全局情况作出放置决定,读取文件时,namenode尽量让用户读取最近的副本,降低带块消耗和读取时延。
- namenode全权管理数据块的复制,他周期性的从集群中的每个datanode接受心跳信号和块状态报告。接收到心跳信号意味着datanode结点工作正常。块状态报告包括了一个该datanode上所有数据块的列表。
DataNode
- 一个数据块在DataNode以文件 存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,数据块的校验和,以及时间戳。
- DataNode启动后向namenode注册,通过后,周期性(1小时)的向namenode上报所有的块信息。
- 心跳时每3秒一次,心跳返回结果带有namenode给该datanode的命令,如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟(可配置)没有收到某个datanode的心跳,则认为该结点不可用。
- 集群运行中可以安全加入和退出一些机器。
文件
- 文件切成块(默认大小128M),以块为单位,每个块有多个副本存储在不同的机器上,副本数可在文件生成时指定(文件上传时候可以通过serrep参数指定副本数,默认3)
- namenode是主节点,存储文件的元数据,如文件名,文件目录结构,文件属性(生成时间,副本数,文件权限),以及每个文件的块列表及块所在的datanode
- datanode在本地文件系统存储文件块数据,以及数据块的校验和。
- 可以创建,删除,移动或重命名文件,当文件创建,写入和关闭之后不能修改文件内容,可以追加。
数据损坏处理
- 当datanode读取数据时,会计算checksum
- 如果计算后的checksum和block创建时的checksum不一致,说明该block被损坏。
- client会读取其他datanode上的block
- namenode标记该块已被损坏,然后复制block达到预期设置的文件备份数。
- datanode在其文件创建后三周验证其checksum
HDFS交互方式
shell交互
- 命令:
bin/hdfs dfs
每次使用这个命令的时候,都会去读取core-site.xml,hdfs-site.xml等配置文件,也可以通过命令中的可选项临时改变配置文件中的信息(如:bin/hdfs dfs -D fs.defaultFS=file:/// -ls
将文件系统改为本地文件系统 - 命令:
bin/hdfs dfsadmin
查看集群的状态报告(在50070窗口有显示):bin/hdfs dfsadmin -report
安全命令:bin/hdfs dfsadmin -safemode
刷新命令:bin/hdfs dfsadmin -refresh
,在往集群中增加或者退出结点时要进行刷新操作。
java api调用
开发所需jar包
hadoop-2.5.0\share\hadoop\common
所有jar,
hadoop-2.5.0\share\hadoop\common\lib
所有jar,
hadoop-2.5.0\share\hadoop\hdfs
所有jar
hadoop-2.5.0\share\hadoop\mapreduce
所有jar
hadoop-2.5.0\share\hadoop\yarn
所有jarmaven
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.5.0</version>
</dependency>
- 获取hdfs文件系统
public static FileSystem getFileSystem(){
Configuration conf = new Configuration();
FileSystem fs = null;;
try {
fs = FileSystem.get(conf);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return fs;
}
- 读取hdfs文件系统上的文件
public static void main( String[] args ) throws IOException
{
String fileName = "/user/bxp/mapreduce/wordcount/input/test";
String fileName2 = "/user/bxp/mapreduce/wordcount/output/part-r-00000";
readFile(fileName2);
}
public static void readFile(String fileName){
FileSystem fs = getFileSystem();
Path path = new Path(fileName);
FSDataInputStream in = null;
try {
in = fs.open(path);
IOUtils.copyBytes(in, System.out, 1024, false);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
IOUtils.closeStream(in);
}
}
- 上传文件
public static void main( String[] args ) throws IOException
{
String srcPath = "/usr/lib/hadoop-2.5.0-cdh5.3.6/input/test1";
String destPath = "/user/bxp/mapreduce/wordcount/input2/test1";
uploadFile(srcPath, destPath);
}
//上传文件
public static void uploadFile(String srcPath, String destPath){
FileSystem fs = getFileSystem();
FileInputStream in = null;
FSDataOutputStream out = null;
try {
in = new FileInputStream(new File(srcPath));
out = fs.create(new Path(destPath));
IOUtils.copyBytes(in, out, 1024, false);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
IOUtils.closeStream(in);
IOUtils.closeStream(out);
}
}