一、概述

1、HDFS 介绍

首先,它是一个文件系统,用于存储文件,通过统一的命名空间目录树来定位文件;
其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。
HDFS主要是用来解决海量数据存储问题。
HDFS 是 Hadoop Distribute File System 的简称,意为:Hadoop 分布式文件系统。是 Hadoop 核心组件之一,作为最底层的分布式存储服务而存在。
分布式文件系统解决的问题就是大数据存储。它们是横跨在多台计算机上的存储系统。分布式文件系统在大数据时代有着广泛的应用前景,它们为存储和处理超大规模数据提供所需的扩展能力

2、HDFS优缺点

优点
1.支持超大文件
2.检测和快速应对硬件故障
3.流式数据访问
Hdfs的数据处理规模比较大,应用一次需要访问大量的数据,同时这些应用一般都是批量处理,而不是用户交互式处理。应用程序能以流的形式访问数据集。主要的是数据的吞吐量,而不是访问速度。
4.简化的一致性模型
大部分hdfs操作文件时,需要一次写入,多次读取。在hdfs中,一个文件一旦经过创建、写入、关闭后,一般就不需要修改了。这样简单的一致性模型,有利于提高吞吐量。
5.高容错性
数据自动保存多个副本,副本丢失后自动恢复
6.可构建在廉价机器上
构建在廉价机器上可以轻松的通过扩展机器数量来近乎线性的提高集群存储能力
缺点
1.低延迟数据访问
低延迟数据。如和用户进行交互的应用,需要数据在毫秒或秒的范围内得到响应。由于hadoop针对海量数据的吞吐量做了优化,牺牲了获取数据的延迟,所以对于低延迟来说,不适合用hadoop来做。
2.大量的小文件
Hdfs支持超大的文件,是通过数据分布在数据节点,数据的元数据保存在名字节点上。名字节点的内存大小,决定了hdfs文件系统可保存的文件数量。虽然现在的系统内存都比较大,但大量的小文件还是会影响名字节点的性能。
3.不支持修改,只能追加
Hdfs的文件只能有一次写入,不支持修改和追加写入(2.0版本支持追加),也不支持修改。只有这样数据的吞吐量才能大。
4.不支持超强的事务
没有像关系型数据库那样,对事务有强有力的支持。

3、 HDFS 角色

HDFS 采用 master/slave 架构。一般一个 HDFS 集群是有一个 Namenode 和一定数目的 Datanode 组成。Namenode 是 HDFS 集群主节点,Datanode 是 HDFS 集群从节点,两种角色各司其职,共同协调完成分布式的文件存储服务。
1)、NameNode 主要是存储元数据 文件名、目录结构、文件属性、块列表、块所在的datanode
2)、DataNode 存储文件的block块 存储文件块以及校验和
3)、secondaryNameNode(2nn)周期合并fsimage(元数据全量快照)和edit_log(增量操作日志)生成新的fsimage返回给NameNode【减轻NameNode的压力】 对Namenode元数据备份(不是全部数据)


4、分块存储

块的大小是基于磁盘的读写速率
HDFS 中的文件在物理上是分块存储(block)的,块的大小可以通过配置参数来规定,默认大小在 hadoop2.x 版本中是 128M。

5、 副本机制

为了容错,文件的所有 block 都会有副本。每个文件的 block 大小和副本系数都是可配置的。应用程序可以指定某个文件的副本数目。副本系数可以在文件创建的时候指定,也可以在之后改变(每个datanode节点上只会有一个副本,当datanode节点增加时,也会根据副本数创建)。

二、部署安装

需要提前好配置hosts文件
172.17.0.5 hadoop001
172.17.0.6 hadoop002

1、单机版部署

(伪分布式,伪分布式的所有角色都在同一台服务器)

1、下载安装包

  1. wget https://downloads.apache.org/hadoop/common/hadoop-3.3.2/hadoop-3.3.2.tar.gz

2、解压

  1. mv hadoop-3.3.2.tar.gz /home/hadoop/
  2. tar -zxvf hadoop-3.3.2.tar.gz
  3. chown hadoop:hadoop -R hadoop-3.3.2*
  4. ll -rt | grep hadoop

3、修改hadoop.env配置文件

  1. cd hadoop-3.3.2
  2. vim ./etc/hadoop/hadoop-env.sh
  1. export JAVA_HOME=/usr/local/jdk1.8.0_141/

4、修改core-site.xml配置文件

