Java大数据平台开发 学习笔记(63)—— HDFS 原理(附 Hadoop 百度云盘下载地址)


一、简介

1.1、概述

  • HDFS(Hadoop Distribute File System)是Hadoop提供的分布式文件存储系统
  • HDFS是仿照Google File System(GFS)来实现的

1.2、特点

  1. 能够存储超大文件 - 切块
  2. 能够快速的应对和检测故障 - 心跳
  3. 能够在相对廉价的机器上进行横向扩展
  4. 不支持低延迟的响应
  5. 不建议存储小文件 - 一个文件大小<Block*0.8
  6. 简化的一致性模型 - 一次写入多次读取,不允许修改但是允许追加写入
  7. 提供了流式访问模型
  8. 支持弱事务或者不支持事务。在样本量足够大的前提下,允许产生一定的容错误差

二、基本理论

2.1、概述

  1. HDFS本身是一个典型的主从(MS)结构:主节点是NameNode,从节点是DataNode
    在HDFS中,会对上传的文件来进行切分,切成1个到多个数据块(Block)
    HDFS会对存入的数据自动的进行备份。每一个备份称之为是一个副本(replication)。默认副本数量为3
    HDFS仿照Linux设计了一套虚拟文件系统,保证上传的文件可以放在不同的路径下。HDFS的根路径是/

2.2、Block - 数据块

  1. Block是HDFS中数据存储的基本单位。在HDFS中,所有的文件都是以Block形式存储的
  2. 在Hadoop2.0中,Block的默认(最大)大小是134217728B(即128M,通过dfs.blocksize属性来调节,单位是字节,放在hdfs-site.xml文件中)
  3. 如果一个文件不到一个Block大小,那么这个文件本身是多大,对应的Block就是多大。例如如果一个文件只有10M,对应的Block就是10M
  4. HDFS会给每一个Block分配一个唯一的BlockID
  5. 切块的意义
    a 为了能够存储超大文件
    b 为了能够进行快速备份

2.3、NameNode

  1. NameNode是HDFS的主节点,也是HDFS的核心节点。默认情况下,Hadoop2.0集群中只有1个
    NameNode,意味着存在单点故障
  2. NameNode负责记录元数据,管理DataNode
  3. 元数据(metadata)是用于描述数据的数据,可以看作是一个账本
  4. HDFS中的元数据包含了30多个属性
  5. NameNode会将元数据维系在磁盘以及内存中
    a 维系在磁盘中的目的是为了可靠性
    b 维系在内存中的目的是为了读写快
  6. 元数据在磁盘中的存储位置由hadoop.tmp.dir属性来决定。如果不指定,那么元数据默认是放在/tmp目录下
  7. dfs目录下的in_use.lock标记当前服务器是否已经启动了指定的进程
  8. 和元数据相关的文件
    a edits:写操作文件。当NameNode接收到写请求的时候,会将请求命令记录到edits文件中
    b fsimage:元映像文件。用于记录元数据的。注意,fsimage文件中的元数据和内存中的元数据不同步
  9. 当NameNode接收到写请求的时候,会先将这个写请求记录到edits_inprogress文件。如果记录成功,那么NameNode会去修改内存中的元数据,修改完成之后,会给客户端返回一个成功信号ACK。此时,并没有修改fsimage文件中的元数据,所以fsimage文件中的元数据和内存中的元数据不是同步的
  10. 当达到指定条件的时候,edits_inprogress文件会滚动生成一个edits文件,同时产生一个新的edits_inprogress文件。后续来的新的写操作会继续记录到新的edits_inprogress文件中。滚动生成的edits文件中的内容会一一取出,然后再次更新fsimage文件中的元数据
  11. edits_inprogress文件的滚动条件
    a 空间:当edits_inprogress文件达到指定大(默认是64M,通过fs.checkpoint.size属性来指定,单位是字节,放在core-site.xml文件中)小的时候,会滚动生成一个edits文件
    b 时间:当距离上一次滚动达到指定的时间间隔(默认是1H,通过fs.checkpoint.period属性来指定,单位是秒,放在core-site.xml文件中)的时候,那么edits_inprogress文件也会产生滚动
    c 重启:当NameNode被重启的时候,会自动的触发edits_inprogress文件的滚动
    d 强制:通过hadoop dfsadmin -rollEdits命令来强制edits_inprogress文件的滚动
  12. 在HDFS第一次启动的时候,启动之后1min,会自动产生一次滚动,生成一个edits文件。之后会按照指定的时间间隔来滚动
  13. 每一个fsimage文件都会对应一个md5文件,md5文件对元数据文件来进行校验
  14. 在HDFS中,会将每一次的写操作看作是一个事务,分配一个全局递增的事务id,简写为txid
  15. NameNode通过心跳机制来管理DataNode
  16. DataNode定时(默认是3s,通过dfs.heartbeat.interval属性来指定,单位是s,放在hdfs-site.xml中)给NameNode的心跳信号。如果超过10min,NameNode没有收到DataNode的心跳,那么此时NameNode会认为这个DataNode已经lost(丢失),那么NameNode就会将这个DataNode的数据备份到其他节点上来保证副本数量
  17. 心跳信号
    a clusterid - 集群编号
    b DataNode的状态(预服役、服役、预退役)
    c DataNode中存储的Block的情况
  18. 安全模式(safe mode)
    a NameNode重启之后,会自动进入安全模式
    b NameNode先将edits_inprogress文件滚动生成edits文件
    c 滚动完成之后,NameNode会更新fsimage文件中的元数据
    d 更新完成之后,NameNode会将fsimage文件中的元数据加载到内存中
    e 加载完元数据之后,NameNode就会等待DataNode的心跳
    f 如果NameNode没有收到DataNode的心跳,那么NameNode会将这个DataNode上的数据重新备份保证集群中的副本数量
    g 如果NameNode收到DataNode的心跳,会校验心跳信息。如果校验成功,则NameNode会自动退出安全模式;如果校验失败,则NameNode会试图恢复数据,恢复完成之后,会重新校验
  19. 如果在实际生产过程中,发现NameNode处在安全模式中,需要等待一段时间;如果在合理的时间内,NameNode都没有退出安全模式,那么说明数据产生了不可逆的丢失,此时需要强制退出安全模式:hadoop dfsadmin -safemode leave
  20. 在安全模式下,HDFS集群只提供读服务不提供写服务
  21. 正因为安全模式的存在,所以副本数量不能超过节点数量

