一、HDFS基础知识
1. hadoop是什么?
Hadoop是Apache软件基金会开发的一款开源软件,它允许用户使用简单的编程模型,在多台计算机组成的集群上进行分布式计算处理,以处理和存储海量数据。
hadoop核心组件
HDFS(分布式文件存储系统):负责解决海量数据的存储问题。
YARN(集群资源管理和任务调度框架):负责资源管理和任务调度。
MapReduce(分布式计算框架):负责海量数据的计算。
2. HDFS 介绍
HDFS 是 Hadoop Distributed File System 的简写,即 Hadoop 分布式文件系统。
HDFS 采用分布式架构,将数据分散存储在集群中的多台机器(称为数据节点)上。
HDFS架构及存储
HDFS采用Master/Slave架构存储数据,主要由以下四部分组成:
HDFS客户端(HDFS Client)
主节点(NameNode)
数据节点(DataNode)
次级主节点(Secondary NameNode)
一个HDFS集群通常包含一个NameNode和多个DataNode。
NameNode是中心服务器,负责管理文件系统的名称空间(Namespace)以及客户端对文件的访问。
DataNode负责管理其所在节点上的数据存储。
HDFS文件存储特点:
分块存储:HDFS中的文件在物理上是以块(Block)的形式进行存储,默认大小为128MB。
文件切分:文件存储到HDFS时,会被切分成多个块(Block),这些块分布在多个DataNode节点上。
映射管理:HDFS中的文件与实际存储的块之间存在映射关系,由NameNode管理。
多副本存储:每个块在集群中会存储多个副本,增加数据的可靠性和访问的吞吐量。
HDFS架构图

HDFS的特点
分块存储:文件在HDFS中被切块(Block),默认大小为128MB。
NameNode和DataNode:HDFS有两个主要的节点:
NameNode:负责管理DataNode,处理文件系统的元数据(Metadata)。
DataNode:负责存储实际的数据块。
多副本存储:HDFS会为每个文件块生成多个副本(Replication),默认情况下,HDFS生成3个副本。
高可用性:如果某个DataNode宕机,HDFS会自动在其他节点上生成新的副本,确保数据不会丢失。
NameNode中元数据存储问题及工作机制
Namenode是HDFS集群主节点,负责管理整个文件系统的元数据,所有的读写请求都要经过Namenode。

