大数据基础系列教程:Apache Hadoop HDFS 面向大规模数据存储的分布式文件系统详解!

本文章仅提供学习,切勿将其用于不法手段!


引言

Hadoop Distributed File System(HDFS)是 Apache Hadoop 生态的核心组件之一,是一个面向大规模数据存储的分布式文件系统,设计目标是高容错性、高吞吐量(适合批量处理)、支持 PB 级数据存储。HDFS 采用主从架构(Master/Slave)​,核心角色包括:

  • NameNode(NN)​​:管理文件系统的元数据(文件/目录结构、块位置映射),是 HDFS 的“大脑”。
  • DataNode(DN)​​:存储实际的数据块(默认 128MB/块),负责数据的读写和心跳上报。
  • SecondaryNameNode(SNN,可选)​​:辅助 NameNode 合并元数据快照(非热备,仅用于定期合并 fsimage 和 edits)。

本教程从下载→安装→配置→调试→运行→运维→测试→安全全流程展开,结合命令行与配置示例,帮助开发者快速掌握 HDFS 生产级实践能力。


一、HDFS 下载

1.1 官方下载渠道

HDFS 是 Hadoop 生态的核心模块,需通过下载完整的 ​Apache Hadoop 发行版​ 获取(不单独提供 HDFS 独立包)。访问 Apache Hadoop 官网,选择稳定版本(如 3.3.6,截至 2024 年主流生产版本)。

版本选择建议​:

  • 生产环境​:优先选择 ​LTS(长期支持)版本​(如 3.3.x/3.2.x),社区支持更持久。
  • 新特性需求​:若需使用 HDFS 新功能(如 Erasure Coding 编码存储、Router-based Federation),可选择较新的稳定版(如 3.3.6+)。
  • 依赖兼容性​:HDFS 3.x 需要 ​JDK 8/11​(推荐 JDK 11),与 Spark/Flink 等组件版本需匹配(例如 Spark 3.x 兼容 Hadoop 3.x)。

推荐下载预编译包(二进制文件,无需自行编译):

# 示例:下载 Hadoop 3.3.6(HDFS 包含在内)
wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz

二、HDFS 安装(基于 Hadoop 生态)

2.1 环境准备

  • 操作系统​:Linux(推荐 CentOS/Ubuntu)、macOS(开发测试)、Windows(需 WSL2)。
  • Java 环境​:确保 java -version 显示 JDK 8/11(通过 export JAVA_HOME=/path/to/jdk 配置)。
  • 主机规划​:至少 2 台服务器(或虚拟机):
    • 1 台 NameNode(NN)​​:主节点,管理元数据。
    • 2 台及以上 DataNode(DN)​​:从节点,存储实际数据(生产环境建议至少 3 个 DN 以保证冗余)。
  • 依赖工具​:tar(解压)、ssh(免密登录)、vim/nano(编辑配置)。

2.2 安装步骤(单机/伪分布式模式 → 完全分布式模式)

场景 1:伪分布式模式(单机模拟 HDFS 集群)

适用于开发调试,单台机器同时运行 NameNode 和 DataNode。

步骤 1:下载并解压
# 1. 下载 Hadoop
wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz

# 2. 解压到指定目录(如 /opt)
tar -zxvf hadoop-3.3.6.tar.gz -C /opt/
cd /opt/hadoop-3.3.6

# 3. 配置环境变量(添加到 ~/.bashrc 或 ~/.zshrc)
export HADOOP_HOME=/opt/hadoop-3.3.6
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64  # 替换为实际 JDK 路径
source ~/.bashrc
步骤 2:配置核心文件

修改 etc/hadoop/ 目录下的关键配置文件:

(1)hadoop-env.sh(Java 环境)
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64  # 确保指向正确的 JDK 路径
(2)core-site.xml(HDFS 基础配置)
<configuration>
  <!-- 指定 NameNode 的 RPC 地址(伪分布式模式下即本机) -->
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://localhost:9000</value>
  </property>
  <!-- HDFS 数据存储的本地目录(需手动创建) -->
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/opt/hadoop-3.3.6/tmp</value>
  </property>
</configuration>
(3)hdfs-site.xml(HDFS 核心参数)
<configuration>
  <!-- NameNode 元数据存储目录(需手动创建) -->
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>/opt/hadoop-3.3.6/namenode_data</value>
  </property>
  <!-- DataNode 数据存储目录(需手动创建) -->
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>/opt/hadoop-3.3.6/datanode_data</value>
  </property>
  <!-- 副本数(伪分布式模式下只能为 1) -->
  <property>
    <name>dfs.replication</name>
    <value>1</value>
  </property>
  <!-- 是否启动 Web UI -->
  <property>
    <name>dfs.webhdfs.enabled</name>
    <value>true</value>
  </property>