2.4、DataNode

  • DataNode是用于存储数据的,数据是以Block形式来存储
  • DataNode将数据存储在磁盘上,在磁盘上的存储位置由hadoop.tmp.dir属性来决定
  • DataNode的状态:预服役、服役、预退役、退役、丢失

2.5、SecondaryNameNode

  1. SecondaryNameNode并不是NameNode的备份,而是辅助NameNode完成edits_inprogress文件的滚动和fsimage文件的更新
  2. 如果在集群中存在SecondaryNameNode,那么edits_inprogress文件的滚动和fsimage文件的更新由SecondaryNameNode来完成;如果集群中没有SecondaryNameNode,那么上述这些操作由NameNode自己完成
  3. 到目前为止,在Hadoop2.0中只支持两种结构
    a 1个NameNode+1个SecondaryName+n个DataNode
    b 2个NameNode(Active+Standby)+n个DataNode
  4. 在HDFS中,NameNode处在核心位置,如果NameNode宕机,那么HDFS集群就无法对外提供服务,所以必须考虑对NameNode来进行备份。在这种情况下,就会选择上述的第二种结构来搭建集群,来保证NameNode的高可用

2.6、副本放置策略

  1. 在HDFS中,默认支持的是多副本策略。如果不指定,则默认情况下副本数量为3。通过dfs.replication属性来决定,放在hdfs-site.xml中
  2. 如果没有开启机架感知策略的前提下,HDFS中的多个副本是放在相对空闲的节点上
  3. 如果开启了机架感知策略,那么HDFS在放置副本的时候就需要使用副本放置策略
    a 第一个副本
    集群内部上传:谁上传就放在谁身上
    集群外部上传:谁空闲就放在谁身上
    b 第二个副本
    Hadoop2.7之前:第二个副本放在和第一个副本不同机架的节点上
    Hadoop2.7开始:第二个副本放在和第一个副本相同机架的节点上
    c 第三个副本
    Hadoop2.7之前:第三个副本放在和第二个副本相同机架的节点上
    Hadoop2.7开始:第三个副本放在和第二个副本不同机架的节点上
    更多副本:谁空闲就放在谁身上

2.7、机架感知策略

  1. 机架感知策略默认是不开启的
  2. 如果需要开启机架感知策略,那么需要在hadoop-site.xml文件中通过tepology.script.file.name属性来指定,属性值的是脚本文件的名字
  3. 脚本文件可以是Python/Shell脚本,需要在这个脚本文件中定义一个Map来存储机架结构。在这个Map中,键是主机名或者是IP,值是机架名。只要值一致,那么就表示将键对应的节点配置了同一个机架上
  4. 机架感知策略中的机架,实际上是一个逻辑机架,也就意味着可以将不同物理机架上的节点配置在同一个逻辑机架上。但是在实际生产过程中,为了方便管理,往往会将同一个物理机架上的节点配置在同一个逻辑机架上

