1.HDFS 分布式文件系统,适合一次写入,多次读出的场景。且不支持文件修改。适合做数据分析。
优点
1高容错性:数据自动保存多个副本,通过增加副本来提高容错性。某个副本丢失以后,可以自动恢复。
2.适合处理大数据: 数据规模,处理的数据达到GB,TB,PB。文件规模,处理百万规模以上的文件数量。
3.可构建在廉价机器上。
缺点
不合适低延迟数据访问
无法高效的对大量小文件进行存储(存储小文件,会占用NameNode大量的内存来存储文件目录和块信息)
不支持并发写入,文件随机修改(一个文件只能一个写,不支持多线程。可以数据追加append)
2.HDFS组成架构
1)NameNode(nn)就是Master。它是以个主管,管理者。
管理HDFS的名称空间 配置副本策略
管理数据块(Block)映射信息 处理客户端读写请求
2)DataNode:就是Slave.NameNode下达命令。DataNode执行实际的操作
存储实际的数据块 执行数据块的读/写操作
3)Cliect:就是客户端
文件切分。文件上传HDFS的时候,Client将文件切分成一个一个的Block,然后进行上传。
与NameNode交互,获取文件的位置信息
与DataNode交互,读取或者写入数据
Client提供一些命令来管理HDFS.比如NameNode格式化
Client提供一些命令来访问HDFS,比如对HDFS增删查改操作
4)Secondary NameNode,不是NameNode的热备。当NameNode挂掉的时间,不能马上替换NameNode并提供服务
3.HDFS的块设置太小,会增加寻址时间 ,HDFS的快设置太大,会增加MapReduce时间 (应该和HashMap的加载因子差不多)
Hadoop fs 常用的命令 eg::: hadoop fs -cat /1.txt
本地-》HDFS
put
copyFromLocal 和put没有区别,只是名字不一样
moveFromLocal 和put的区别就是剪切
appendToFile 追加文件
HDFS-》HDFS
cp
mv
chown
chgrp
chmod
mkdir
du
df
cat
HFDS-》本地
get
getmerge 合并下载
copyToLocal 和get一样
本地API操作HDFS
创建一个maven项目
public void test1() throws IOException, InterruptedException, URISyntaxException {
// 1 获取HDFS抽象对象
Configuration configuration = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://hadoop100:9000"), configuration, "zxzh");
//上传文件
fs.copyFromLocalFile(new Path("f:\\1.txt"), new Path("/"));
// 3 关闭资源
fs.close();
}
HDFS读写流程
1.端通过Distributed FileSystem向Namenode申请上传文件(是否有权限和文件是否存在)
2.Namenode相应是否可以上传
3.客户端第一次请求Block上传到那几天Datanode服务器上
4.Namenode返回相应的节点数
5.客户端通过FSDataOutputStream模块请求 Datanode1上传数据->Datanode2->Datanode3 建立通道
6.Datanode1,Datanode2,Datanode3逐级应答客户端。
7.客户端开始往Datanode1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,Datanode1收到一个Packet就会传给Datanode2,Datanode2传给Datanode3;Datanode1每传一个packet会放入一个应答队列等待应答。
8.当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。(重复执行3-7步)
4.NameNode和SecondaryNameNode(2NN比NN少一个edits-inprogress_oo2)
1). 第一阶段:NameNode启动
(1)第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
(2)客户端对元数据进行增删改的请求。
(3)NameNode记录操作日志,更新滚动日志。
(4)NameNode在内存中对元数据进行增删改
2). 第二阶段:Secondary NameNode工作
(1)Secondary NameNode询问NameNode是否需要CheckPoint。直接带回NameNode是否检查结果。
(2)Secondary NameNode请求执行CheckPoint。
(3)NameNode滚动正在写的Edits日志。
(4)将滚动前的编辑日志和镜像文件拷贝到Secondary NameNode。
(5)Secondary NameNode加载编辑日志和镜像文件到内存,并合并。
(6)生成新的镜像文件fsimage.chkpoint。
(7)拷贝fsimage.chkpoint到NameNode。
(8)NameNode将fsimage.chkpoint重新命名成fsimage。
Fsimage:NameNode内存中元数据序列化后形成的文件。
Edits:记录客户端更新元数据信息的每一步操作(可通过Edits运算出元数据)。
3).NameNode启动时,先滚动Edits并生成一个空的edits.inprogress,然后加载Edits和Fsimage到内存中,此时NameNode内存就持有最新的元数据信息。Client开始对NameNode发送元数据的增删改的请求,这些请求的操作首先会被记录到edits.inprogress中(查询元数据的操作不会被记录在Edits中,因为查询操作不会更改元数据信息),如果此时NameNode挂掉,重启后会从Edits中读取元数据的信息。然后,NameNode会在内存中执行元数据的增删改的操作。
由于Edits中记录的操作会越来越多,Edits文件会越来越大,导致NameNode在启动加载Edits时会很慢,所以需要对Edits和Fsimage进行合并(所谓合并,就是将Edits和Fsimage加载到内存中,照着Edits中的操作一步步执行,最终形成新的Fsimage)。SecondaryNameNode的作用就是帮助NameNode进行Edits和Fsimage的合并工作。
SecondaryNameNode首先会询问NameNode是否需要CheckPoint(触发CheckPoint需要满足两个条件中的任意一个,定时时间到和Edits中数据写满了)。直接带回NameNode是否检查结果。SecondaryNameNode执行CheckPoint操作,首先会让NameNode滚动Edits并生成一个空的edits.inprogress,滚动Edits的目的是给Edits打个标记,以后所有新的操作都写入edits.inprogress,其他未合并的Edits和Fsimage会拷贝到SecondaryNameNode的本地,然后将拷贝的Edits和Fsimage加载到内存中进行合并,生成fsimage.chkpoint,然后将fsimage.chkpoint拷贝给NameNode,重命名为Fsimage后替换掉原来的Fsimage。NameNode在启动时就只需要加载之前未合并的Edits和Fsimage即可,因为合并过的Edits中的元数据信息已经被记录在Fsimage中。
5.NameNode工作流程
1)一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。
2)DataNode启动后向NameNode注册,通过后,周期性(1小时)的向NameNode上报所有的块信息。
3)心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用。
4)集群运行中可以安全加入和退出一些机器。
6.新增/删除HDFS节点
1).克隆虚拟机,修改IP和主机名
2).删除新克隆机器的hadoop data 和 log 配置 /etc/profile
3). 直接启动 hadoop-daemon.sh start datanode
添加白名单
1).自己创建一个文件,写成白名单的主机名 dfs.hosts
2).在NameNode的hdfs-site.xml里面增加dfs.hosts属性 ,涮新NameNode hdfs dfsadmin -refreshNodes
<property>
<name>dfs.hosts</name>
<value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts</value>
</property>
黑名单
1).自己创建一个文件,写成黑名单的主机名 dfs.hosts.exclude
2).在NameNode的hdfs-site.xml配置文件中增加dfs.hosts.exclude属性
<property>
<name>dfs.hosts.exclude</name>
<value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts.exclude</value>
</property>
3).刷新NameNode、刷新ResourceManager