从数据写入的角度,HDFS 的数据写入过程分为以下几个步骤,我们可以通过这张图来解释数据如何在 HDFS 中写入:
客户端请求写入数据:
图中的 Client(客户端) 首先向 NameNode 发起请求,表明它想要写入一个文件。Client 会将文件分割成多个块(Blocks),每个块会单独写入到 HDFS 的多个 DataNode 中。
NameNode 分配数据块并返回位置信息:
NameNode 在接收到客户端的写入请求后,会为文件分配数据块(Blocks),并根据可用的 DataNode 列表决定哪些 DataNode 来存储这些块。图中表示 NameNode 保存着文件块(Block)的位置信息,并将这些信息返回给 Client,告知它可以将数据写入哪些 DataNode。
数据块写入到多个 DataNode:
客户端获取到块的位置后,开始将数据块写入到图中的 DataNode。为了实现数据的冗余和可靠性,HDFS 采用了副本机制。每个数据块会被复制到多个 DataNode 上(默认情况下是 3 个副本)。例如,图中显示一个数据块(Block 1)同时被写入到多个不同的 DataNode,如第一个和最后一个 DataNode。
客户端首先与第一个 DataNode 直接交互,将数据块写入该节点。接着,该 DataNode 会将数据块的副本复制到下一个 DataNode,如图中的箭头所示,这个过程称为 链式复制(Pipeline Replication)。
DataNode 向 NameNode 发送心跳信号:
当 DataNode 接收到并成功存储数据块后,它会向 NameNode 发送心跳信号,并报告哪些块被成功写入。这些心跳信号允许 NameNode 知道数据块的健康状况和所在位置。
Secondary NameNode 定期备份元数据:
图中右侧的 Secondary NameNode 负责定期从 NameNode 获取当前的元数据快照(FSImage)和增量日志文件(Edits),然后将两者合并成一个新的 FSImage,并将合并后的文件传回给 NameNode。这个操作的目的是减少 Edits 日志文件的大小,防止 NameNode 在重启时加载过多的增量日志,导致启动时间过长。
元数据管理方式
NameNode对元数据的管理主要采用以下三种方式:
内存元数据:
元数据存储在内存中,方便快速访问和处理。这些元数据是比较完整的,能够及时响应客户端的请求。
FsImage文件:
FsImage是存储在磁盘上的元数据镜像文件,包含文件系统的目录结构、文件属性等信息。
HDFS运行时会将FsImage文件加载到内存中。系统的写操作只会更新内存中的元数据,而不会直接修改FsImage文件。
Edits文件:
fsimage + edits = 内存元数据Edits文件是记录数据操作日志的文件,用于记录对内存元数据的所有写操作(如修改)。
它衔接内存元数据和FsImage文件之间的差异,确保系统的一致性。
为什么元数据需要存放在内存中?
如果元数据存储在NameNode节点的磁盘中,由于需要频繁进行随机访问,并响应客户端请求,效率会非常低。因此,元数据需要存放在内存中以提高系统性能。
如何防止元数据丢失?
如果元数据仅存放在内存中,一旦系统断电,元数据将会丢失,整个集群也将无法正常工作。为防止这种情况发生,NameNode会在磁盘中备份元数据,通过FsImage文件进行持久化。
如何解决元数据的一致性问题?
当内存中的元数据更新时,如果同时更新FsImage文件,会导致效率过低。如果不更新FsImage文件,则会发生一致性问题,在NameNode节点断电时可能导致数据丢失。
为了解决这一问题,Hadoop引入了Edits文件。Edits文件只记录追加操作,不进行计算,效率很高。每当元数据有更新时,NameNode会修改内存中的元数据,并将操作记录追加到Edits文件中。
(注意:HDFS仅支持数据的追加操作,不支持文件的随机修改。)
Edits文件的管理与合并
随着时间推移,Edits文件中的数据会不断增多,这会导致文件过大、效率降低,并且在断电后恢复元数据所需的时间过长。为此,需要定期将FsImage和Edits文件进行合并。
如果让NameNode执行合并操作,会影响其效率。因此,Hadoop引入了一个新的节点——Secondary NameNode,专门负责合并FsImage和Edits文件,并将结果推送回NameNode。
内存与磁盘的协调管理
内存中的元数据:实时存储当前的元数据信息,便于快速查询和处理。
FsImage文件:磁盘上的备份数据,存储系统最新的元数据快照,保障数据的持久性。
Edits文件:记录所有对内存元数据的更新操作,确保系统在重启后能够恢复最新状态。
合并操作的执行时机
开机时:NameNode会将FsImage文件和Edits文件的数据加载到内存中,恢复最新的元数据状态。
关机时:Secondary NameNode会将FsImage文件和Edits文件进行合并,将合并后的数据写回FsImage文件,并清空Edits文件。
定时合并:根据预设的时间间隔,Secondary NameNode定期触发合并操作,防止Edits文件过大。
数据量合并:当Edits文件中的数据量达到一定阈值时,会自动触发合并操作,确保系统高效运行。
HDFS的写数据流程

流程解读:
客户端请求NameNode上传文件,NameNode检查文件和目录的存在性。
NameNode返回可以上传的确认信息。
客户端请求NameNode分配数据块的存储位置(DataNode)。
NameNode返回可用的DataNode列表(如dn1、dn2、dn3)。
客户端通过管道机制逐级上传数据块到各DataNode。
数据块上传完成后,客户端请求下一块的存储位置,重复步骤3-5。
HDFS的读数据流程