HDFS - 图2

  1. cd hadoop-3.3.2
  2. vim ./etc/hadoop/core-site.xml
  1. <configuration>
  2. <!--nameNode的位置信息-->
  3. <property>
  4. <name>fs.defaultFS</name>
  5. <value>hdfs://hadoop001:9000</value>
  6. <description>表示HDFS的基本路径</description>
  7. </property>
  8. <property>
  9. <name>hadoop.tmp.dir</name>
  10. <value>file:///data/hadoop-data/tmp</value>
  11. <description>Abase for other temporary directories.</description>
  12. </property>
  13. </configuration>

5、修改hdfs-site.xml配置文件

访问namenode的hdfs使用50070端口,访问datanode的webhdfs使用50075端口。访问文件、文件夹信息使用namenode的IP和50070端口,访问文件内容或者进行打开、上传、修改、下载等操作使用datanode的IP和50075端口。要想不区分端口,直接使用namenode的IP和端口进行所有的webhdfs操作,就需要在所有的datanode上都设置hefs-site.xml中的dfs.webhdfs.enabled为true。
HDFS - 图3

  1. vim ./etc/hadoop/hdfs-site.xml
  1. <configuration>
  2. <property>
  3. <name>dfs.namenode.logging.level</name>
  4. <value>warn</value>
  5. </property>
  6. <!-- hdfs文件的副本数量 -->
  7. <property>
  8. <name>dfs.replication</name>
  9. <value>1</value>
  10. </property>
  11. <!-- nameNode 元数据存储路径 -->
  12. <property>
  13. <name>dfs.namenode.name.dir</name>
  14. <value>file:///data/hadoop-data/nn</value>
  15. </property>
  16. <!-- DataNode 数据存储路径-->
  17. <property>
  18. <name>dfs.datanode.data.dir</name>
  19. <value>file:///data/hadoop-data/dn</value>
  20. </property>
  21. <!-- secondaryNameNode数据存储路径 -->
  22. <property>
  23. <name>dfs.namenode.checkpoint.dir</name>
  24. <value>file:///data/hadoop-data/snn</value>
  25. </property>
  26. <!-- web页面配置必须为true -->
  27. <property>
  28. <name>dfs.webhdfs.enabled</name>
  29. <value>true</value>
  30. </property>
  31. <!-- datanode之间是否通过域名方式通信 -->
  32. <property>
  33. <name>dfs.datanode.use.datanode.hostname</name>
  34. <value>false</value>
  35. </property>
  36. <!-- 默认为true,namenode连接datanode时,会进行host解析查询 -->
  37. <property>
  38. <name>dfs.namenode.datanode.registration.ip-hostname-check</name>
  39. <value>false</value>
  40. </property>
  41. </configuration>

6、配置slaves/workers文件【dataNode的节点地址】

  1. --hadoop3.0以后slaves更名为workers,并且端口也有修改
  2. vim ./etc/hadoop/workers
  3. vim ./etc/hadoop/slaves

7、设置免密登录

  1. ssh-keygen -t rsa
  2. cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
  3. chmod 0600 ~/.ssh/authorized_keys
  4. chmod 700 ~/.ssh
  5. chmod 600 ~/.sshauthorized_keys

8、启动(第一次启动需要格式化)

  1. 格式化namenode
  2. hdfs namenode -format
  1. su - hadoop
  2. cd sbin/
  3. ./start-dfs.sh
  1. ./stop-dfs.sh

8、jps查看和ps查看

  1. jps | grep 'NameNode\|DataNode\|SecondaryNameNode'
  2. ps -elf | grep 'NameNode\|DataNode\|SecondaryNameNode'

image.png

2、分布式部署

1、 角色规划

NN SNN DN
hadoop001 *
hadoop002 * *
hadoop003 *
hadoop004 *

3、修改hadoop.env配置文件

**见单机版部署配置

4、修改core-site.xml文件(指定nn的服务器)

**见单机版部署配置