2.8、基本命令

在这里插入图片描述

2.9、回收站机制

  1. 默认情况下,HDFS的回收站机制是不开启的,也就意味着删除命令会立即生效且不可逆
  2. 开启回收站
    在这里插入图片描述

三、流程

3.1、上传/写流程

  1. 客户端发起RPC请求到NameNode,请求上传文件
  2. NameNode收到请求之后,先进行校验
    a 先校验是否有写入权限
    b 再校验是否有同名文件 - FileAlreadyExistException
  3. 如果校验失败,则会报错;如果校验成功,那么NameNode会给客户端返回一个成功信号表示允许上传
  4. 客户端收到成功信号之后,会再次发起请求,请求获取第一个Block的存储位置
  5. 当NameNode收到请求之后,会将这个Block的存储位置(DataNode的主机名/IP)放到队列中返回给客户端。默认情况下,一个Block对应了3个副本,所以队列中默认会放3个DataNode的主机名/IP
  6. 当客户端收到队列之后,会将位置从队列中全部取出来,然后从这些位置中选取较近(网络拓扑距离的远近)的节点将当前Block的第一个副本写入
  7. 第一个副本所在的节点会通过pipeline(管道,本质上就是NIO中的Channel)将这个Block的第二个副本写入到对应的节点上。第二个副本写完之后,通过pipeline将数据写到第三个副本所在的节点上
  8. 当最后一个副本写完之后,这个副本所在的节点会给上一个副本所在的节点返回一个ACK信号,依次前推。直到第一个副本所在的节点也收到ACK,那么会给客户端来返回一个ACK
  9. 当客户端收到ACK之后,会向NameNode发送请求,请求获取下一个Block的地址,重复5.6.7.8.9步骤,直到所有的Block全部写完
  10. 当所有的Block写完之后,客户端会给NameNode发送一个结束信号。NameNode在收到信号之后会关闭这个文件(实际上就是关流)。文件一旦关闭,就不能修改

3.2、下载/读流程

  1. 客户端发起RPC请求到NameNode,请求读取数据
  2. NameNode收到请求之后,会先校验。如果校验失败,则直接报错;如果校验成功,则NameNode会给客户端返回一个成功信号表示允许读取
  3. 客户端在收到信号之后,会再次发起请求到NameNode,请求获取第一个Block的位置
  4. NameNode收到请求之后,会Block的存储位置放到队列中返回给客户端
  5. 客户端收到队列之后,会将Block的存储位置从队列中全部取出,从中选取一个较近的节点来读取这个Block
  6. 客户端在读取到Block之后,会对这个Block进行checksum校验(例如Block的大小、内容等)
  7. 如果校验失败,则客户端会给NameNode发送信号,会从剩余的地址中重新选取位置重新读取重新校验;如果校验成功,那么客户端会向NameNode发送请求,请求获取下一个Block的地址,直到读取完所有的Block
  8. 当客户端读取完所有的Block之后,会给NameNode发送结束信号。NameNode收到信号之后,会关闭文件

3.3、删除流程

  1. 客户端发起RPC请求到NameNode,请求删除文件
  2. NameNode收到请求之后,先进行校验
    先校验文件是否存在 - FileNotFoundException
    再检验是否有写权限 - AccessControlException:Permission Denied
  3. 如果校验失败,则直接报错;如果校验成功,NameNode会将这个命令记录到edits_inprogress文件中,修改内存中的元数据,修改完成之后,会给客户端返回一个ACK信号。注意:此时文件并没有真正删除而是依然存储在DataNode上
  4. NameNode等待DataNode的心跳。在收到心跳之后,NameNode会校验心跳,然后在心跳响应中要求DataNode删除对应的Block
  5. DataNode在收到心跳响应之后,才会删除对应的Block。直到此时,文件才真正从HDFS上移除

四、hadoop 搭建集群

4.1、伪分布式集群搭建

1.	安装JDK1.8
2.	关闭防火墙
	service iptables stop
	chkconfig iptables off
	###如果不能修改主机名,则关闭云主机的初始化服务
	service cloud-init stop
	service cloud-init-local stop
	chkconfig cloud-init off
	chkconfig cloud-init-local off
