Hadoop的Hdfs核心进程

HDFS基本命令

功能命令备注
开启hdfssbin/start-all.sh可使用jps查看是否开启成功
关闭hdfssbin/stop-all.sh可使用jps查看是否关闭成功
查询指定路径信息hdfs dfs -ls /查询根目录的文件信息 ;想要递归显示所有目录的信息,可以在ls后面添加-R参数
上传hdfs dfs -put hello.sh /将hello.sh上传到根目录
下载hdfs dfs -get /hello.txt将hello.sh上传到根目录
删除hdfs dfs -rm [-r] /hello.txt删除多级目录 -rm -r
查看文件内容hdfs dfs cat /hello.txt查看hello.txt文件内容
创建目录hdfs dfs mkdir [-p] /test创建test目录,如果要递归创建多级目录,还需要再指定-p参数

HDFS的体系结构

HDFS的主节点称为 NameNode ,NameNode支持多个;从节点称为 DataNode ,是因为从节点上面运行的有DataNode进程,DataNode支持多个。
简单理解三者的关系:

  • 校长:NameNode
  • 校长秘书:SecondaryNameNode
  • 教职工:DataNode
    在这里插入图片描述

NameNode

NameNode主要维护着整个文件系统的文件目录树,文件/目录的信息和每个文件对应的数据块列表,并且还负责接收用户的操作请求
查看NameNode文件路径:/data/hadoop_repo/dfs/name

[root@bigdata01 name]# cd /data/hadoop_repo/dfs/name
[root@bigdata01 name]# ll
total 8
drwxr-xr-x. 2 root root 4096 Apr  8 21:31 current
-rw-r--r--. 1 root root   14 Apr  8 20:30 in_use.lock

current表示当前
in_use.lock 这个只是一个普通文件,但是它其实有特殊的含义,其文件名后缀值lock 表示是锁的意思,文件名是in_use 表示这个文件现在正在使用,不允许你再启动NameNode。如果没有的话,才可以启动成功,启动成功之后就会加一把锁, 停止的时候会把这个锁去掉。

fsimage文件

fsimage( filesystem image,文件系统镜像),fsimage文件有两个文件名相同的,有一个后缀是md5,这个其实主要是为了做md5校验的,为了保证文件传输的过程中不出问题,相同内容的md5是一样的。

[root@bigdata01 name]# cd current
[root@bigdata01 current]# ll
total 4152
-rw-r--r--. 1 root root      42 Apr  7 22:17 edits_0000000000000000001-0000000000000000002
-rw-r--r--. 1 root root 1048576 Apr  7 22:17 edits_0000000000000000003-0000000000000000003
-rw-r--r--. 1 root root      42 Apr  7 22:22 edits_0000000000000000004-0000000000000000005
-rw-r--r--. 1 root root 1048576 Apr  7 22:22 edits_0000000000000000006-0000000000000000006
-rw-r--r--. 1 root root      42 Apr  8 14:53 edits_0000000000000000007-0000000000000000008
-rw-r--r--. 1 root root    1644 Apr  8 15:53 edits_0000000000000000009-0000000000000000031
-rw-r--r--. 1 root root    1523 Apr  8 16:53 edits_0000000000000000032-0000000000000000051
-rw-r--r--. 1 root root      42 Apr  8 17:53 edits_0000000000000000052-0000000000000000053
-rw-r--r--. 1 root root 1048576 Apr  8 17:53 edits_0000000000000000054-0000000000000000054
-rw-r--r--. 1 root root      42 Apr  8 20:31 edits_0000000000000000055-0000000000000000056
-rw-r--r--. 1 root root     523 Apr  8 21:31 edits_0000000000000000057-0000000000000000065
-rw-r--r--. 1 root root 1048576 Apr  8 21:31 edits_inprogress_0000000000000000066
-rw-r--r--. 1 root root     652 Apr  8 20:31 fsimage_0000000000000000056
-rw-r--r--. 1 root root      62 Apr  8 20:31 fsimage_0000000000000000056.md5
-rw-r--r--. 1 root root     661 Apr  8 21:31 fsimage_0000000000000000065
-rw-r--r--. 1 root root      62 Apr  8 21:31 fsimage_0000000000000000065.md5
-rw-r--r--. 1 root root       3 Apr  8 21:31 seen_txid
-rw-r--r--. 1 root root     219 Apr  8 20:30 VERSION

