第五章:HDFS分布式文件系统(详述及部署)
一个初学者的大数据学习过程
文章目录
1.HDFS概述
1.1 定义
HDFS(Hadoop Distributed File System)是Hadoop项目的核心子项目,是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开发的,可以运行于廉价的商用服务器上。HDFS 源于 Google 在2003年10月份发表的GFS(Google File System)论文。 它其实就是 GFS 的一个克隆版本。 HDFS(Hadoop Distributed File System)是Hadoop项目的核心子项目,是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开发的,可以运行于廉价的商用服务器上。HDFS 源于 Google 在2003年10月份发表的GFS(Google File System)论文。 它其实就是 GFS 的一个克隆版本。
1.2 特点
随着互联网的快速发展,数据量越来越多,一台服务器的存储有限,所以数据应该分配到更多的机器的磁盘中,因此需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统 ,它具有高容错的特点,它可以部署在廉价的通用硬件上,提供高吞吐率的数据访问,适合那些需要处理海量数据集的应用程序。它具有如下特点:
- 高容错性
上传的数据自动保存多个副本。它是通过增加副本的数量,来增加它的容错性。如果某一个副本丢失,HDFS机制会复制其他机器上的副本,而我们不必关注它的实现。 - 支持超大文件
超大文件在这里指的是几百MB、几百GB甚至几TB大小的文件,一般来说,一个Hadoop文件系统会存储T (1TB=1024GB), P (1P=1024T)级别的数据。 - 流式数据访问
HDFS处理的数据规模都比较大,应用一次需要访问大量的数据。同时,这些应用一般是批量处理,而不是用户交互式处理。HDFS使应用程序能够以流的形式访问数据集,注重的是数据的吞吐量,而不是数据访问的速度。 - 简化的一致性模型
大部分的HDFS程序操作文件时需要一次写入,多次读取。在HDFS中,一个文件一旦经过创建、写入、关闭后,一般就不需要修改了。这样简单一致性模型,有利于提供高吞吐量的数据访问模型。
2.HDFS体系结构
2.1 Client
- 实现文件切分。
- 与 NameNode 交互,获取文件的位置信息。
- 跟 DataNode 交互,读取对应的数据块。
- 管理和访问HDFS。
2.2 NameNode
- 管理 HDFS 的名称空间。
- 管理数据块的映射关系。
- 配置副本策略。
- 客户端的读写请求。
2.3 DataNode
- 存储实际的数据块。
- 执行数据块的读/写操作。
2.4 Block(数据块)
一个文件是被切分成多个Block,并且每个block有多个副本,这些副本被分布在多个datanode上,它是HDFS的最小存储单元。
2.5 元数据
是文件系统中文件和目录的信息以及文件和block的对应关系。
2.6 命名空间镜像(FSlmage)
HDFS的目录树及文件/目录元信息是保存在内存中的,如果节点掉电或进程崩溃,数据将不再存在,必须将上述信息保存到磁盘,Fslmage就是保存某一个时刻元数据的信息的磁盘文件。
2.7 镜像编辑日志(EditLog)
对内存目录树的修改,也必须同步到磁盘元数据上,但每次修改都将内存元数据导出到磁盘,显然是不现实的,为此,namenode引入了镜像编辑日志,将每次的改动都保存在日志中,如果namenode机器宕机或者namenode进程挂掉后可以使用FSlmage和EditLog联合恢复内存元数据。
3.HDFS HA (高可用)
3.1 HDFS HA-Namenode HA工作原理
- 两台独立的机器的来配置NameNode角色,无论在任何时候,集群中只能有一个NameNode作为Active状态,而另一个是Standby状态。Active状态的NameNode负责集群中所有的客户端操作,状态为Standby的NameNode这时候仅仅扮演一个Slave的角色,以便于在任何时候Active的NameNode挂掉时能够第一时间接替它的任务,成为主NameNode,达到一个热备份的效果.
- 为了保持从NameNode与主NameNode的元数据保持一致,他们之间的交互通过一系列守护的轻量级进程JournalNode来完成,当任何修改操作在主NameNode上执行时,它同时也会记录修改log到至少半数以上的JornalNode中,这时状态为Standby的NameNode监测到JournalNode里面的同步log发生变化了,会读取JornalNode里面的修改log,然后同步到自己的的目录镜像树里面.
- 当发生故障时,Active的NameNode挂掉后,Standby的NameNode会在它成为Active NameNode前,读取所有的JournalNode里面的修改日志,这样就能高可靠的保证与挂掉的NameNode的目录镜像树一致,然后无缝的接替它的职责,维护来自客户端请求,从而达到一个高可用的目的。
- 为了达到快速容错掌握全局的目的,Standby角色也会接受来自DataNode角色汇报的块信息。
3.2 HDFS HA-ZKFailoverController
ZKFailoverController作为独立的进程运行,简称ZKFC,对NameNode的主备切换进行总体控制。ZKFailoverController能及时检测到NameNode的健康状况,在主NameNode故障时借助Zookeeper实现自动的主备选举和切换.每个运行NameNode的机器上都会运行一个ZKFC。
ZKFC的作用如下:
-
NameNode健康状况监控:ZKFC定期以RPC的方式向本地的NameNode发送健康检查命令,只要NameNode及时回复自己是健康的,那么ZKFC则认为NameNode是健康的。如果NameNode宕机、卡死,则ZKFC则认为NameNode是不健康的。
-
ZK会话管理: 当本地的NameNode是健康的,ZKFC则以心跳的方式保持一个会话。如果本地的NameNode是Active的,ZKFC也在ZK上持有一个特殊lock znode,如果ZKFC检测到NameNode时不健康的,则停止向ZK上报心跳,会话失效,Lock node过期删除。
-
ZK选举:如果本地的NameNode是健康的,ZKFC也没有看到其他NameNode持有lock znode,它将试着获取lock znode,如果成功,即赢得了选举,则它本地的namenode变为active。
ZKFC为什么要作为一个deamon进程从NN分离出来?
(这里NN为NameNode的简写,DN为DataNode的简写)
- 防止因为NN的GC失败导致心跳受影响。
- FailoverController功能的代码应该和应用的分离,提高的容错性。
- 使得主备选举成为可插拔式的插件。
3.3 HDFS HA-共享存储QJM
NameNode记录了HDFS的目录文件等元数据,客户端每次对文件的增删改等操作,Namenode都会记录一条日志,叫做editlog,而元数据存储在fsimage中。为了保持Stadnby与active的状态一致,standby需要尽量实时获取每条editlog日志,并应用到FsImage中。这时需要一个共享存储存放editlog,standby能实时获取日志。
有两个关键点需要保证:
- 共享存储是高可用的。
- 需要防止两个NameNode同时向共享存储写数据导致数据损坏。共享存储常用的方式是Qurom Journal Manager,它包含多个JournalNode 。
QJM可以认为是包含一些JournalNode的集群,JournalNode运行在不同的机器上,每个JournalNode是一个很轻量的守护进程,所以可以部署在hadoop集群的节点上,QJM中至少要有3个JournalNode,因为edit log必须要写到JournalNodes中大部分节点中,比如运行3,5,7个JournalNode,如果你运行了N个JournalNode,那么系统可以容忍最多(N-1)/2个节点失败。
共享存储实现逻辑:
- 初始化后,Active NN把editlog写到大多数JN并返回成功(即大于等于N+1)即认定写成功。
- Standby NN定期从JN读取一批editlog,并应用到内存中的FsImage中。
- NameNode每次写Editlog都需要传递一个编号Epoch给JN,JN会对比Epoch,如果比自己保存的Epoch大或相同,则可以写,JN更新自己的Epoch到最新,否则拒绝操作。在切换时,Standby转换为Active时,会把Epoch+1,这样就防止即使之前的NameNode向JN写日志,即使写也会失败。
3.4 HDFS HA-防止脑裂
确保只有一个NN能命令DN。
- 每个NN改变状态的时候,向DN发送自己的状态和一个序列号。
- DN在运行过程中维护此序列号,当failover时,新的NN在返回DN心跳时,会返回自己的active状态和一个更大的序列号。DN接收到这个返回时,认为该NN为新的active。
- 如果这时原来的active(比如GC)恢复,返回给DN的心跳信息包含active状态和原来的序列号,这时DN就会拒绝这个NN的命令。
4.HDFS 安装部署
4.1 下载 Hadoop 安装包
Apache 版本下载地址:
https://archive.apache.org/dist/hadoop/common/
CDH 版本下载地址:
http://archive-primary.cloudera.com/cdh5/cdh/5/
下 载 对 应 版 本 Hadoop , 这 里 下 载 hadoop-2.6.0-cdh5.10.0.tar.gz 版本 , 并 上 传 至/home/hadoop/app 目录下。
4.2 解压 Hadoop
通过 tar -zxvf 命令对 Hadoop 安装包进行解压即可。
4.3 创建软连接
为了方便版本的更换和学习使用,可以创建 hadoop 软连接指向 hadoop 真实安装路径。可以使用如下命令:
ln -s hadoop-xxx hadoop
1.4 修改配置文件
依次分别修改 core-site.xml、hdfs-site.xml、slaves、hadoop-env.sh 配置文件
1.5 安装目录同步到其他节点
将 hadoop 安装目录整体同步到其他节点:
deploy.sh hadoop-2.6.0 /home/hadoop/app/ slave
各个节点分别创建软连接:
ln -s hadoop-2.6.0 hadoop
1.6 创建规划的目录
runRemoteCmd.sh “mkdir -p /home/hadoop/data” all
1.7 启动并测试 hdfs
1.7.1 启动所有 Zookeeper 节点
runRemoteCmd.sh “/home/hadoop/app/zookeeper/bin/zkServer.sh start” all
1.7.2 启动所有 journalnode 节点
runRemoteCmd.sh “/home/hadoop/app/hadoop/sbin/hadoop-daemon.sh start journalnode” all
1.7.3 nn1 节点格式化 namenode
bin/hdfs namenode –format
1.7.4 nn1 节点格式化 zkfc
bin/hdfs zkfc -formatZK
1.7.5 nn1 节点启动 namenode
bin/hdfs namenode
1.7.6nn2 节点同步 nn1 节点元数据信息
bin/hdfs namenode –bootstrapStandby
nn2 同步完 nn1 节点信息之后,Ctrl+c 关闭 nn1 节点 namenode 进程。
1.7.7 关闭所有节点 journalnode
runRemoteCmd.sh “/home/hadoop/app/hadoop/sbin/hadoop-daemon.sh stop journalnode” all
1.7.8 一键启动 hdfs
sbin/start-dfs.sh
hdfs 启动之后可以通过如下命令查看 namenode 状态:
bin/hdfs haadmin -getServiceState nn1
bin/hdfs haadmin -getServiceState nn2
一键关闭 hdfs:sbin/stop-dfs.sh
1.7.9 Web 界面查看 hdfs
http://master:50070
1.7.10 测试 hdfs
本地目录新建文件 wd.txt
[hadoop@master hadoop]$ cat wd.txt
hadoop spark
hadoop spark
hadoop spark
Hdfs 文件系统创建 test 目录
[hadoop@master hadoop]$ bin/hdfs mkdir /test
[hadoop@master hadoop]$ bin/hdfs dfs -ls /
将 wd.txt 文件上传至/test 目录下
bin/hdfs dfs -put wd.txt /test/
bin/hdfs dfs -ls /test