流程解读:
客户端请求NameNode读取文件,NameNode返回文件块所在的DataNode地址。
客户端选择就近的DataNode读取数据。
DataNode将数据传输给客户端,客户端接收并保存数据。
HDFS的主要组件
Client(客户端):负责文件切分、与NameNode交互、与DataNode交互、提供管理命令。
NameNode(主节点):负责元数据管理、配置副本策略、处理客户端请求。
DataNode(数据节点):负责数据块存储、执行数据块读写操作、通过心跳机制向NameNode报告状态。
Secondary NameNode(次级主节点):负责合并FsImage和Edits文件,辅助恢复NameNode。
HDFS的元数据与多副本策略
元数据:
包含文件的存储路径、复本数量、对应的文件块、每个块的存储节点信息。
存储在NameNode的内存和磁盘中,用于快速查询和崩溃恢复。
多副本放置策略:
第一个副本:放在上传节点或空闲的DataNode上。
第二个副本:放在不同机架的节点上。
第三个副本:放在另一个不同机架的节点上。
更多副本:选择相对空闲的节点存储。
3. HDFS实践
接下来介绍Linux操作系统中关于HDFS文件操作的常用Shell命令,利用Web界面查看和管理Hadoop文件系统,
启动Hadoop
start-dfs.sh # 在master启动hdfs
start-yarn.sh # 在slave1启动yarn3.1 利用Shell命令与HDFS进行交互
hadoop fs 和 hdfs dfs 都是用于与 Hadoop 文件系统进行交互的命令行工具。可以用它们来执行各种文件操作,比如查看文件列表、上传下载文件、删除文件等等。
两种常见的 Shell 命令方式:
通过
hadoop fs命令执行:格式:
hadoop fs [options]示例:
hadoop fs -ls /解释:列出 HDFS 根目录(/)下的文件和目录。通过
hdfs dfs命令执行:格式:
hdfs dfs [options]示例:
hdfs dfs -ls /解释:与hadoop fs -ls /命令作用相同,列出 HDFS 根目录下的文件和目录。
区别:
hdfs dfs是更推荐的方式,因为它专门用于处理 HDFS 文件系统操作,hadoop fs则是一个更通用的命令,可以处理多种文件系统类型(例如本地文件系统和 HDFS)如查看本地文件系统根目录下的opt目录:
hadoop fs -ls file:///opt
在实际使用中,hdfs dfs 是更为常见的操作方式,用于大多数 HDFS 相关的命令执行。
查看HDFS上文件内容
hdfs dfs -ls / #列出HDFS的根目录下的所有内容
hdfs dfs -ls -R / #列出HDFS的根目录下的所有内容及子目录, -R(递归)
3.2 利用Web界面管理HDFS
# 在浏览器中输入地址
http://master:9870
或者 192.168.36.100:9870依次点击Utilities - Browse the file system)

查看fs总共支持了哪些命令
hdfs dfs
Shell 命令

在终端输入如下命令,可以查看具体某个命令的作用
例如:我们查看put命令如何使用,可以输入如下命令
hdfs dfs -help put
Shell 命令