5、修改hdfs-site.xml配置文件(指定snn的服务器)

  1. <configuration>
  2. <property>
  3. <name>dfs.namenode.logging.level</name>
  4. <value>warn</value>
  5. </property>
  6. <!-- 修改hdfs文件的副本数量 -->
  7. <property>
  8. <name>dfs.replication</name>
  9. <value>3</value>
  10. </property>
  11. <!--nameNode的位置信息-->
  12. <property>
  13. <name>dfs.namenode.secondary.http-address</name>
  14. <value>hadoop002:50090</value>
  15. </property>
  16. <!-- nameNode 元数据存储路径 -->
  17. <property>
  18. <name>dfs.namenode.name.dir</name>
  19. <value>file:///data/hadoop-data/nn</value>
  20. </property>
  21. <!-- DataNode 数据存储路径-->
  22. <property>
  23. <name>dfs.datanode.data.dir</name>
  24. <value>file:///data/hadoop-data/dn</value>
  25. </property>
  26. <!-- secondaryNameNode数据存储路径 -->
  27. <property>
  28. <name>dfs.namenode.checkpoint.dir</name>
  29. <value>file:///data/hadoop-data/snn</value>
  30. </property>
  31. <!-- web页面配置必须为true -->
  32. <property>
  33. <name>dfs.webhdfs.enabled</name>
  34. <value>true</value>
  35. </property>
  36. <!-- datanode之间是否通过域名方式通信 -->
  37. <property>
  38. <name>dfs.datanode.use.datanode.hostname</name>
  39. <value>false</value>
  40. </property>
  41. <!-- 默认为true,namenode连接datanode时,会进行host解析查询 -->
  42. <property>
  43. <name>dfs.namenode.datanode.registration.ip-hostname-check</name>
  44. <value>false</value>
  45. </property>
  46. </configuration>

6、配置slaves/workers文件【指定dataNode的节点地址】

  1. --hadoop3.0以后slaves更名为workers,并且端口也有修改
  2. vim ./etc/hadoop/workers
  3. vim ./etc/hadoop/slaves
  4. hadoop002
  5. hadoop003
  6. hadoop004

7、设置免密登录

**见单机版部署配置

8、启动

在NN节点启动即可

3、高可用模式部署

https://blog.csdn.net/m0_46360532/article/details/120858425

三、HDFS的Shell相关操作

1、查看

查看hdfs分布式系统根目录下所有文件和文件夹信息

  1. hdfs dfs -ls /

2、创建文件夹

  1. hdfs dfs -mkdir /test1

3、上传

  1. hdfs dfs -put test1.txt /test1

4、下载

  1. hdfs dfs -get /test1/test1.txt

5、查看文件内容

  1. hdfs dfs -text /test1/test1.txt
  2. hdfs dfs -cat /test1/test1.txt

6、追加内容

  1. #在本地编辑testtmp.txt文件,文件内容为“12345”
  2. #将testtmp.txt文件的内容追加到hdfs分布式系统的/test1/test1.txt文件后。
  3. [root@hadoop1 ~]# hdfs dfs -appendToFile testtmp.txt /test1/test1.txt

7、复制

  1. hdfs dfs -cp /test1/test1.txt /test2/test2.txt

8、移动

  1. hdfs dfs -mv /test2/test2.txt /test1

9、删除

  1. hdfs dfs -rm /test2/test1.txt

四、HDFS的读写流程

1、写入流程

image.png

详细步骤:

client 发起文件上传请求,通过 RPC 与 NameNode 建立通讯,NameNode 检查目标文件是否已存在,父目录是否存在,返回是否可以上传;
client 请求第一个 block 该传输到哪些 DataNode 服务器上;
NameNode 根据配置文件中指定的备份数量及副本放置策略进行文件分配,返回可用的 DataNode 的地址,如:A,B,C;
client 请求3台 DataNode 中的一台A上传数据(本质上是一个 RPC 调用,建立 pipeline),A收到请求会继续调用B,然后B调用C,将整个 pipeline 建立完成,后逐级返回 client;
client 开始往A上传第一个 block(先从磁盘读取数据放到一个本地内存缓存),以 packet 为单位(默认64K),A收到一个 packet 就会传给B,B传给C;A每传一个 packet 会放入一个应答队列等待应答。
数据被分割成一个个 packet 数据包在 pipeline 上依次传输,在 pipeline 反方向上,逐个发送 ack(ack 应答机制),最终由pipeline中第一个 DataNode 节点A将 pipeline ack 发送给client;
当一个 block 传输完成之后,client 再次请求 NameNode 上传第二个 block 到服务器。

2、读数据流程

image.png
详细步骤:

Client 向 NameNode 发起 RPC 请求,来确定请求文件 block 所在的位置;
NameNode 会视情况返回文件的部分或者全部 block 列表,对于每个 block,NameNode 都会返回含有该 block 副本的 DataNode 地址;
这些返回的 DataNode 地址,会按照集群拓扑结构得出 DataNode 与客户端的距离,然后进行排序,排序两个规则:网络拓扑结构中距离Client近的排靠前;心跳机制中超时汇报的 DataNode 状态为 STALE,这样的排靠后;
Client 选取排序靠前的 DataNode 来读取 block,如果客户端本身就是 DataNode,那么将从本地直接获取数据;底层上本质是建立 Socket Stream(FSDataInputStream),重复的调用父类 DataInputStream 的 read 方法,直到这个块上的数据读取完毕;
当读完列表的 block 后,若文件读取还没有结束,客户端会继续向 NameNode 获取下一批的 block 列表;
读取完一个 block 都会进行 checksum 验证,如果读取 DataNode 时出现错误,客户端会通知 NameNode,然后再从下一个拥有该 block 副本的 DataNode 继续读。
read 方法是并行的读取 block 信息,不是一块一块的读取;NameNode 只是返回 Client 请求包含块的 DataNode 地址,并不是返回请求块的数据;
最终读取来所有的 block 会合并成一个完整的最终文件。

五、Datanode工作机制

image.png
.DataNode启动后会向NameNode注册。(将自己所保存的Block信息告诉NameNode)

2.NameNode接收到DataNode发送的信息,注册成功

3.在默认配置中,DataNode会周期性(6小时)上报所有块信息

4.DataNode会每三秒心跳一次,目的是告诉NameNode,它还活着

5.当NameNode超过十分钟+30秒没有收到DataNode的心跳,则认为该节点不可用,那么后续NameNode不会再向该节点进行读写操作

六、机架感知

机架感知是一种计算不同计算节点(TaskTracker)的距离的技术,用以在任务调度过程中尽量减少网络带宽资源的消耗,这里用尽量,想表达的是当一个TT(TaskTracker)申请不到本地化任务时,JT(JobTracker)会尽量调度一个机架的任务给他,因为不同机架的网络带宽资源比同一个机架的网络带宽资源更可贵。

三、机架感知设计思想

首先,一个重要的假设前提是HDFS运行于一个具有树状网络拓扑结构的集群上。例如集群由多个数据中心组成,每个数据中心里有多个机架,而每个机架上有多台计算机(数据节点)。如下图所示:
HDFS - 图8

网络拓扑(NetworkTopology)

在Hadoop里,以类似于一种文件目录结构的方式来表示节点。
例如,R1的位置可以表示为 /D1/R1,而H12的位置可以表示为 /D2/R4/H12。
当数据节点启动的时候,需要通过一种机制来明确它在集群中的位置,才能构建完整的网络拓扑图。
因此,首先它需要确认它的上级节点(通常也就是机架)的位置。数据节点程序支持选项”-p”或”-parent”从命令行读入上级节点位置。
如果没有指定这个选项,那么会使用一个默认的上级节点。
至于如何获取上级节点信息,由实施Hadoop的机构自行决定。一个常用的做法是使用脚本打印当前机器的上级节点信息到标准输出stdout。
这样数据节点启动的时候就可以获取到上级节点的信息(Hadoop应该是通过接口’DNSToSwitchMapping’来解析这个信息,具体请参考手册的Class说明)。
数据节点会把它的位置信息发给名称节点。
当名称节点收到数据节点的位置信息以后,它会先检查网络拓扑中是否已经有这个数据节点的记录。
如果有,它会把旧的记录删除,加入新的节点位置信息。

副本放置(ReplicaPlacement)

数据块的副本放置策略的目的是在以下两者之间取得平衡:
— 使数据的可靠性和可用性较大化
— 使写入数据产生的开销最小化
因此,当一个新的数据块被创建的时候,遵循以下规则:
— 第1个副本放置于本地节点
— 第2个副本放置于不同的机架
— 第3个副本放置于本地机架的不同节点
— 其余的副本在遵循以下限制的前提下随机放置
— 1个节点最多放置1个副本
— 如果副本数少于2倍机架数,不可以在同一机架放置超过2个副本
当重新复制一个数据块的时候,遵循以下规则:
— 如果已有1个副本,把第2个副本放置在不同的机架
— 如果已有2个副本且处于同一机架,把第3个副本放置在不同的机架
— 如果已有2个副本但不处于同一机架,把第3个副本放置在和第1个副本相同的机架
— 当可用副本数超过2个的时候,随机放置
当发生数据读取的时候,名称节点首先检查客户端是否位于集群中。
如果是的话,就可以按照由近到远的优先次序决定由哪个数据节点向客户端发送它需要的数据块。
也就是说,对于拥有同一数据块副本的节点来说,在网络拓扑中距离客户端近的节点会优先响应。