</configuration>
步骤 3:创建数据存储目录
mkdir -p /opt/hadoop-3.3.6/{tmp,namenode_data,datanode_data}
步骤 4:格式化 NameNode(首次启动必须执行)
hdfs namenode -format  # 格式化会生成元数据目录(谨慎操作,仅首次需要!)
步骤 5:启动 HDFS 服务
start-dfs.sh  # 启动 NameNode 和 DataNode(伪分布式模式下 DataNode 也运行在本机)
步骤 6:验证服务
  • 查看进程​:
    jps  # 应看到 NameNode、DataNode、SecondaryNameNode(伪分布式模式下 SecondaryNameNode 也会启动)
  • 访问 Web UI​:
    • NameNode UI:http://localhost:9870(Hadoop 3.x 默认端口 9870,2.x 为 50070)。
    • 查看 DataNode 状态:在 Web UI 的 "Datanodes" 标签页确认在线节点。
  • 命令行验证​:
    hdfs dfsadmin -report  # 查看集群状态(DataNode 数量、存储容量)
    hdfs dfs -ls /         # 列出根目录(初始为空)

场景 2:完全分布式模式(多节点生产环境)

适用于生产环境,需至少 1 个 NameNode 和 2 个 DataNode。

步骤 1:主机规划与准备
  • 节点角色分配​(示例):
    • NameNode(NN)​​:hadoop-nn1(IP: 192.168.1.100)。
    • DataNode(DN)​​:hadoop-dn1(IP: 192.168.1.101)、hadoop-dn2(IP: 192.168.1.102)。
  • 所有节点通用配置​:
    • 解压 Hadoop 到相同路径(如 /opt/hadoop-3.3.6)。
    • 配置免密 SSH(NameNode 需能通过 ssh 访问所有 DataNode)。
步骤 2:配置核心文件(所有节点)
(1)hadoop-env.sh(所有节点)
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64  # 替换为实际 JDK 路径
(2)core-site.xml(所有节点)
<configuration>
  <!-- 指定 NameNode 的 RPC 地址(生产环境为真实 NN 的 IP/hostname) -->
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://hadoop-nn1:9000</value>  <!-- 替换为实际的 NameNode hostname -->
  </property>
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/opt/hadoop-3.3.6/tmp</value>
  </property>
</configuration>
(3)hdfs-site.xml(所有节点)
<configuration>
  <!-- NameNode 元数据存储目录 -->
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>/opt/hadoop-3.3.6/namenode_data</value>
  </property>
  <!-- DataNode 数据存储目录 -->
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>/opt/hadoop-3.3.6/datanode_data</value>
  </property>
  <!-- 副本数(生产环境建议 3,根据 DN 数量调整) -->
  <property>
    <name>dfs.replication</name>
    <value>3</value>
  </property>
  <!-- NameNode HTTP UI 端口(Hadoop 3.x) -->
  <property>
    <name>dfs.namenode.http-address</name>
    <value>hadoop-nn1:9870</value>
  </property>
  <!-- DataNode HTTP UI 端口 -->
  <property>
    <name>dfs.datanode.http.address</name>
    <value>0.0.0.0:9864</value>
  </property>
</configuration>
(4)workers(仅 NameNode 节点,列出所有 DataNode 的 hostname)
hadoop-dn1
hadoop-dn2

注:Hadoop 3.x 使用 workers 文件(替代 2.x 的 slaves),需确保所有 DataNode 的 hostname 能被 NameNode 解析(通过 /etc/hosts 或 DNS)。

步骤 3:分发 Hadoop 到所有节点

将配置好的 Hadoop 目录同步到所有 DataNode(保持路径一致):

# 从 NameNode 执行(假设使用 scp)
scp -r /opt/hadoop-3.3.6 hadoop-dn1:/opt/
scp -r /opt/hadoop-3.3.6 hadoop-dn2:/opt/
步骤 4:启动集群

在 NameNode 节点执行:

# 启动 HDFS(NameNode + 所有 DataNode)
start-dfs.sh

# 验证进程
jps  # NameNode 节点应看到 NameNode、SecondaryNameNode;DataNode 节点应看到 DataNode

# 查看 Web UI
# NameNode UI: http://hadoop-nn1:9870(确认 DataNode 数量为 2)
# DataNode UI: http://hadoop-dn1:9864、http://hadoop-dn2:9864

三、HDFS 基础配置

3.1 核心配置文件说明