3.	修改主机名 - Hadoop集群中,不建议主机名中出现-或者_
	vim /etc/sysconfig/network
	修改HOSTNAME属性
	HOSTNAME=hadoop01
	保存退出,重新生效
	source /etc/sysconfig/network
4.	配置IP和主机名的映射
	vim /etc/hosts
	添加IP 主机名映射,例如
	127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
	::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
	10.9.162.133 hadoop01
	保存退出
5.	重启
	reboot
6.	配置免密互通
	产生密钥:ssh-keygen
	拷贝公钥:ssh-copy-id root@hadoop01
	云主机密码:tarena2017Up;
	测试是否成功:ssh root@hadoop01
	如果不需要密码:logout
	*** 如果出现Name or Service not known或者Unknown host,那么说明IP映射错误
7.	进入/home/software目录
	cd /home/software
8.	下载Hadoop安装包
	wget http://bj-yzjd.ufile.cn-north-02.ucloud.cn/hadoop-2.7.1_64bit.tar.gz
9.	解压
	tar -xvf hadoop-2.7.1_64bit.tar.gz
10.	进入子目录
	cd hadoop-2.7.1/etc/hadoop
11.	编辑
	vim hadoop-env.sh
	修改
	export JAVA_HOME=/home/presoftware/jdk1.8
	export HADOOP_CONF_DIR=/home/software/hadoop-2.7.1/etc/hadoop/
	保存退出,重新生效
	source hadoop-env.sh
12.	编辑
	vim core-site.xml
	添加
	<property>
            <name>fs.defaultFS</name>
            <value>hdfs://hadoop01:9000</value>
    </property>
    <property>
            <name>hadoop.tmp.dir</name>
            <value>/home/software/hadoop-2.7.1/tmp</value>
    </property>
13.	编辑
	vim hdfs-site.xml
	添加
	<property>
            <name>dfs.replication</name>
            <value>1</value>
    </property>
14.	编辑
	cp mapred-site.xml.template mapred-site.xml
	vim mapred-site.xml
	添加
	<property>
            <name>mapreduce.framework.name</name>
            <value>yarn</value>
    </property>
15.	编辑
	vim yarn-site.xml
	添加
	<property>
	        <name>yarn.resourcemanager.hostname</name>
	        <value>hadoop01</value>
	</property>
	<property>
	        <name>yarn.nodemanager.aux-services</name>
	        <value>mapreduce_shuffle</value>
	</property>
16.	编辑
	vim slaves
	添加云主机的名字
17.	配置环境变量
	vim /etc/profile
	在文件末尾追加
	export HADOOP_HOME=/home/software/hadoop-2.7.1
	export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
	保存退出,重新生效
18.	Hadoop第一次启动的时候需要进行格式化
	hadoop namenode -format
	如果出现Storage directory /home/software/hadoop-2.7.1/tmp/dfs/name has been successfully formatted表示格式化成功
	***如果出现Command not found:环境变量配置错误或者是配置完环境变量没有source
	***如果出现其他错误,那么说明配置文件写错,查找core-site.xml或者是hdfs-site.xml
	***如果出现JDK找不到,那么说明hadoop-env.sh配置错误或者没有source
	***上述错误修改完成之后,查看/home/software/hadoop-2.7.1目录下是否tmp,如果有tmp目录,修改完错误之后删除这个目录再重新格式化
19.	启动Hadoop
	start-all.sh
20.	通过jps查看进程
	Jps
	NameNode --- 50070
	DataNode --- 50075
	SecondaryNameNode --- 50090
	ResourceManager --- 8088
	NodeManager

4.2、完全分布式集群搭建

1.	三台云主机关闭防火墙
2.	三台云主机安装JDK
3.	关闭三台云主机开启初始化
   service cloud-init-local stop
   service cloud-init stop
   chkconfig cloud-init-local off
   chkconfig cloud-init off
4.	修改三台云主机的主机名
   vim /etc/sysconfig/network
   修改HOSTNAME属性
   第一台云主机可以改为hadoop01,第二台云主机改为hadoop02,第三台云主机改为hadoop03
   改完之后保存退出,重新生效
   source /etc/sysconfig/network
5.	三台云主机进行IP映射
   vim /etc/hosts
   注意,修改完成之后,三台云主机中hosts文件的内容应该一模一样!!!
6.	三台云主机重启
   reboot
