HDFS
第一章HDFS概述
1.1 HDFS产生背景
随着数据量越来越大,在一个操作系统(电脑)中存不下所有的数据,那么就分配到更多的操作系统(电脑)管理的磁盘中,但是这样不方便管理和维护.此时迫切的需要一种系统来管理多台机器的文件,这就是分布式文件管理系统.
HDFS只是分布式文件管理系统中的一种
1.2 HDFS定义
HDFS(Hadoop Distributed File System),它是一个文件系统,用于存储文件、通过目录树来定位文件,其次他是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色
1.3 HDFS组成架构
1.客户端上传或下载 都需要先找NameNode 写入 读取 2.NameNode将数据所在节点返回客户端
3.客户端到指定节点进行上传/下载
1.4 HDFS文件块大小
HDFS的文件在物理上是分块存储(Block)

思考:为什么块的大小不能设置太小,也不能设置太大?
(1)HDFS的块设置太小,会增加寻址时间,程序一致在找块开始的位置
(2)HDFS的块设置太大,磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间,导致程序在处理这块数据时,会非常慢
总结:HDFS块的大小设置主要取决于磁盘传输速率
第2章 HDFS的Shell操作
2.3 常用命令实操
2.3.2 上传
-put:从本地文件系统中拷贝文件到HDFS路径去
hadoop fs -put /opt/moudule/hadoop/aaa.txt /input
将linux中的/opt/moudule/hadoop/aaa.txt文件上传到HDFS的/input目录下
2.3.3 下载
-get:从HDFS下载文件到本地
hadoop fs -get /input/aa.txt /opt/module/hadoop
将HDFS的/input/aa.txt下载到linux中的/opt/module/hadoop
2.3.4 HDFS直接操作
类似Linux操作,直接操作HDFS
1)-ls: 显示目录信息
hadoop fs -ls /
2)-mkdir:在HDFS上创建目录
hadoop fs -mkdir -p /sanguo/shuguo
3)-mv:在HDFS目录中移动文件
hadoop fs -mv /liubei.txt /sanguo/shuguo
4)-du统计文件夹的大小信息
hadoop fs -du -s -h /sanguo/shuguo
5)-setrep:设置HDFS中文件的副本数量
hadoop fs -setrep 10 /sanguo/shuguo/liubei.txt
第3章 HDFS客户端操作
package com.dai.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
public class HDFSDemo1 {
private FileSystem fs;
@Before
public void before() throws IOException, InterruptedException, URISyntaxException {
URI uri = new URI("hdfs://hadoop102:9820");
Configuration conf = new Configuration();
fs = FileSystem.get(uri,conf,"atguigu");
}
@After
public void after(){
try {
if(fs!=null){
fs.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test() throws IOException {
fs.copyFromLocalFile(false,false,new Path("G:\\0521\\06-hadoop\\2.资料\\01_jar包\\jdk-8u212-linux-x64.tar.gz"),
new Path("/input"));
}
@Test
public void test1() throws IOException {
fs.copyToLocalFile(false,new Path("/input/testtt.txt"),new Path("E:\\test"),false);
}
@Test
public void test2() throws IOException {
fs.delete(new Path("/test.txt"),false);
}
@Test
public void test3() throws IOException {
fs.rename(new Path("/testtt.txt"),new Path("/input"));
}
@Test
public void test4() throws IOException {
RemoteIterator<LocatedFileStatus> remoteIterator = fs.listFiles(new Path("/"), true);
while (remoteIterator.hasNext()){
LocatedFileStatus fileStatus = remoteIterator.next();
System.out.println("文件名字为"+fileStatus.getPath().getName()+"=================");
System.out.println("文件长度为"+fileStatus.getLen());
System.out.println("文件权限为"+fileStatus.getPermission());
System.out.println("文件的分组为"+fileStatus.getGroup());
BlockLocation[] blockLocations = fileStatus.getBlockLocations();
System.out.println("文件块信息为"+Arrays.toString(blockLocations));
}
}
@Test
public void test5() throws IOException {
FileStatus[] fileStatuses = fs.listStatus(new Path("/"));
for (FileStatus files : fileStatuses){
if(files.isFile()){
System.out.println(files.getPath().getName()+"是一个文件");
}else if(files.isDirectory()){
System.out.println(files.getPath().getName()+"是一个目录");
}
}
}
@Test
public void test6() throws IOException {
FileInputStream fls = new FileInputStream("E:\\test\\newsanguo.txt");
FSDataOutputStream fds = fs.create(new Path("/newsanguo"));
IOUtils.copyBytes(fls,fds,1024,true);
}
@Test
public void test7() throws IOException {
FSDataInputStream fsl = fs.open(new Path("/newsanguo"));
FileOutputStream fileOutputStream = new FileOutputStream("E:\\test\\123.TXT");
IOUtils.copyBytes(fsl,fileOutputStream,1024,true);
}

第4章 HDFS的数据流
4.1 HDFS写数据流程
4.1.1 剖析文件写入
1.客户端创建FileSystem,向NameNode请求上传文件
2.NameNode接受客户端携带的参数(例如果文件已经存在是否覆盖等)
3.NameNode相应可以上传文件
4.客户端请求上传第一块文件,请求返回DataNode
5.NameNode根据客户端设置的副本数量决定返回几个DataNode
6.NameNode返回DataNode1,DataNode2,DataNode3,表示采用这三个节点存储数据
7.客户端创建流并向DataNode请求传输通道
8.DataNode应答成功
9.客户端对文件进行上传
10.关闭流

(1)客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode检查目标文件是否已存在,父目录是否存在
(2)NameNode返回是否可以上传
(3)客户端请求第一个 Block上传到哪几个DataNode服务器上。
(4)NameNode返回3个DataNode节点,分别为dn1、dn2、dn3
(5)客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成。
(6)dn1、dn2、dn3逐级应答客户端
(7)客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答
(8)当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。(重复执行3-7步)
4.1.3 机架感知(副本存储节点选择)

4.2 HDFS读数据流程

(1)客户端通过Distributed FileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址
(2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据
(3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)
(4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件
第5章 NameNode和SecondaryNameNode
5.1 NN和2NN工作机制
5.1.1第一次启动NameNode格式化

5.1.2不是第一次启动NameNode
断电后,内存中的元数据清空,内存会重新从Edit_in progress 和 fsimage中加载元数据

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
checkPoint:询问NN是否需要进行将元素据拷背到磁盘的操作
5.1.3CheckPoint的触发条件
1)定时时间到
2)Edits中的数据满了
5.3 CheckPoint时间设置
1)通常情况下,SecondaryNameNode每隔一小时执行一次
[hdfs-default.xml]
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600</value>
</property>
2)一分钟检查一次操作次数,当操作次数达到1百万时,SecondaryNameNode执行一次
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
<description>操作动作次数</description>
</property>
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60</value>
<description> 1分钟检查一次操作次数</description>
</property >
5.5 集群安全模式

1)基本语法
集群处于安全模式,不能执行重要操作(写操作)。集群启动完成后,自动退出安全模式。
(1)bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式状态)
(2)bin/hdfs dfsadmin -safemode enter (功能描述:进入安全模式状态)
(3)bin/hdfs dfsadmin -safemode leave (功能描述:离开安全模式状态)
(4)bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式状态)
第6章 DataNode
6.1 DataNode工作机制