二、HDFS 练习
1. 目录操作
在 Hadoop 系统安装完成后,第一次使用 HDFS 时,通常需要为每个用户在 HDFS 中创建用户的家目录,路径格式为 /[父目录]/[用户名]。例如,如果用户名是 root,则家目录为 /user/root。
默认操作路径:
使用
hdfs dfs命令操作文件时,默认操作路径是用户的家目录。例如,用户root的家目录路径通常是/user/root。如果没有明确指定其他路径,文件操作都会在该家目录中进行。父目录路径:
HDFS 中所有用户的家目录的上级目录通常是
/user。该路径由hdfs-site.xml配置文件中的dfs.user.home.dir.prefix参数定义,默认值是/user。/user是用户家目录的父目录,[用户名]则是该用户的家目录。例如,用户
root的家目录为/user/root,即在/user下有一个名为root的子目录。
1.1 在 HDFS 中为 root 用户创建用户家目录
hdfs dfs -mkdir -p /user/root
# -p: 创建多级目录命令解释:
hdfs dfs -mkdir:创建目录的命令。-p:如果目录路径中包含多级目录,则会创建所有必要的父目录。/user/root:这是root用户在HDFS中的家目录。
1.2 在 root 用户家目录下创建一个 input 目录
hdfs dfs -mkdir input
# 创建 input 目录在 /user/root 下1.3 在根目录下创建 input 和 inputdata 目录
hdfs dfs -mkdir /input
hdfs dfs -mkdir /inputdata
# 创建 /input 和 /inputdata 目录在 HDFS 根目录下1.4.显示HDFS中当前用户的目录内容
# 列出root用户在HDFS家目录中的文件
hdfs dfs -ls .命令解释:
hdfs dfs -ls:列出指定目录下的所有内容。.表示当前用户的家目录。对于root用户来说,这相当于列出/user/root目录的内容。上述命令与以下命令等效:
# 默认会查看当前用户在 HDFS 中的家目录,如果用户是root,则就是“/user/root”目录
# 等效命令:hdfs dfs -ls == hdfs dfs -ls . == hdfs dfs -ls /user/root
hdfs dfs -ls .
hdfs dfs -ls /user/root
hdfs dfs -ls注意:如果在
hdfs dfs -ls命令后未指定路径,则会默认列出/user/用户名/目录下的文件。
1.5 列出HDFS根目录的内容
hdfs dfs -ls / #列出HDFS的根目录下的所有内容
hdfs dfs -ls -R / #列出HDFS的根目录下的所有内容及子目录1.6 删除根目录下的 inputdata 目录
hdfs dfs -rm -r /inputdata
# 递归删除 /inputdata 目录命令解释:
hdfs dfs -rm:删除文件或目录的命令。-r:递归删除目录及其子目录。-f:忽略不存在的文件,强制删除,不提示确认。注意:如果要删除的目录包含子目录,必须使用
-r参数,否则删除操作将失败。
1.7 修改 input 目录的权限
# 修改 /input 目录的权限为 755
hdfs dfs -chmod 755 /input解释:
755:权限模式,采用八进制表示,代表文件或目录的权限:
7:所有者(用户)有读(r)、写(w)、执行(x) 权限。
5:所属组有读(r)、执行(x) 权限,没有写权限。
5:其他用户有读(r)、执行(x) 权限,没有写权限。
1.8 将 /input 目录的所有者和所属组修改为 root
hdfs dfs -chown root:root /input
# 修改 /input 的所有者和组为 root解释:
第一个
root:目录的所有者。第二个
root:目录的所属组。
2. 文件操作
2.1 在本地文件系统中创建 zhang.txt 文件并编辑内容
# 创建目录
mkdir -p /opt/data
cd /opt/data
# 创建文件
touch zhang.txt
# 使用 vim 编辑器编辑文件内容 或者 双击编辑
vim zhang.txt
# 添加以下内容
Hadoop2.2 将本地 zhang.txt 文件上传到 HDFS 的 input 目录
hdfs dfs -put /opt/data/zhang.txt input
2.3 查看文件是否成功上传到 input 目录
# 列出 /user/root/input 目录中的文件
hdfs dfs -ls input2.4 使用 cat 命令查看 HDFS 中 zhang.txt 文件内容
hdfs dfs -cat input/zhang.txt
2.5 实时监控 zhang.txt 文件的新增内容
hdfs dfs -tail -f /user/root/input/zhang.txt
# -tail:读取并显示文件的最后几行内容。
# -f:持续输出文件末尾的内容,如果文件内容发生更新,它会自动显示新的内容。常用于实时监控文件日志。在另一个终端窗口向 zhang.txt 文件追加内容:
# 编辑文本
vi /opt/data/new_content.txt # 添加编辑内容:python
# 向HDFS上的文件追加内容
hdfs dfs -appendToFile new_content.txt /user/root/input/zhang.txt
# -appendToFile:将一个本地文件的内容追加到 HDFS 中的目标文件的末尾2.6 将 zhang.txt 文件从 HDFS 用户家目录复制到 HDFS 根目录 input 目录
hdfs dfs -cp input/zhang.txt /input
2.7 强制删除根目录 input 中的 zhang.txt 文件
# 强制递归删除指定目录及其所有子目录和文件,【-f 忽略不存在的文件或目录,不提示确认。】
hdfs dfs -rm -f /input/zhang.txt2.8 将 zhang.txt 文件从 HDFS 下载到本地
hdfs dfs -get /user/root/input/zhang.txt /opt/data/zhao.txt
2.9 输出 HDFS 根目录下所有文件的详细信息
# 递归输出 HDFS 根目录下的所有文件信息
hdfs dfs -ls -R -h /解释:
hdfs:Hadoop 文件系统命令工具。
dfs:执行 HDFS 上的文件操作。
-l:显示文件详细信息(权限、大小等)。
-h:以易读格式显示文件大小(KB、MB、GB)。