文件 关键参数 作用
core-site.xml fs.defaultFS 指定 HDFS 的命名服务地址(如 hdfs://nn-host:9000)。
hadoop.tmp.dir HDFS 临时数据的本地存储路径(如元数据备份、临时文件)。
hdfs-site.xml dfs.namenode.name.dir NameNode 元数据的本地存储目录(需持久化存储,如 SSD)。
dfs.datanode.data.dir DataNode 数据块的本地存储目录(可配置多个路径,逗号分隔)。
dfs.replication 数据块的副本数(生产环境建议 3,根据 DN 数量调整)。
dfs.webhdfs.enabled 是否启用 WebHDFS(支持 HTTP REST API 访问 HDFS)。

3.2 生产环境推荐配置

  • 副本数​:根据 DataNode 数量设置(例如 5 个 DN 可设为 3~5,保证高可用)。
  • 存储目录​:NameNode 的 dfs.namenode.name.dir 建议使用 RAID 或分布式存储(避免单磁盘故障导致元数据丢失)。
  • 内存分配​:NameNode 的 JVM 堆内存需根据元数据量调整(例如 -Xmx4g ~ -Xmx8g,可通过 hadoop-env.sh 中的 HADOOP_NAMENODE_OPTS 配置)。

四、HDFS 调试与运行

4.1 基本操作命令

HDFS 提供命令行工具(hdfs dfs)和 Java API 进行文件操作,常用命令如下:

(1)文件上传/下载
# 上传本地文件到 HDFS 根目录
hdfs dfs -put /local/path/file.txt /hdfs/path/

# 下载 HDFS 文件到本地
hdfs dfs -get /hdfs/path/file.txt /local/path/

# 从本地复制文件到 HDFS(等同于 put)
hdfs dfs -copyFromLocal /local/file.txt /hdfs/

# 从 HDFS 复制文件到本地(等同于 get)
hdfs dfs -copyToLocal /hdfs/file.txt /local/
(2)目录操作
# 创建目录
hdfs dfs -mkdir -p /user/hadoop/data

# 列出目录内容
hdfs dfs -ls /  # 查看根目录
hdfs dfs -ls -h /user/hadoop/data  # -h 显示人类可读的单位(如 KB/MB)

# 删除文件/目录(-rm 删除文件,-rm -r 删除目录)
hdfs dfs -rm /hdfs/path/file.txt
hdfs dfs -rm -r /hdfs/path/empty_dir
(3)文件信息与权限
# 查看文件详情(块大小、副本数、存储位置)
hdfs dfs -ls -d /hdfs/path/file.txt

# 修改文件所有者/权限
hdfs dfs -chown hadoop:user /hdfs/path/file.txt
hdfs dfs -chmod 755 /hdfs/path/dir/

4.2 Web UI 调试

  • NameNode WebUI​:http://<nn-host>:9870(Hadoop 3.x),提供以下信息:
    • 集群概览(总容量、已用空间、剩余空间)。
    • DataNode 列表(每个节点的存储使用率、网络状态)。
    • 文件系统浏览器(通过 "Utilities" → "Browse the file system" 查看 HDFS 文件树)。
  • DataNode WebUI​:http://<dn-host>:9864,显示该节点存储的数据块详情和心跳状态。

4.3 常见问题排查

  • 连接失败​:检查 NameNode 的 RPC 端口(默认 9000)和 WebUI 端口(默认 9870)是否开放(防火墙规则)。
  • 数据节点未注册​:查看 NameNode 日志(logs/hadoop-*-namenode-*.log),确认 DataNode 的心跳是否正常(DataNode 默认每 3 秒发送一次心跳)。
  • 权限拒绝​:通过 hdfs dfs -chmodhdfs dfs -chown 调整文件/目录权限。

五、HDFS 运维管理

5.1 集群监控与维护

  • 日常操作​:

    • 查看集群状态​:
      hdfs dfsadmin -report  # 显示 DataNode 数量、存储容量、剩余空间
      hdfs dfs -df -h        # 查看 HDFS 总体存储使用情况
    • 平衡数据分布​(当新 DataNode 加入或数据倾斜时):
      hdfs balancer -threshold 10  # 平衡阈值(默认 10%,表示 DN 间存储使用率差异超过 10% 时移动数据)
    • 清理临时文件​:
      hdfs dfs -expunge  # 清空 HDFS 客户端的本地垃圾箱(用户删除文件后默认进入垃圾箱,保留 7 天)
  • 高级维护​:

    • 退役 DataNode​(安全下线节点):

      1. hdfs-site.xml 中配置排除列表:
        <property>
          <name>dfs.hosts.exclude</name>
          <value>/opt/hadoop-3.3.6/etc/hadoop/excludes</value>
        </property>
      2. 创建 excludes 文件,写入要退役的 DataNode hostname(每行一个),然后刷新配置:
        hdfs dfsadmin -refreshNodes
      3. 等待数据迁移完成后,从 workers 文件中移除该节点并重启集群。
    • 修复损坏的块​:

      hdfs fsck / -delete  # 检查整个文件系统的块健康状态,并删除无法修复的损坏块(谨慎操作!)

5.2 日志与告警

  • 关键日志路径​:
    • NameNode 日志:logs/hadoop-*-namenode-*.log(记录元数据操作、DataNode 心跳)。
    • DataNode 日志:logs/hadoop-*-datanode-*.log(记录数据块读写、心跳上报)。
  • 日志级别调整​:修改 log4j.properties 文件(位于 etc/hadoop/),例如将 NameNode 日志级别改为 DEBUG:
    log4j.logger.org.apache.hadoop.hdfs.server.namenode=DEBUG

六、HDFS 测试实践

6.1 功能测试

  • 小文件上传/下载​:验证基本读写功能(例如上传 1KB~10MB 的文本文件)。
  • 大文件分块存储​:上传超过 128MB 的文件(默认块大小),通过 Web UI 查看块分布和副本数。
  • 目录递归操作​:创建多级目录并上传文件,验证 ls -Rrm -r 的正确性。

6.2 性能测试

  • 吞吐量测试​:使用 hadoop jar 自带的基准工具(如 TestDFSIO)测试读写性能:
    # 写入测试(生成 1GB 文件,1 个 Map 任务)
    hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.3.6-tests.jar TestDFSIO -write -nrFiles 1 -fileSize 1GB
    
    # 读取测试(读取刚才生成的文件)
    hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.3.6-tests.jar TestDFSIO -read -nrFiles 1 -fileSize 1GB
    结果会输出吞吐量(MB/s)、I/O 延迟等指标。

6.3 故障模拟测试

  • DataNode 宕机​:手动停止某个 DataNode 进程,观察 NameNode 是否检测到节点离线(Web UI 显示 "Dead"),并验证数据读取是否仍可用(通过副本)。
  • 网络分区​:模拟 NameNode 与部分 DataNode 网络不通,检查副本恢复机制。

七、HDFS 安全配置

7.1 认证与授权

  • Kerberos 认证​(生产环境必备):

    1. 部署 Kerberos KDC 服务(如 MIT Kerberos)。
    2. 为 HDFS 组件(NameNode/DataNode)和用户创建 Kerberos 主体(Principal)和密钥表(Keytab)。
    3. 配置 core-site.xmlhdfs-site.xml
      <!-- core-site.xml -->
      <property>
        <name>hadoop.security.authentication</name>
        <value>kerberos</value>
      </property>
      <property>
        <name>hadoop.security.authorization</name>
        <value>true</value>
      </property>
      
      <!-- hdfs-site.xml -->
      <property>
        <name>dfs.namenode.kerberos.principal</name>
        <value>nn/_HOST@EXAMPLE.COM</value>
      </property>
      <property>
        <name>dfs.datanode.kerberos.principal</name>
        <value>dn/_HOST@EXAMPLE.COM</value>
      </property>
    4. 启动 HDFS 时使用 Kerberos 凭据(通过 kinit 认证)。
  • 简单认证(开发环境)​​:通过 hadoop-policy.xml 配置用户/组的访问权限(不推荐生产使用)。

7.2 数据安全

  • 传输加密​:启用 HDFS 的 RPC 和 HTTP 通信加密(配置 SSL/TLS)。
  • 存储加密​:使用 HDFS 透明加密(HDFS Transparent Encryption),为敏感目录配置加密区域(Encryption Zone)和密钥。

7.3 权限控制

  • POSIX 风格权限​:HDFS 支持类似 Linux 的用户/组/其他权限(rwx),通过 hdfs dfs -chmodhdfs dfs -chown 管理。
  • ACL(访问控制列表)​​:为特定用户/组设置细粒度权限(例如允许用户 A 读写某目录,但禁止其他用户访问)。

附录

常见问题

  1. NameNode 启动失败​:检查 java_home 是否配置正确,磁盘空间是否充足(hadoop.tmp.dir 目录需有写入权限)。
  2. DataNode 无法注册​:确认 DataNode 的 dfs.datanode.data.dir 目录可写,且 NameNode 的防火墙放行了 DataNode 的心跳端口(默认 50010/50020)。
  3. 文件读取慢​:检查副本数是否足够(dfs.replication),DataNode 的磁盘 I/O 是否瓶颈(通过 iostat 监控)。

推荐学习资源


通过本教程,您已掌握 HDFS 从环境搭建到生产运维的全流程技能,可结合 Spark/Flink 等计算框架构建完整的大数据平台。

注:本文仅用于教育目的,实际渗透测试必须获得合法授权。未经授权的黑客行为是违法的。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