(1)一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳
(2)DataNode启动后向NameNode注册,通过后,周期性(1小时)的向NameNode上报所有的块信息
(3)心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令(如复制块数据到另一台机器,或删除某个数据块), 如果超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用
(4)集群运行中可以安全加入和退出一些机器
6.2 数据完整性
6.4 服役新数据节点
1)需求
随着公司业务的增长,数据量越来越大,原有的数据节点的容量已经不能满足存储数据的需求,需要在原有集群基础上动态添加新的数据节点。
1.修改ip地址和hostname
2.works不是决定谁是集群中的节点,只是决定了在群起(start-dfs.sh,start-yarn.sh)的时候去启动哪些节点。
3.要将hadoop105中的data,logs,/tmp/*删除。
4.所有节点的hosts都要有hadoop105
6.5 退役旧数据节点
6.5.1 添加白名单
添加到白名单的主机节点,都允许访问NameNode,不在白名单的主机节点,都会被退出。
配置白名单的具体步骤如下:
- 在NameNode的/opt/module/hadoop-3.1.3/etc/hadoop目录下创建dfs.hosts文件在文件下添加主机名称
2)在NameNode的hdfs-site.xml配置文件中增加dfs.hosts属性(并重启NameNode)
<property>
<name>dfs.hosts</name>
<value>/opt/module/hadoop-3.1.3/etc/hadoop/dfs.hosts</value>
</property>
6.5.2 黑名单退役
在黑名单上面的主机都会被强制退出
1)在NameNode的/opt/module/hadoop-3.1.3/etc/hadoop目录下创建dfs.hosts.exclude文件,在文件中添加主机名称(要退役的节点)
2)在NameNode的hdfs-site.xml配置文件中增加dfs.hosts.exclude属性(并重启NameNode)
<property>
<name>dfs.hosts.exclude</name>
<value>/opt/module/hadoop-3.1.3/etc/hadoop/dfs.hosts.exclude</value>
</property>
参考资料: 尚硅谷大数据技术之Hadoop(HDFS) (作者:尚硅谷大数据研发部) 版本:V3.0
|