7.	三台云主机需要相互之间免密
   ssh-keygen
   ssh-copy-id root@hadoop01
   ssh-copy-id root@hadoop02
   ssh-copy-id root@hadoop03
   云主机密码:tarena2017Up;
   ssh hadoop01
   如果不需要输入密码,则logout
   ssh hadoop02
   如果不需要输入密码,则logout
   ssh hadoop03
   如果不需要输入密码,则logout
8.	先将第一台云主机的Hadoop的伪分布式保留下来
   cd /home/software/
   mv hadoop-2.7.1/ hadoop-alone
9.	三台云主机都进入software目录,下载配置好的Hadoop分布式安装包
   cd /home/software/
   wget http://bj-yzjd.ufile.cn-north-02.ucloud.cn/hadoop-dist.tar.gz
10.	解压安装包
   tar -xvf hadoop-dist.tar.gz
11.	修改三台云主机的环境变量
   vim /etc/profile
   在文件末尾添加
   export HADOOP_HOME=/home/software/hadoop-2.7.1
   export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
   保存退出,重新生效
   source /etc/profile
12.	三台云主机启动Zookeeper
   cd /home/software/zookeeper-3.4.8/bin
   sh zkServer.sh start
   sh zkServer.sh status
13.	在第一台云主机格式化Zookeeper,实际上就是在Zookeeper上注册Hadoop节点
   hdfs zkfc -formatZK
   如果出现Successfully created /hadoop-ha/ns in ZK.表示格式化成功
14.	在三台云主机上启动JournalNode
   hadoop-daemon.sh start journalnode
15.	在第一台云主机上格式化NameNode
   hadoop namenode -format
   如果出现 Storage directory /home/software/hadoop-2.7.1/tmp/hdfs/name has been successfully formatted.表示格式化成功
16.	在第一台云主机上启动NameNode
   hadoop-daemon.sh start namenode
17.	在第二台云主机上格式化NameNode
   hdfs namenode -bootstrapStandby
   如果出现Storage directory /home/software/hadoop-2.7.1/tmp/hdfs/name has been successfully formatted.表示格式化成功
18.	在第二台云主机上启动NameNode
   hadoop-daemon.sh start namenode
19.	在三台云主机上启动DataNode
   hadoop-daemon.sh start datanode
20.	在第一台和第二台云主机上启动FailOverController
   hadoop-daemon.sh start zkfc
21.	在第三台云主机上启动YARN
   start-yarn.sh
22.	在第一台云主机上启动ResourceManager
   yarn-daemon.sh start resourcemanager

通过jps查看
第一个节点会出现8个进程
Jps
NameNode
DataNode
JournalNode
DFSZKFailoverController
ResourceManager
NodeManager
QuorumPeerMain
第二个节点会出现7个进程
Jps
NameNode
DataNode
JournalNode
DFSZKFailoverController
NodeManager
QuorumPeerMain
第三节点会出现6个进程
Jps
DataNode
JournalNode
ResourceManager
NodeManager
QuorumPeerMain

问题解决:
   1. Hadoop集群在启动的时候,必须先启动Zookeeper后启动hadoop
   2. 如果在上述步骤中,出现Name or Service not Known或者Unknown host,表示IP或者主机名配置错误
   3. 如果出现IllegalArgumentException,检查命令是否准确
   4. 如果在格式化Zookeeper的时候出现HA is not enable/available,那么表示系统兼容 - 重装云主机系统
   5. 如果缺少NameNode/DataNode/JournalNode/DFSZKFailoverController,通过命令hadoop-daemon.sh start namenode/datanode/jounalnode/zkfc。例如hadoop-daemon.sh start datanode
   6. 如果缺少了ResourceManager/NodeManager,那么通过yarn-daemon.sh start resourcemanager/nodemanager。例如yarn-daemon.sh start nodemanager
   7. 如果在启动过程中出现xxx already running as xxx,但是通过jps又没有发现这个进程,那么通过kill -9 xxx来杀死这个进程,然后重新启动这个进程
   8. 如果缺少了QuorumPeerMain,那么说明Zookeeper启动错误
   9. 如果出现Command not found,那么表示命令错误或者是环境变量配置错误
   10. 如果出现所有命令不生效,那么先从另一台云主机上将profile下载下来,然后上传到有问题的云主机上,替换掉原来的profile,重启云主机

五、hadoop 下载地址

百度云盘链接:https://pan.baidu.com/s/1jCv_dEtussA5Z_4ii40l2Q(提取码:aj8n
(如果提示过期,请评论再次更新)


• 由 ChiKong_Tam 写于 2021 年 1 月 8 日

猜你喜欢

转载自blog.csdn.net/qq_42209354/article/details/112302143
今日推荐