这个文件需要使用特殊的命令进行查看
-i 输入文件 -o 输出文件

[root@bigdata01 current]# hdfs oiv -p XML -i fsimage_0000000000000000056 -o fsimage56.xml

fsimage结构:

# inode表示是hdfs中的每一个目录或者文件信息
<inode>
# id:唯一编号
<id>16393</id>
# type:文件类型
<type>FILE</type>
# name:文件名称
<name>LICENSE.txt</name>
# replication:文件的副本数量
<replication>2</replication>
# mtime:修改时间
<mtime>1586332513657</mtime
# atime:访问时间
<atime>1586332513485</atime>
# preferredBlockSize:推荐每一个数据块的大小,即128M
<preferredBlockSize>134217728</preferredBlockSize>
# permission:权限信息
<permission>root:supergroup:0644</permission>
# blocks:包含多少数据块【文件被切成数据块】
<blocks>
	<block>
# 	块id
	<id>1073741827</id>
# 	genstamp是一个唯一编号
	<genstamp>1003</genstamp>
# 	numBytes表示当前数据块的实际大小
	<numBytes>150569</numBytes>
	</block>
</blocks>
# storagePolicyId表示是数据的存储策略
<storagePolicyId>0</storagePolicyId>
</inode>

这个文件中其实就维护了整个文件系统的文件目录树,文件/目录的元数据和每个文件对应的数据块列表,所以说fsimage中存放了hdfs最核心的数据。

edits文件

edits:事务文件
当我们上传大文件的时候,一个大文件会分为多个block,那么edits文件中就会记录这些block的上传状态,只有当全部block都上传成功了以后,这个时候edits中才会记录这个文件上传成功了,那么我们执行hdfs dfs -ls的时候就能查到这个文件了。当我们在hdfs中执行ls命令的时候,其实会查询fsimage和edits中的内容。
查看edits文件,-i 输入文件 -o 输出文件

[root@bigdata01 current]# hdfs oev -i  edits_0000000000000000057-0000000000000000065  -o edits.xml

edits文件主要结构:

OP_ADD:执行上传操作

OP_ALLOCATE_BLOCK_ID:分配block块id

OP_SET_GENSTAMP_V2:设置GENSTAMP唯一标识

OP_ADD_BLOCK:添加block块

OP_CLOSE:关闭上传操作

edits文件会定期合并到fsimage文件中,这个是框架去做的,在合并的时候会对edits中的内容进行转换,生成新的内容,上传成功之后,我们只需要保存文件具体存储的block信息就行了,所以在合并的时候其实是对edits中的内容进行了精简。

seen_txid文件

current目录中还有一个seen_txid文件,HDFS format之后是0,它代表的是NameNode里面的edits_*文件的尾数,NameNode重启的时候,会按照seen_txid的数字,顺序从头跑edits_0000001~到seen_txid的数字。如果根据对应的seen_txid无法加载到对应的文件,NameNode进程将不会完成启动以保护数据一致性。

SecondaryNameNode

SecondaryNameNode主要负责定期的把edits文件中的内容合并到fsimage中

这个合并操作称为checkpoint,在合并的时候会对edits中的内容进行转换,生成新的内容保存到fsimage文件中。

【注意】在NameNode的HA架构中没有SecondaryNameNode进程,文件合并操作会由standby NameNode负责实现

所以在Hadoop集群中,SecondaryNameNode进程并不是必须的。

DataNode

DataNode是提供真实文件数据的存储服务,主要掌握两个概念,一个是block,一个是replication

Block

HDFS会按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个Block,HDFS默认Block大小是 128MB
如果你的文件较大的话,就会分为多个block存储,默认 hadoop3中一个block的大小为128M。根据字节进行截取,截取到128M就是一个block。如果文件大小没有默认的block块大,那最终就只有一个block,即如果一个文件小于一个数据块的大小,那么并不会占用整个数据块的存储空间。


假设我们上传了两个10M的文件 又上传了一个200M的文件

