章节内容介绍
1) HDFS的基本概念
2) HDFS的架构说明 //理解 + 记忆
3) HDFS中副本机制和机架感知原理 //理解 + 记忆
4) HDFS的shell命令的操作: //基本命令(重点关注) + 高级命令
5) HDFS的namenode和datanode的基本功能详细说明 //理解
6) HDFS如何读写数据操作 //理解 + 记忆
7) HDFS的元数据的辅助管理原理 //理解 + 记忆
以下是具体的知识点
-
HDFS的基本的介绍
HDFS的概念:
//大白话: 全称为Hadoop Distributed File System, Hadoop分布式文件系统, 用来将数据跨多台机器 来完成数据的存储工作的.
就是 hadoop的 分布式文件存储系统. 主要是用来存储海量数据(TB PB 以上级别), 并且为用户提供
一个统一的资源访问的接口, 让用户感觉到, 只是在访问一个普通的文件系统.
虽然是分布式的, 但是让用户操作起来就像在操作"一台机器", 提高用户体验.如何实现一个分布式的文件系统呢?
你出 5毛 我出5毛 我们一起凑成一块的过程…HDFS 本质上就是一个分布式存储系统的软件, 通过这个软件, 实现将多个服务器的磁盘进行打通操作, 构建一个
更大的存储空间, 交由HDFS进行管理, 而数据, 最终都是落在各个服务器的本地磁盘上.
//详见图片, 如何实现一个分布式存储系统. -
HDFS的设计目标及其应用场景
2.1) HDFS的设计目标
1. 硬件故障是常态.
//HDFS将有成百上千的服务器组成,每一个组成部分都有可能出现故障。因此故障的检测和自动快速恢复是HDFS的核心架构目标。
//例如: 阿里, 百度, 京东等的集群, 硬盘出现故障的几率太高了, 因为机器太多了.2. HDFS上的应用与一般的应用不同,它们主要是以流式读取数据。 //HDFS被设计成适合批量处理,而不是用户交互式的。相较于数据访问的反应时间,更注重数据访问的高吞吐量。 //交互式解释: 你要数据, 我直接给你. 因为HDFS存的就是太多了, 达不到交互式, 如果你要一个大文件,它 可能十几分钟后给你. 3. 典型的HDFS文件大小是GB到TB的级别。所以,HDFS被调整成支持大文件。 //它应该提供很高的聚合数据带宽,一个集群中支持数百个节点,一个集群中还应该支持千万级别的文件。 4. 大部分HDFS应用对文件要求的是: write-one-read-many访问模型。 //一个文件一旦创建、写入、关闭之后就不需要修改了。这一假设简化了数据一致性问题,使高吞吐量的数据访问成为可能。 5. 移动计算的代价比之移动数据的代价低。 //一个应用请求的计算,离它操作的数据越近就越高效,这在数据达到海量级别的时候更是如此。 //将计算移动到数据附近,比之将数据移动到应用所在显然更好。 6. 在异构的硬件和软件平台上的可移植性。这将推动需要大数据集的应用更广泛地采用HDFS作为平台。 //因为它(HDFS)提供了一个统一的数据存储, 不管你怎么操作, 切换到什么平台, 只要能把数据读出来即可, 所以可移植性变高了.
2.2) HDFS 适用的场景:
1) 存储非常大的文件: 适合于存储大文件
//需要 高吞吐量,对延时没有要求。
2) 一次写入、多次读取.
//一旦将存储进去后 不需要对数据进行修改, 后期只是查询场景2.3) HDFS 不适用的场景:
1) 低延时的数据访问 对延时要求在毫秒级别的应用
2) 不适合存储大量的小文件: 因为每个文件都会有元数据. 而元数据存储在namenode的内存中.
//大文件的元数据和小文件的元数据大小差不多, 小文件多, 元数据就会变多, 内存满了后, NameNode就挂掉了.
3) 需要进行多次修改数据的操作业务 -
HDFS的架构说明
概述:
HDFS采用Master/Slave架构,一个HDFS集群有两个重要的角色,分别是Namenode和Datanode。
Namenode:
管理节点,负责管理文件系统的命名空间(namespace)以及客户端对文件的访问。
Datanode:
实际存储数据的节点。HDFS暴露了文件系统的命名空间,用户能够以操作文件的形式在上面操作数据。
HDFS的四个基本组件:
HDFS Client
NameNode
DataNode
Secondary NameNode。
HDFS的四个基本组件介绍:
1. Client:就是客户端。
文件切分。文件上传 HDFS 的时候,Client 将文件切分成 一个一个的Block,然后进行存储. //文件再少, 也是独立占一个块.
与 NameNode 交互,获取文件的位置信息。
与 DataNode 交互,读取或者写入数据。
Client 提供一些命令来管理 和访问HDFS,比如启动或者关闭HDFS。
2. NameNode:就是 master,它是一个主管、管理者。
管理 HDFS 的名称空间
管理数据块(Block)映射信息
配置副本策略
处理客户端读写请求。
3. DataNode:就是Slave。NameNode 下达命令,DataNode 执行实际的操作。
存储实际的数据块。
执行数据块的读/写操作。
4. Secondary NameNode:并非 NameNode 的热备。当NameNode 挂掉的时候,它并不能马上替换 NameNode 并提供服务。
辅助 NameNode,分担其工作量。定期合并 fsimage和fsedits,并推送给NameNode。在紧急情况下,可辅助恢复 NameNode。
//详见图片/HDFS的结构说明.png -
HDFS副本机架感知原理
//详见图片/HDFS的机架感知原理.png
4.1) HDFS文件副本机制
HDFS被设计成能够在一个大集群中跨机器可靠地存储超大文件。它将每个文件存储成一系列的数据块,这个数据块被称为block,
除了最后一个,所有的数据块都是同样大小的。为了容错,文件的所有block都会有副本。每个文件的数据块大小和副本系数都是
可配置的。所有的文件都是以 block 块的方式存放在 HDFS 文件系统当中.4.2) HDFS以Block块的方式存储数据的作用如下:
1. 一个文件有可能大于集群中任意一个磁盘,引入块机制,可以很好的解决这个问题
2. 使用块作为文件存储的逻辑单位可以简化存储子系统
3. 块非常适合用于数据备份进而提供数据容错能力
4. 副本优点是安全,缺点是占空间。4.3) 每一个块默认的大小为 128M . 可以配置的: //在hdfs-size.xml文件中.
dfs.blocksize
134217728 //这个就是: 128M
dfs.replication //Block副本块的数量.
3
4.4) 注意:
当一个文件的大小不足128M时,比如文件大小为2M,那么这个文件也占用一个block,
但是这个block实际只占2M的空间,所以从某种意义上来讲,block只是一个逻辑单位。4.5) 机架感知原理:
在存储一个文件的某一个副本的时候, 根据机架感知原理以及网络拓扑关系(寻最近机架),
将第一个副本放置在某一个机架上, 剩下两个副本放到另一个机架的不同服务器上. -
HDFS的shell基本命令
5.1) Shell命令行客户端
HDFS是存取数据的分布式文件系统,那么对HDFS的操作,就是文件系统的基本操作,比如文件的创建、修改、删除、修改权限等,
文件夹的创建、删除、重命名等。对HDFS的操作命令类似于Linux的shell对文件的操作,如ls、mkdir、rm等。格式: hadoop fs <args> //这个是Hadoop1.x的命令格式 hdfs dfs <args> //这个是Hadoop2.x的命令格式. //注意: 在2.x中依然可以使用1.x的命令, 在3.x中1.x的命令就不再支持了, 部分指令是全新的命令. HDFS可以操作虚拟机的也可以操作本地的文件, 细节分别如下: 对于HDFS,命令示例如下: hadoop fs -ls hdfs://namenode:host/parent/child hadoop fs -ls /parent/child //hdfs-site.xml中的fs.defaultFS中有配置 对于本地文件系统,命令示例如下: hadoop fs -ls file:///root/ //操作本地文件.
5.2) Shell命令选项
选项名称 使用格式 含义
-ls -ls <路径> 查看指定路径的当前目录结构
-lsr -lsr <路径> 递归查看指定路径的目录结构
-du -du <路径> 统计目录下个文件大小
-dus -dus <路径> 汇总统计目录下文件(夹)大小
-count -count [-q] <路径> 统计文件(夹)数量
-mv -mv <源路径> <目的路径> 移动
-cp -cp <源路径> <目的路径> 复制
-rm -rm [-skipTrash] <路径> 删除文件/空白文件夹
-rmr -rmr [-skipTrash] <路径> 递归删除
-put -put <多个linux上的文件> <hdfs路径> 上传文件
-copyFromLocal -copyFromLocal <多个linux上的文件> <hdfs路径> 从本地复制
-moveFromLocal -moveFromLocal <多个linux上的文件> <hdfs路径> 从本地移动
-getmerge -getmerge <源路径> <linux路径> 合并到本地
-cat -cat <hdfs路径> 查看文件内容
-text -text <hdfs路径> 查看文件内容
-copyToLocal -copyToLocal [-ignoreCrc] [-crc] [hdfs源路径] [linux目的路径] 从本地复制
-moveToLocal -moveToLocal [-crc] <hdfs源路径> <linux目的路径> 从本地移动
-mkdir -mkdir <hdfs路径> 创建空白文件夹
-setrep -setrep [-R] [-w] <副本数> <路径> 修改副本数量
-touchz -touchz <文件路径> 创建空白文件
-stat -stat [format] <路径> 显示文件统计信息
-tail -tail [-f] <文件> 查看文件尾部信息
-chmod -chmod [-R] <权限模式> [路径] 修改权限
-chown -chown [-R] [属主][:[属组]] 路径 修改属主
-chgrp -chgrp [-R] 属组名称 路径 修改属组
-help -help [命令选项] 帮助5.3) 常用的Shell命令 //以下所有命令的开头都可以用 hadoop fs 或者 hdfs dfs中任选其一, 建议使用: hdfs dfs
注意:
1. 操作命令之前, 保证hadoop集群是启动的状态, hadoop不会自动启动.
2. 在node1中运行: start-all.sh //启动HDFS集群和Yarn集群.
3. 在node1中运行: mr-jobhistory-daemon.sh start historyserver //启动查看MR计算程序运行的日志
4. 因为我们现在玩儿的是HDFS, 所以严格意义上讲, 只要启动HDFS集群就行了, Yarn集群都不用启动.
5. 启动之后, 打开浏览器, 分别输入如下的网址, 查看是否能够访问, 如果OK, 说明Hadoop集群启动成功.
192.168.88.161:50070 //HDFS集群外部管理界面.
192.168.88.161:8088 //Yarn集群平台的外部界面.
192.168.88.161:19888 //MapReduce计算程序运行的日志信息的外部界面.
6. 然后在 192.168.88.161:50070(HDFS集群外部管理界面)选择 Utilities -> Browse the file system, 输入/, 查看根目录结构.
-ls
格式:
hadoop fs -ls URI
作用:
类似于Linux的ls命令,显示文件列表
示例:
hadoop fs -ls / //查看根目录结构, 跟我们在网页中看到的是一样的, 1.x的命令.
hdfs dfs -ls / //查看根目录结构, 跟我们在网页中看到的是一样的, 2.x的命令.-lsr 格式: hdfs dfs -lsr URI 作用: 在整个目录下递归执行ls, 与UNIX中的ls-R类似 示例: hadoop fs -lsr / //递归获取某一个目录下所有的数据(包括它的子目录) hdfs dfs -lsr / //递归获取某一个目录下所有的数据(包括它的子目录) hdfs dfs -ls -R / //上述的命令可以优化成这种写法. -mkdir 格式: hdfs dfs [-p] -mkdir <paths> //跟上-p可以创建多级目录. 作用: 以<paths>中的URI作为参数,创建目录。使用-p参数可以递归创建目录 案例: hadoop fs -mkdir /dir1 hadoop fs -mkdir -p /aaa/bbb/ccc //为了保证和Linux语法类似(或者一致), 我们可以把mkdir放前边. -put 格式: hadoop fs -put <localsrc > ... <dst> //相当于拷贝. 作用: 将单个的源文件src或者多个源文件srcs从本地文件系统拷贝到目标文件系统中(<dst>对应的路径)。 也可以从标准输入中读取输入,写入目标文件系统中. 案例: echo "Hello HDFS" >> /root/1.txt hadoop fs -put /root/1.txt /dir1 //上传Linux中的文件 1.txt 到Hadoop集群的 /dir1目录下 hdfs dfs -put aa.txt bb.txt cc.txt /dir1 //上传多个文件. -moveFromLocal 格式: hdfs dfs -moveFromLocal <localsrc> <dst> 作用: 和put命令类似,但是源文件localsrc拷贝之后自身被删除 案例: echo "Hello HDFS" >> /root/2.txt hdfs dfs -moveFromLocal /root/2.txt / //移动目录到 HDFS的根目录下(相当于: 剪切) -moveToLocal //未实现, 即: Hadoop提供了这个命令, 但是还没有实现它的功能. hdfs dfs -help moveToLocal //查看该命令的介绍. -get 格式: hadoop fs -get [-ignorecrc ] [-crc] <src> <localdst> 作用: 将文件拷贝到本地文件系统。 CRC 校验失败的文件通过-ignorecrc选项拷贝。 文件和CRC校验和可以通过-CRC选项拷贝 案例: hadoop fs -get /2.txt /export/data //下载HDFS根目录下的2.txt文件到Linux的 /export/data目录下. -getmerge 格式: hadoop fs -getmerge -nl < hdfs dir > < local file > 功能: 合并下载多个文件 参数: 加上nl后,合并到local file中的hdfs文件之间会空出一行 案例: 比如hdfs的目录 /aaa/下有多个文件:log.1, log.2,log.3,... hadoop fs -getmerge /aaa/log.* ./log.sum //下载HDFS的/aaa/log.*文件到 Linux本地的log.sum文件夹下 hdfs dfs -getmerge /aaa/bb/cc/aa.txt /aaa/bb/cc/dd.txt ./merge.txt //合并HDFS中的两个文件并下载Linux中. -mv 格式: hdfs dfs -mv URI <dest> 作用: 将hdfs上的文件从原路径移动到目标路径(移动之后文件删除),该命令不能夸文件系统 案例: hdfs dfs -mv /dir1/a.txt /dir2 //把HDFS的 /dir1下的a.txt 剪切到 HDFS的 /dir2目录下. -rm 格式: hadoop fs -rm [-r] 【-skipTrash】 URI 【URI 。。。】 作用: 删除参数指定的文件和目录,参数可以有多个,删除目录需要加-r参数 如果指定-skipTrash选项,那么在回收站可用的情况下,该选项将跳过回收站而直接删除文件; 否则,在回收站可用时,在HDFS Shell 中执行此命令,会将文件暂时放到回收站中。 案例: hadoop fs -rm /2.txt //删除文件 hadoop fs -rm -r /dir1 //删除目录 -cp 格式: hdfs dfs -cp URI [URI ...] <dest> 作用: 将文件拷贝到目标路径中。如果<dest> 为目录的话,可以将多个文件拷贝到该目录下。 -f 选项将覆盖目标,如果它已经存在。 -p 选项将保留文件属性(时间戳、所有权、许可、ACL、XAttr)。 案例: hadoop fs -cp /dir1/1.txt /dir2/2.txt //把HDFS的 dir1下的1.txt 拷贝到 dir2目录中, 并改名为2.txt. -cat 格式: hadoop fs -cat URI [uri ...] 作用: 将参数所指示的文件内容输出到控制台 案例: hadoop fs -cat /dir2/2.txt //查看文件内容. -du 格式: hadoop fs -du URI 功能: 显示目录中所有文件大小,当只指定一个文件时,显示此文件的大小。 案例: hadoop fs -du / //展示根目录大小. -chmod 格式: hadoop fs -chmod [-R] URI[URI ...] 作用: 改变文件权限。如果使用 -R 选项,则对整个目录有效递归执行。 使用这一命令的用户必须是文件的所属用户,或者超级用户。 例如: 可以创建一个用户hadoop,将/a.txt的所属用户和所属用户组修改为hadoop hadoop fs -chmod -R 777 /dir1 //修改文件夹的权限. hadoop fs -chmod -R 777 /aa.txt //修改文件的权限. 注意: 权限的操作, 在HDFS中并不是特别强, 因为HDFS是一个非常单纯的孩子, 相信: 我告诉你我是谁, 我就是谁. HDFS的权限是: 防止好人做错事, 但是防止不了坏人做坏事儿. -chown 格式: hdfs dfs -chmod [-R] URI[URI ...] 作用: 改变文件的所属用户和用户组。如果使用 -R 选项,则对整个目录有效递归执行。 使用这一命令的用户必须是文件的所属用户,或者超级用户。 案例: hadoop fs -chown -R hadoop:hadoop /a.txt -appendToFile 格式: hadoop fs -appendToFile <localsrc> ... <dst> 作用: 追加一个或者多个文件到hdfs指定文件中.也可以从命令行读取输入. 案例: vim /export/date/123.txt //修改文件中的内容. hadoop fs -appendToFile /export/data/123.txt /aa.txt //追加数据到指定的文件中.
5.4) 需要明确记忆的命令:
ls命令 //显示文件列表(不包含子目录和子文件)
mkdir命令: //显示文件列表(包含子目录)
put命令: //用于上传文件操作
get命令: //用于下载数据
getmerge命令: //用于合并下载操作 --次要
mv命令: //从hdfs 某一个路径移动到hdfs的另一个路径下
rm命令: //删除参数指定的文件和目录,参数可以有多个,删除目录需要加-r参数
cp命令: //将文件拷贝到目标路径中
cat命令: //将参数所指示的文件内容输出到控制台
du命令: //显示目录中所有文件大小
chmod命令: //改变文件权限
appendToFile: //追加数据操作 -
HDFS的安全模式
当hdfs刚刚启动的时候, 此时hdfs会自动进入到安全模式下, 此时, datanode在和namenode进行块的校验过程, 对于用户而言,
无法对hdfs的进行数据写入操作, 只允许进行查询.
//即: 集群新启动时, datenode都会向namenode汇报它的"块"信息, 方便namenode做统一的管理.默认情况下, hdfs启动到达30s后, 会自动的退出安全模式, 或者说等所有的块校验完成后 自动的退出安全模式.
//即: 第一次启动的时候, 时间会比较长, 因为块比较多, 都需要做校验.如果发现hdfs中块的副本不够了, 而且还无法新增了, 此时系统自动进入安全模式, 直到手动修复 (将对应块所属文件删除).
//手动修复方案: 强制退出安全模式, 然后手动删除这些块.安全模式的相关命令:
hdfs dfsadmin -safemode get //查看安全模式状态
hdfs dfsadmin -safemode enter //进入安全模式
hdfs dfsadmin -safemode leave //离开安全模式 -
HDFS的基准测试内容
实际生产环境当中,hadoop的环境搭建完成之后,第一件事情就是进行压力测试,测试我们的集群的读取和写入速度,
测试我们的网络带宽是否足够等一些基准测试.
//即: 验证HDFS的读写的效率, 就是其 吞吐量的的问题.如何测试写入的速度:
hadoop jar /export/server/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -write -nrFiles 10 -size 10MB
//nrFiles: 表示文件的个数, size: 每个文件的大小(实际开发可能会测十几个G, 甚至更大)
//注意: 你现在测试的时候不要去写10个G, 因为是直接往里边写入的, 如果你写的过大, 可能磁盘直接就爆了.hadoop fs -text /benchmarks/TestDFSIO/io_write/part-00000 //完成之后查看写入速度结果, 这个可以不执行.
如何测试读取的数据:
hadoop jar /export/server/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -read -nrFiles 10 -fileSize 10MBhadoop fs -text /benchmarks/TestDFSIO/io_read/part-00000 //完成之后查看读取速度结果, 这个可以不执行.
清空的基准测试数据:
hadoop jar /export/server/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -clean注意:
1. 这些目前没什么太大的实际作用, 我们只是测试下, 玩儿玩儿就Ok了, 上述的时间要减去大概20秒, 这个是MapReduce的启动时间.
2. 正常像200台左右的集群, 大约写入在 100MB/S以上, 读取在 500MB/s以上.
3. 上述的临时文件都在 HDFS的 /benchmarks/TestDFSIO/io_data 这里边, 测试完毕后需要删除.
4. 到这儿, 今天的操作类的内容就讲解完毕了, 之后的内容都是原理性的知识点. -
namenode的基本原理
8.1) 基本原理
//详见图片/namenode的基本原理.png
1) namenode保存的所有的元数据信息, 都是存储在内存中.2) 整个HDFS可存储的文件数受限于NameNode的内存大小 注意: 实际环境中, namenode需要选择一台性能较高的服务器来当做namenode //128G 内存及以上, 硬盘采用固态的硬盘, 当然, 配置越高越好, 根据公司的预算来. 3) namenode, 在保存元数据的时候, 会先将元数据保存到磁盘上, 然后在内存中也保存一份. 用于保存元数据的磁盘文件, 主要有二个: fsImage文件 和 edis文件 fsImage文件, 是namenode元数据的镜像文件: 保存一份较为完整的元数据信息 edits文件: 是namenode在运行过程中, 会将元数据更新, 新增 操作全部写入到edits文件中 注意:在达到一定阈值后, snn 会进行对 edits文件和fsImage文件进行合并操作, 以保证在namenode edits文件不至于过大. 4) namenode不真实负责数据的读写操作, 但是需要经过namenode的询问之后 才可以读取datanode数据 //NameNode对于HDFS至关重要,当NameNode关闭时,HDFS / Hadoop集群无法访问
8.2) 作用
1. NameNode是HDFS的核心。
2. NameNode也称为Master。
3. NameNode仅存储HDFS的元数据:文件系统中所有文件的目录树,并跟踪整个集群中的文件。
4. NameNode不存储实际数据或数据集。数据本身实际存储在DataNodes中。
5. NameNode知道HDFS中任何给定文件的块列表及其位置。使用此信息NameNode知道如何从块中构建文件。
6. NameNode并不持久化存储每个文件中各个块所在的DataNode的位置信息,这些信息会在系统启动时从数据节点重建。
7. NameNode对于HDFS至关重要,当NameNode关闭时,HDFS / Hadoop集群无法访问。
8. NameNode是Hadoop集群中的单点故障。
9. NameNode所在机器通常会配置有大量内存(RAM) -
datenode的基本原理
大白话版:
1) datanode以数据块(block)来存储文件
2) datanode和namenode保持心跳的机制: 默认每隔3秒, 进行一次心跳, 如果10分钟内, 没有心跳, 认为, 宕机了
3) datanode每隔6个小时, 会向namenode报告一次完整的块信息
4) 在真实集群中, 宕掉某一台datanode, 并不会整个集群的可用性, 因为namenode会自动的容错, 在其他的节点上构建缺失的block块.专业版:
1. Data Node以数据块的形式存储HDFS文件
2. DataNode也称为Slave。
3. NameNode和DataNode会保持不断通信。
4. DataNode启动时,它将自己发布到NameNode并汇报自己负责持有的块列表。
5. 当某个DataNode关闭时,它不会影响数据或群集的可用性。NameNode将安排由其他DataNode管理的块进行副本复制。
6. DataNode所在机器通常配置有大量的硬盘空间。因为实际数据存储在DataNode中。
7. DataNode会定期(dfs.heartbeat.interval配置项配置,默认是3秒)向NameNode发送心跳,
如果NameNode长时间没有接受到DataNode发送的心跳, NameNode就会认为该DataNode失效。
8. block汇报时间间隔取参数dfs.blockreport.intervalMsec,参数未配置的话默认为6小时. -
HDFS的写入数据的流程
- 客户端发送请求, 连接namenode, 请求写入数据操作
- namenode接收到请求后, 首先要判断客户端用户是否具有写入权限, 如果没有, 直接报错, 如果有权限
接下来要判断在要写入的路径下是否有这个文件, 如果有, 直接报错, 如果没有, 通知客户端可以写入 - 客户端接收到可以写入的信息后, 开始对文件进行切分, 形成多个block块
- 客户端请求namenode, 第一个block应该存储在那些datanode中
- namenode 根据机架感知原理以及网络拓扑关系 和 副本机制, 来寻找到对应的datanode的地址列表, 然后
将这些datanode的地址列表返回客户端 - 客户端从接收地址列表中, 拿出第一个地址与之连接, 形成一个pipeline的管道
- 当第一个连接成功后, 让第一个连接第二个地址, 然后第二个在连接第三个地址, 形成一个pipeline的管道
- 客户端开始进行写入数据: 数据以 package 数据包(64kb)的形式来发送数据, 当第一台接收数据后, 然后
将请求发送给第二个datanode, 然后第二个接收到以后,然后在发送给第三个datanode - 当第一个接收到数据后, 建立好一个应答响应队列, 当每个节点接收数据后, 都向应答队列反向报告, 最终所有
都报告完成后, 将应答队列返回客户端 - 不断的进行发送, 不断的进行应答响应, 即可完成数据的发送, 当第一个block发送完成后, 重新请求namenode
第二个block应该存储在那些datanode中, 此时在从流程第5步, 往下走即可 … 循环让所有的block写入成功即可
//详见图片 HDFS写数据的流程图.png
-
HDFS的读取数据的流程
- 向namenode发送请求, 连接namenode, 请求读取数据操作
- namenode接收到请求后, 首先要判断客户端用户是否具有读取权限, 如果没有, 直接报错, 如果有权限
接下来要判断在要写入的路径下是否有这个文件, 如果没有, 直接报错, 如果有, 根据机架感知原理以及网络拓扑关系 和 副本机制,
返回给客户端部分或者全部的block对应的datanode的地址信息列表 - 客户端接收到地址列表后, 开始并行方式连接多个datanode的地址, 进行读取数据
- 如果上一次返回的部分的block列表, 当读取完成后, 再次请求namenode, 获取剩余的部分或者全部的block对应的datanode信息
在接着执行第三步, 进行读取数据操作, 直到将所有的block全部读取完成 - 在client客户端, 进行对block排序, 然后将每个block拼接在一起, 形成了最终的文件
//详见图片 HDFS写读据的流程图.png
-
HDFS的元数据的辅助管理(SNN)
SecondaryNameNode指的是辅助节点, 主要是将Edits文件和FSImage文件进行合并操作, 形成一个新的FSImage文件.
//详见图片 SNN如何辅助管理NameNode.pngHDFS的配置文件都在: /export/server/hadoop-2.7.5/etc/hadoop 目录下.
NameNode存储元数据的目录: /export/server/hadoop-2.7.5/hadoopDatas/namenodeDatas/currentSecondaryNameNode出现的原因
但是如果NameNode执行了很多操作的话,就会导致edits文件会很大,那么在下一次启动的过程中,
就会导致NameNode的启动速度很慢,慢到几个小时也不是不可能,所以出现了SecondNameNode。 -
HDFS的fsimage和edits文件中的信息查看
概述:
详见word讲义, 内容和我刚才给大家画的图片是一致的.fsimage 中的文件信息查看:
cd /export/server/hadoop2.7.5/hadoopDatas/namenodeDatas/current //该目录下存放的是NameNode节点存储的元数据.
cp fsimage_0000000000000000589 /root //在上述目录随便找一个fsimage文件, 将其拷贝到root目录中.
cd /root //切换到root目录下.
hdfs oiv -i fsimage_0000000000000000589 -p XML -o hello.xml //将上述文件转成XML文件, 并设置名字为: hello.xml
然后通过notepad++连接虚拟机, 查看该文件中的内容即可.edits 中的文件信息查看:
cd /export/server/hadoop-2.7.5/hadoopDatas/nn/edits/current //存放的是NameNode的edits文件
cp edits_0000000000000000181-0000000000000000237 /root/ //在上述目录随便找一个edits文件, 将其拷贝到root目录中.
cd /root //切换到root目录下.
hdfs oev -i edits_0000000000000000181-0000000000000000237 -p XML -o myedit.xml //将上述文件转成XML文件, 并设置名字为: myedit.xml
然后通过notepad++连接虚拟机, 查看该文件中的内容即可. -
如何使用SNN来恢复元数据
概述:
当NameNode发生故障时,我们可以通过将 SecondaryNameNode 中数据 拷贝到 NameNode存储数据的目录
的方式来恢复NameNode的数据.操作步骤:
1. 杀死NameNode进程
kill -9 NameNode进程号
2. 删除NameNode存储的数据. //这个指令在node1中执行.
删除 namenode 的 fsimage 相关的文件:
cd /export/server/hadoop-2.7.5/hadoopDatas/namenodeDatas
rm -rf *
删除 namenode 的 edits 相关的文件:
cd /export/server/hadoop-2.7.5/hadoopDatas/nn/edits
rm -rf *
//删除这些文件之后, 你的namenode都启动不起来.3. 拷贝SecondaryNameNode中数据到原NameNode存储数据目录. //以下指令在node2中执行, 因为SecondaryNameNode是部署在这里的. cd /export/server/hadoop-2.7.5/hadoopDatas/namenodeDatas/ //这里也没有, 因为它不是namenode节点, 是SNN节点, 数据在SNN目录中. //从node2中拷贝fsimage文件到 node1中. cd /export/server/hadoop-2.7.5/hadoopDatas/snn/name //这里存放的是fsimage文件. scp -r * node1:/export/server/hadoop-2.7.5/hadoopDatas/namenodeDatas/ //把数据拷贝到node1中. //从node2中拷贝edits文件到 node1中. cd /export/server/hadoop-2.7.5/hadoopDatas/dfs/snn/edits //这里存放的是edits文件. scp -r * node1:/export/server/hadoop-2.7.5/hadoopDatas/nn/edits/ //把数据拷贝到node1中. 4. 重新启动NameNode hadoop-daemon.sh start namenode 5. 打开浏览器, 在 node1:50070 中查看内容是否恢复成功即可.