首页 > 编程知识 正文

Hadoop教程 第四弹 HDFS工作原理

时间:2023-05-05 08:57:32 阅读:51478 作者:2276

1、HDFS客户端1.1、HDFS shell上传指令:

ovefromlocalcopyfromlocalputappendtofile下载命令:

版权所有其他:

lscatchgrp、chmod、chownmkdircp和HDFS中的副本、移动文件tailrm和rm -rdu统计文件夹大小信息setrep更改副本的数量。 一台机器上最多只有一个ls命令等副本。 使用方法如下所示。

hadoop fs -ls /

1.2、HDFS Java客户端1.2.1、pom为dependencygroupidorg.Apache.Hadoop/groupidartifactidhadoop-client/依赖于artifactidversion3的ependencydependencygroupidorg.slf4j/groupidartifactidslf 4j-log4j 12/artifactidversion1.7. 30 /

1.2.2、示例代码importorg.Apache.Hadoop.conf.configuration; importorg.Apache.Hadoop.fs.file system; importorg.Apache.Hadoop.fs.path; import java.net.URI; publicclasshdfsdemo { privatefilesystemfs; 公共语音输入(throws exception ) uriURL=newuri ) (HDFS://Hadoop10233608020 ); 配置配置=new配置(; String user='root '; fs=filesystem.get(URL,config,user ); }公共void close () throws exception (fs.close ); } public void mkdir () throwsexception ) fs.mkdirs ) newpath ) (/input ); } publicstaticvoidmain (字符串[ ] args ) Throwsexception ) HDFsdemodemo=newHDFsdemo ); demo.init (; demo.mkdir (; demo.close (; }

1.3、优先级服务端配置有两种方式。

1.1、默认配置文件(如hdfs-default.xml1.2 )和自定义配置文件(如etc/hadoop/hdfs-site.xml )也有两种方法。

2.1、配置类2.2、classpath路径中的配置文件,例如src/main/resources/HDFS-site.XML的优先级从低到高为1.1.1.2.2.1

2、HDFS写入数据流

客户端通过分布式文件系统模块请求NameNode上传文件,NameNode检查目标文件是否已存在以及父目录是否存在。 NameNode返回是否可以上载。 客户端请求第一个Block已上载到哪个DataNode服务。 NameNode返回三个DataNode节点: dn1、dn2和dn3。 客户端通过FSDataOutputStream模块请求dn1上传数据,dn1在收到请求后继续调用dn2,dn2调用dn3建立此通信管道。 dn1、dn2、dn3分阶段响应客户端。 客户端开始将第一块上传到dn1。 首先从磁盘读取数据并将其放入本地内存缓存中。 以包为单位,dn1收到包后,将其转发到dn2,dn2转发到dn3。 每次传递包时,dn1都会放入响应队列中等待响应。 块传输完成后,客户端再次请求NameNode上传第二个块的服务。 重复步骤3到7。 上载文件时,文件的区块在客户端进行,区块大小默认为128M,可以在hdfs-site.xml中通过dfs.blocksize参数进行设置。

在步骤7中,dn1收到包后,将包写入其本地磁盘和将包传递给dn2是同时进行的。

那么对于步骤4,dn1、dn2、dn3是如何选择的呢?

也就是说,hadoop集群中有n个节点(n3 ),而

所上传的文件副本数为3,那么从n个节点中选哪3个节点最合适呢?

下面来介绍HDFS对于块的分布,首先看一下集群节点的物理分布图。

虽然我画出了两个机房,但一般情况下机房之间数据是不互通的,也就是说上图相当有两个集群,这里我们只讨论集群内部的情况。

块副本的分布位置直接影响着HDFS的可靠性和性能。一个大型的HDFS系统一般都需要跨很多机架,不同机架之间的数据传输需要经过网关,并且同一个机架中机器之间的带宽要大于不同机架机器之间的带宽。

如果把所有的副本都放在不同的机架中,这样既可以防止机架失败导致数据块不可用,又可以在读数据时利用到多个机架的带宽,起到负载均衡的效果。
但是,如果是写数据,各个数据块需要同步到不同的机架,会影响到写数据的效率。
在Hadoop中,在副本数量为3的情况下,会把第一个副本放到机架的某个节点上(客户端所在节点或离客户端最近的节点),第二个副本放到另一个机架上,最后一个副本放在第二个副本所在机架的不同节点上。这种策略减少了跨机架副本的个数,提高了写的性能,也能够允许一个机架失败的情况,算是一个很好的权衡。

 

3、HDFS读数据流程

客户端通过DistributedFileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址,并返回给客户端。客户端挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。

当文件有多个块时,客户端读取数据不是并行读取的,而是先读完第一个块,再读第二个块。

不管是读文件还是写文件,其选择副本节点时都有会两方面的考量:

距离优先负载均衡3.1、数据完整性校验

HDFS可以检测到数据块损坏。在读取数据块时,HDFS会对数据块和保存的CheckSum(校验和)文件匹配,如果计算后的CheckSum与Block创建时值不一样,说明Block已经损坏,NameNode会重新备份损坏的数据块。

这里介绍两种校验算法,HDFS用的是CRC32.

CRC校验:将信息字段左移r位,然后用生成多项式生成r位的校验字段,信息字段+校验字段就是CRC码。比如信息字段是1001,校验字段是110,那么CRC码就是1001110。不同的CRC版本的区别是生成多项式不同。
优点:校验速度和成本要优于奇偶校验。

奇偶校验:通过校验1的个数是奇数还是偶数,来判断数据的正确性。
有两种形式:

奇校验(校验位确保整个数据中1的个数是偶数个):数据中1的个数已经是奇数时,校验为填0,否则填1。偶校验(校验位确保整个数据中1的个数是偶数个):数据中1的个数已经是偶数时,校验为填0,否则填1。

缺点:只能检测一位数据发生错误,如果多位数据发生错误则检测不出来,更检测不到发生错误的数据的位置。
优点:效率高,一次能检测更多的数据,实现简单。

 

4、NameNode和SecondaryNameNode

2nn并非nn的热备,当NameNode挂掉的时候,它并不能马上替换NameNode并提供服务,2nn作用是定期合并Fsimage和Edits。nn仍然会存在单点故障以及数据丢失问题。因此,企业一般不用2nn,而是用nn的高可用机制。不过还是有必要介绍一下2nn与nn两者是如何协作的。
因为内存快的原因,NameNode中的元数据存储在内存中,并且元数据还会以FSImage文件的形式持久化到磁盘中。当元数据更新时,如果同时更新内存和FsImage文件,就会导致效率过低,如果不更新磁盘,就会发生一致性问题,一旦NameNode节点断电,数据就会丢失。
因此引入Edits文件(只进行追加操作,效率很高)。当元数据有增删改时,修改内存中的元数据并追加到Edits中,即使NameNode节点断电,可通过合并FsImage和Edits,合成元数据。
但是,如果长时间添加数据到Edits中,会导致该文件数据过大,效率降低,而且一旦断电,恢复元数据需要的时间过长(NameNode会在启动时合并,即NameNode启动时间过长)。
因此,需要定期进行FsImage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低。因此,引入一个新的节点SecondaryNamenode,专门用于FsImage和Edits的合并。

 

第一阶段:NameNode启动

NameNode格式化(第一次启动)后会创建FSImage和Edits,如果不是第一次启动,直接加载Edits和FSImage到内存。客户端对元数据进行增删改的请求。NameNode先记录Edits,然后再更改内存中的元数据。

第二阶段:SecondaryNameNode工作

SecondaryNameNode询问NameNode是否需要CheckPoint,如果需要,则进行第2步。SecondaryNameNode请求执行CheckPoint。NameNode将当前时刻的Edits和FSImage拷贝到SecondaryNameNode,如果此时有客户端更改元数据则将其持久化到Edits.new文件中。SecondaryNameNode加载Edits和FSImage到内存,并合并,生成新的镜像文件fsimage.chkpoint。拷贝fsimage.chkpoint到NameNode。NameNode将fsimage.chkpoint重新命名成fsimage,fsimage+Edits.new又组成了最新的一份元数据,等待下一次合并。4.1、CheckPoint触发时机设置

SecondaryNameNode默认每1小时执行一次(hdfs-default.xml)。

<property>  <name>dfs.namenode.checkpoint.period<name>  <value>3600s</value></property>


一分钟检查一次操作次数,当达到1百万时,SecondaryNameNode执行一次(hdfs-default.xml)。

<property>  <name>dfs.namenode.checkpoint.txns</name>  <value>1000000</value>  <description>操作次数</description></property><property>  <name>dfs.namenode.checkpoint.check.period</name>  <value>60s</value>  <description>1分钟检查一次操作次数</description></property>

 

5、DataNode工作机制

一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。
DataNode启动后向NameNode注册,通过后,周期性(6小时)地向NameNode上报所有的块信息。

<property>  <name>dfs.blockreport.intervalMsec</name>  <value>21600000</value>  <description>以毫秒为单位确定块报告间隔</description></property>

DN 扫描自己节点块信息列表的时间,默认6小时

<property>  <name>dfs.datanode.directoryscan.interval</name>  <value>21600s</value></property>

心跳是每3秒一次,如果超过指定时长没有收到某个DataNode的心跳,则认为该节点不可用。此时NameNode把失败节点的数据备份到另外一个健康的节点。

DN超时时长计算公式:TimeOut = 2 * dfs.namenode.heartbeat.recheck-interval(毫秒) + 10 * dfs.heartbeat.interval(秒)

<property>  <name>dfs.namenode.heartbeat.recheck-interval</name>  <value>300000</value></property><property>  <name>dfs.heartbeat.interval</name>  <value>3</value></property>
5.1、安全模式

当NameNode节点启动时,会进入安全模式。在此阶段,DataNode会向NameNode上传它们数据块的列表,并且NameNode得会对每个文件对应的数据块副本进行统计。

比如某个文件的副本数为3,当副本数>=3时,系统会退出安全模式,当副本数<3时,就会对副本数不足的数据块安排DataNode进行复制,直至达到3个副本。
在安全模式下,系统处于只读状态,NameNode不会处理任何块的复制和删除命令。

所有的HDFS中的沟通协议都是基于TCP/IP协议的,NameNode不会主动发起任何请求,只会被动接收来自客户端或DataNode的请求。

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。