问1:会产生多少个block块? 4个
问2:在hdfs中会显示几个文件?3个


block块存放在哪些datanode上,只有datanode自己知道,当集群启动的时候,datanode会扫描自己节点上面的所有block块信息,然后把节点和这个节点上的所有block块信息告诉给namenode。这个关系是每次重启集群都会动态加载的【这个其实就是集群为什么数据越多,启动越慢的原因】。

namenode中不仅维护了文件和block块的信息 还维护了block块和所在的datanode节点的信息。可以理解为NameNode维护了两份关系:

  1. File 与Block list的关系,对应的关系信息存储在fsimage和edits文件中,当NameNode启动的时候会把文件中的元数据加载到内存中
  2. Datanode与Block的关系,对应的关系主要在集群启动的时候保存在内存中,当DataNode启动时会把当前节点上的Block信息和节点信息上报给NameNode

NameNode启动的时候会把文件中的元数据信息加载到内存中,然后每一个文件的元数据信息会占用150字节的内存空间,这个是恒定的,和文件大小没有关系,所以HDFS不适合存储小文件,其实主要原因就在这里,不管是大文件还是小文件,一个文件的元数据信息在NameNode中都会占用150字节,NameNode节点的内存是有限的,所以它的存储能力也是有限的,如果我们存储了一堆都是几KB的小文件,最后发现NameNode的内存占满了,确实存储了很多文件,但是文件的总体大小却很小,这样就失去了HDFS存在的价值。

Replication

Replication即副本表示数据有多少个备份

副本可在hdfs-site.xml中进行配置的

默认副本参数的配置为3,表示会有3个副本。

副本的作用:保证数据安全。

VERSION文件

DataNode的VERSION文件

[root@bigdata02 current]# cat VERSION 
#Wed Apr 08 20:30:04 CST 2020
storageID=DS-0e86cd27-4961-4526-bacb-3b692a90b1b0
# 集群ID
clusterID=CID-cc0792dd-a861-4a3f-9151-b0695e4c7e70
cTime=0
datanodeUuid=0b09f3d7-442d-4e28-b3cc-2edb0991bae3
storageType=DATA_NODE
layoutVersion=-57

NameNode的VERSION文件

[root@bigdata01 current]# cat VERSION 
#Wed Apr 08 20:30:00 CST 2020
namespaceID=498554338
#集群ID
clusterID=CID-cc0792dd-a861-4a3f-9151-b0695e4c7e70
cTime=1586268855170
storageType=NAME_NODE
# BlockID
blockpoolID=BP-1517789416-192.168.182.100-1586268855170
layoutVersion=-65

NameNode不要随便格式化,因为格式化了以后VERSION里面的clusterID会变,但是datanode的VERSION中的clusterID并没有变,所以就对应不上了。
如果确实要重新格式化的话需要把/data/hadoop_repo数据目录下的内容都清空,全部都重新生成是可以的。

HDFS的回收站

HDFS会为每一个用户创建一个回收站目录:/user/用户名/.Trash/,每一个被用户在Shell命令行删除的文件/目录,会进入到对应的回收站目录中,在回收站中的数据都有一个生存周期,也就是当回收站中的文件/目录在一段时间之内没有被用户恢复的话,HDFS就会自动的把这个文件/目录彻底删除,之后,用户就永远也找不回这个文件/目录了。

默认情况下hdfs的回收站是没有开启的,需要通过一个配置来开启,在core-site.xml中添加如下配置:

<property>
    <name>fs.trash.interval</name>
    <value>1440</value>
</property>

value的单位是分钟,1440分钟表示是一天的生存周期

如果删除的文件过大,超过回收站大小的话会提示删除失败,需要指定参数 -skipTrash ,指定这个参数表示删除的文件不会进回收站,例如:

[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm -r -skipTrash /user.txt
Deleted /user.txt

HDFS的安全模式

刚启动集群的时候去上传或者删除文件,会发现报错,提示NameNode处于safe mode。

这个属于HDFS的安全模式,因为在集群每次重新启动的时候,HDFS都会检查集群中文件信息是否完整,例如副本是否缺少之类的信息,所以这个时间段内是不允许对集群有修改操作的,如果遇到了这个情况,可以稍微等一会,等HDFS自检完毕,就会自动退出安全模式。
查看安全模式命令:

[root@bigdata01 hadoop-3.2.0]# hdfs dfsadmin -safemode get
Safe mode is ON
[root@bigdata01 hadoop-3.2.0]# hdfs dfsadmin -safemode leave
Safe mode is OFF

HDFS的高可用

在HDFS的设计中,NameNode也是可以支持多个的,一个主的,多个备用的,当主的挂掉了,备用的可以顶上去,这样就可以解决NameNode节点宕机导致的单点故障问题了,也就实现了HDFS的高可用
在这里插入图片描述
在任何时间点,只有一个NameNode是处于Active状态,其它的是处于Standby状态。

  • Active NameNode(简写为Active NN)负责所有的客户端的操作
  • Standby NameNode(简写为Standby NN)用来同步Active NameNode的状态信息,以提供快速的故障恢复能力。

为了保证Active NN与Standby NN节点状态同步,即元数据保持一致
除了DataNode(简写为DN)需要向这些NameNode发送block位置信息外,还构建了一组独立的守护进程”JournalNodes”(简写为JN),用来同步Edits信息。
当Active NN执行任何有关命名空间的修改,它需要持久化到一半以上的JNs上,而Standby NN负责观察JNs的变化,读取从Active NN发送过来的Edits信息,并更新自己内部的命名空间。一旦Active NN遇到错误,Standby NN需要保证从JNs中读出了全部的Edits,然后切换成Active状态,如果有多个Standby NN,还会涉及到选主的操作,选择一个切换为Active 状态。

元数据

元数据分为静态元数据和动态元数据。
静态的是fsimage和edits,其实fsimage是由edits文件合并生成的,所以只需要保证edits文件内容的一致性。这个就是需要保证多个NameNode中edits文件内容的事务性同步。这块的工作是由JournalNodes集群进行同步的。

动态数据是指block和DataNode节点的信息,**当DataNode启动的时候,上报数据信息的时候需要向每个NameNode都上报一份。**这样就可以保证多个NameNode的元数据信息都一样了,当一个NameNode挂掉以后,立刻从Standby NN中选择一个进行接管,没有影响,因为每个NameNode 的元数据时刻都是同步的。

【注意】注意:使用高可用(HA)的时候,不能启动SecondaryNameNode,会出错。
之前是SecondaryNameNode负责合并edits到fsimage文件,那么现在这个工作被standby NN负责了。

NameNode 切换可以自动切换,也可以手工切换,如果想要实现自动切换,需要使用到zookeeper集群。使用zookeeper集群自动切换的原理:
当多个NameNode 启动的时候会向zookeeper中注册一个临时节点,当NameNode挂掉的时候,这个临时节点也就消失了,这属于zookeeper的特性,这个时候,zookeeper就会有一个watcher监视器监视到,就知道这个节点挂掉了,然后会选择一个节点转为Active,把down掉的节点转为Standby。

HDFS的高扩展

一个主NameNode,多个备用的NameNode的方案只能解决NameNode的单点故障问题,无法解决单个NameNode内存不够用的问题,但官方提供了Federation机制,可以翻译为联邦,它可以解决单节点内存不够用的情况,这个就是HDFS的高扩展。
HDFS Federation可以解决单一命名空间存在的问题,使用多个NameNode,每个NameNode负责一个命令空间。Federation,一般也会和前面我们讲的HA结合起来使用,如下图所示。
在这里插入图片描述
这里面用到了4个NameNode和6个DataNode

  • NN-1、NN-2、NN-3、NN-4
  • DN-1、DN-2、DN-3、DN-4、DN-5、DN-6、

其中NN-1、和NN-3配置了HA,提供了一个命令空间,/share,其实可理解为一个顶级目录

NN-2和NN-4配置了HA,提供了一个命名空间,/user

这样后期我们存储数据的时候,就可以根据数据的业务类型来区分是存储到share目录下还是user目录下,此时HDFS的存储能力就是/share和/user两个命名空间的总和了。

参考文献

慕课网 https://www.imooc.com/wiki/BigData

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是希望

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值