Skip to content

一、 单项选择题 ​

  1. 在 Hadoop 3.x 版本中,HDFS 默认使用哪个端口号作为 NameNode 的 Web 界面端口?( )

    A. 50070

    B. 9870

    C. 8088

    D. 8020

  2. HDFS 的设计目标是支持哪种类型的数据访问模式?( )

    A. 大量小文件的随机读写

    B. 一次写入,多次读取(Write-Once, Read-Many)

    C. 高并发的随机更新

    D. 实时流式处理

  3. 在 Hadoop 集群启动脚本中,用于启动所有 NameNode、DataNode、ResourceManager 和 NodeManager 进程的命令是?( )

    A. start-namenode.sh

    B. start-all.sh(Hadoop 2.x 常用)

    C. start-dfs.sh

    D. start-dfs.sh 和 start-yarn.sh 组合,或使用 start-all.sh (如果配置了)

  4. 在 MapReduce 编程模型中,哪个阶段负责将 Mapper 输出的键值对进行分组和排序?( )

    A. Map

    B. Shuffle

    C. Reduce

    D. InputFormat

  5. 在 Hive 中,如果需要创建一个表,并指定数据存储在 HDFS 的某个特定目录,应该使用哪个关键字?( )

    A. ROW FORMAT

    B. STORED AS

    C. LOCATION

    D. PARTITIONED BY

  6. HBase 是一个基于 HDFS 的( )数据库。

    A. 关系型

    B. 图形

    C. 列式(Column-oriented/Key-Value)

    D. 文档型

  7. 使用 IDEA 进行 MapReduce 程序开发时,通常需要将项目打包成什么格式才能提交到 Hadoop 集群运行?( )

    A. .zip

    B. .war

    C. .jar

    D. .class

  8. 当 DataNode 发生故障时,HDFS 能够通过什么机制来保证数据不丢失?( )

    A. NameNode 备份

    B. 多副本(Replication)机制

    C. Checkpoint 机制

    D. 快照(Snapshot)

  9. 在 Hadoop 集群运维中,如果 DataNode 进程启动失败,首先需要检查的文件是哪个?( )

    A. yarn-site.xml

    B. DataNode 的日志文件

    C. mapred-site.xml

    D. /etc/hosts

  10. 以下哪个命令是用于查看 HDFS 根目录下文件的?( )

    A. hdfs fs -ls /

    B. hadoop fs -ls /

    C. hdfs dfs -ls /

    D. 以上都是常用且正确的命令

  11. Hadoop集群中,NameNode的主要作用是()

    A. 存储实际数据

    B. 管理HDFS的命名空间和元数据

    C. 执行MapReduce任务

    D. 协调各节点之间的通信

  12. HDFS默认的数据块大小是()

    A. 64MB

    B. 128MB

    C. 256MB

    D. 512MB

  13. 在Hadoop集群部署中,以下哪个文件用于配置集群的所有DataNode节点()

    A. hadoop-env.sh

    B. core-site.xml

    C. workers

    D. hdfs-site.xml

  14. MapReduce中,Shuffle过程发生在()阶段

    A. Map之前

    B. Map和Reduce之间

    C. Reduce之后

    D. 只在Map阶段

  15. Hive的数据存储默认位于()

    A. 本地文件系统

    B. HDFS

    C. MySQL数据库

    D. HBase

  16. HBase是基于()模型的NoSQL数据库

    A. 关系型

    B. 文档型

    C. 列族

    D. 图数据库

  17. 以下哪个命令可以查看HDFS集群的健康状态()

    A. hadoop fs -ls

    B. hdfs dfsadmin -report

    C. start-dfs.sh

    D. jps

  18. 在Java API中,以下哪个类用于读取HDFS文件()

    A. FileOutputStream

    B. FSDataInputStream

    C. BufferedReader

    D. FileReader

  19. Hadoop集群启动顺序,正确的是()

    A. 先启动YARN,再启动HDFS

    B. 先启动HDFS,再启动YARN

    C. 可以任意顺序启动

    D. 必须同时启动

  20. Hadoop 集群中负责资源管理与任务调度的组件是:

    A. NameNode

    B. DataNode

    C. ResourceManager

    D. NodeManager

  21. HDFS 中用于存储文件元数据(如文件块位置)的角色是:

    A. SecondaryNameNode

    B. NameNode

    C. DataNode

    D. JobTracker

  22. 在 Hadoop 集群部署中,以下哪个是 SSH 免密登录的作用?

    A. 提高 HDFS 读写速度

    B. 实现节点间自动任务分发

    C. 允许节点间无密码执行命令

    D. 保证 NameNode 高可用

  23. 在 IDEA 中编写 Hadoop 程序时,需要引入的依赖一般为:

    A. hadoop-common/hadoop-hdfs

    B. mysql-connector-java

    C. spark-core

    D. hive-jdbc

  24. 向 HDFS 上传一个文件的命令是:

    A. hdfs dfs -get

    B. hdfs dfs -put

    C. hdfs dfs -touchz

    D. hdfs dfs -du

  25. 启动 HBase 服务的命令通常是:

    A. start-dfs.sh

    B. start-yarn.sh

    C. start-hbase.sh

    D. hbase shell

  26. Hive 的默认运行模式是:

    A. 本地模式

    B. MapReduce 模式

    C. Tez 模式

    D. Spark 模式

  27. 以下哪个是 Java HDFS API 中常用的文件系统对象?

    A. FileSystem

    B. ConfigurationManager

    C. HadoopFS

    D. HdfsReader

  28. 以下哪个操作属于 Hadoop 集群运维工作?

    A. Java 编写 Mapper 程序

    B. HDFS 文件读取

    C. 检查 NameNode 状态和 DataNode 存活

    D. 编写 Hive SQL

  29. 下列不属于Hadoop集群常见部署模式的是( )

    A. 单机模式 B. 伪分布式模式

    C. 完全分布式模式 D. 云原生模式

  30. 在Hadoop集群部署过程中,以下哪个配置文件用于指定Hadoop的环境变量(如JDK路径)( )

    A. core-site.xml B. hadoop-env.sh

    C. hdfs-site.xml D. mapred-site.xml

  31. HDFS中负责存储实际数据块的角色是( )

    A. NameNode B. DataNode

    C. SecondaryNameNode D. ResourceManager

  32. MapReduce编程模型中,负责将输入数据分割成数据块的阶段是( )

    A. Map阶段 B. Shuffle阶段

    C. Reduce阶段 D. InputFormat阶段

  33. 使用IDEA开发Hadoop Java API程序时,需要导入的核心依赖包所属的组织是( )

    A. org.apache.spark B. org.apache.hadoop

    C. org.apache.hive D. org.apache.hbase

  34. Hive的核心功能是( )

    A. 数据存储 B. 数据计算

    C. 将SQL转换为MapReduce任务 D. 集群监控

  35. HBase中用于唯一标识一行数据的是( )

    A. 列族 B. 列

    C. 行键(RowKey) D. 时间戳

  36. 在Hadoop集群运维中,用于启动HDFS集群的命令是( )

    A. start-dfs.sh B. start-yarn.sh

    C. start-all.sh D. hdfs start

  37. 下列关于HDFS的描述,错误的是( )

    A. HDFS适合存储大文件 B. HDFS支持随机写操作

    C. HDFS通过副本机制保证数据可靠性 D. HDFS采用主从架构

  38. Hive中创建表时,用于指定表数据存储位置的关键字是( )

    A. location B. path

    C. directory D. storage

  39. Hadoop集群部署前不需要做以下哪项准备工作?

    A. 配置SSH免密登录 B. 安装JDK C. 关闭防火墙 D. 安装MySQL数据库

  40. HDFS默认的块大小是:

    A. 64MB B. 128MB C. 256MB D. 512MB

  41. 格式化NameNode的命令是:

    A. hdfs datanode -format B. hadoop namenode -format C. hdfs namenode -format D. hadoop format

  42. 启动Hadoop集群所有服务的命令是:

    A. start-dfs.sh B. start-yarn.sh C. start-all.sh D. hadoop-start.sh

  43. 在MapReduce中,哪个阶段负责将相同key的数据聚合在一起?

    A. Map B. Shuffle C. Reduce D. Combiner

  44. HDFS的默认副本数是:

    A. 1 B. 2 C. 3 D. 4

  45. 以下哪个不是Hadoop生态圈的组件?

    A. Hive B. HBase C. Spark D. MySQL

  46. 在Hadoop伪分布式部署中,所有守护进程运行在:

    A. 多台机器 B. 一台机器 C. 虚拟机 D. 容器

  47. 以下哪个命令用于查看HDFS文件列表?

    A. hdfs dfs -ls B. hdfs dfs -cat C. hdfs dfs -mkdir D. hdfs dfs -rm

  48. Hive的作用是:

    A. 分布式计算 B. 分布式存储 C. 数据仓库和SQL查询 D. 实时数据处理

  49. Hadoop的核心组件不包括以下哪一项?

    A. HDFS B. MapReduce

    C. YARN D. MySQL

  50. 以下哪个端口不是Hadoop集群中常用的默认端口?

    A. 50070 (NameNode Web UI)

    B. 8088 (ResourceManager Web UI)

    C. 3306 (MySQL)

    D. 9000 (HDFS RPC)

  51. 在HDFS中,负责存储文件数据的节点是?

    A. NameNode

    B. DataNode

    C. SecondaryNameNode

    D. ResourceManager

  52. MapReduce编程模型中,Map阶段的输出会经过哪个过程后进入Reduce阶段?

    A. 排序和分区

    B. 压缩和解压

    C. 加密和解密

    D. 复制和备份

  53. 在Hive中,将SQL语句转换为MapReduce任务的组件是?

    A. Driver

    B. Metastore

    C. Compiler

    D. Execution Engine

  54. HBase是基于哪种数据库模型构建的?

    A. 关系型数据库

    B. 键值对存储

    C. 文档数据库

    D. 图数据库

  55. 在IDEA中创建Maven项目时,用于管理Hadoop依赖的配置文件是?

    A. pom.xml B. build.gradle

    C. settings.xml D. application.properties

  56. 以下哪个命令用于在HDFS上创建一个新目录?

    A. hdfs dfs -mkdir /test B. hdfs dfs -create /test

    C. hdfs dfs -newdir /test D. hdfs dfs -add /test

  57. 在YARN中,负责管理应用程序资源分配的组件是?

    A. NodeManager B. ApplicationMaster

    C. ResourceManager D. Container

  58. 当Hadoop集群中的DataNode发生故障时,HDFS会自动?

    A. 停止整个集群

    B. 从其他DataNode复制数据块副本

    C. 删除故障节点上的所有数据

    D. 等待管理员手动恢复

重点知识总结 ​

  • 端口变化: Hadoop 3.x 中 NameNode Web UI 从 50070 改为 9870
  • 默认配置: 块大小 128MB,副本数 3
  • 启动顺序: 先 HDFS,后 YARN
  • 核心组件: HDFS(存储) + MapReduce(计算) + YARN(资源管理)
  • Hive: SQL → MapReduce 转换工具
  • HBase: 列式 NoSQL 数据库

二、判断题 ​

  1. (×) NameNode 负责存储文件的实际数据。
    • 错误。NameNode 存储元数据(文件目录结构、块位置等),DataNode 才存储实际数据。
  2. (√) HDFS 适合存储大文件,不适合大量的小文件。
    • 正确。小文件会占用大量 NameNode 内存,影响性能。
  3. (×) MapReduce 程序必须包含 Mapper 和 Reducer 两部分。
    • 错误。可以只有 Mapper(Map-Only 任务)。
  4. (√) Hive 可以自动将 SQL 转换为 MapReduce 或 Tez 作业执行。
    • 正确。这是 Hive 的核心功能。
  5. (√) HBase 擅长海量数据的随机读写。
    • 正确。这是 HBase 的主要优势。
  6. (×) Hadoop 集群中可以有多个 NameNode 同时工作在 Active 状态。
    • 错误。HA 模式下只能有一个 Active NameNode,其他处于 Standby 状态。
  7. (√) HDFS 的副本数可以通过 dfs.replication 参数配置。
    • 正确。默认值通常是 3。
  8. (×) MapReduce 中,Reduce 任务的数量由输入数据的 splits 数量决定。
    • 错误。Map 任务数由 splits 决定,Reduce 任务数由程序指定或配置决定。
  9. (×) SecondaryNameNode 是 NameNode 的热备份节点。
    • 错误。它负责合并 fsimage 和 edits,不是热备份(热备份是 Standby NameNode)。
  10. (×) Hive 支持标准 SQL 的所有语法。
    • 错误。Hive 支持类 SQL(HiveQL),但不是完整的标准 SQL。
  11. (×) HBase 适合存储大量小文件。
    • 错误。HBase 适合结构化数据的随机读写,不适合存储文件。
  12. (√) 在 Java API 中操作 HDFS 需要导入 org.apache.hadoop.fs 包。
    • 正确。这是 HDFS 文件系统 API 的核心包。
  13. (√) Hadoop 集群停止时应先停止 YARN,再停止 HDFS。
    • 正确。正确的停止顺序是:先停止上层应用(如 YARN 的 ResourceManager 和 NodeManager),确保没有作业运行;然后停止底层文件系统(HDFS 的 NameNode 和 DataNode)。
  14. (√) HDFS 的 fsck 命令可以用来检查文件系统的健康状况。
    • 正确。fsck = file system check。
  15. (√) Hive 的元数据默认存储在 Derby 数据库中。
    • 正确。Derby 是默认的嵌入式数据库,生产环境通常用 MySQL。

关键知识点总结 ​

  • NameNode: 元数据管理,不存数据
  • SecondaryNameNode: 辅助合并日志,不是备份
  • MapReduce: Reducer 可选
  • HBase: 随机读写,不是文件存储
  • HDFS: 适合大文件,不适合小文件

三、 填空题 ​

  1. Hadoop 集群的核心组件包括 HDFS、MapReduce 和 YARN。
  2. HDFS 默认的数据块大小是 128 MB(Hadoop 2.x/3.x 版本),默认的副本数是 3 个。
  3. Hive 元数据默认存储在 Derby 数据库中(单机模式下),用于记录表结构、数据位置等信息。
  4. HBase 是基于 列式(或列族) 模型的分布式数据库,其表结构由 行键(RowKey) 和列组成。
  5. 在完全分布式 Hadoop 集群中,为实现节点间免密登录,需要生成 公钥(Public Key) 密钥和 私钥(Private Key) 密钥。
  6. Hadoop 的三大核心组件是 HDFS、MapReduce 和 YARN。
  7. HDFS 采用 主从 架构,由 NameNode 和 DataNode 组成。
  8. 在 Hadoop 完全分布式部署中,通常需要配置 workers(Hadoop 3.x)文件来指定从节点主机名。
  9. 格式化 HDFS 的命令是 hdfs namenode -format。
  10. HDFS 默认 Web 界面访问端口是 9870 (Hadoop 3.x),YARN 的 Web 界面端口是 8088。
  11. MapReduce 作业中,Map 阶段负责数据的分片和映射,Reduce 阶段负责数据的聚合和输出。
  12. HBase 是一个 NoSQL 型的分布式数据库,适用于 随机读写 查询场景。
  13. 在 Hadoop 集群中,ResourceManager(或YARN)负责资源管理和任务调度。
  14. Hadoop 集群通常有三种部署模式:单机模式、伪分布式模式和完全分布式模式。
  15. 在 HDFS 中,文件被分割成固定大小的数据块,默认大小为 128 MB。
  16. MapReduce 程序的两个核心函数是 Map 和 Reduce。
  17. 在 IDEA 中运行 MapReduce 程序前,需要配置 Maven 插件来支持 Hadoop 开发(用于管理依赖和打包)。
  18. HBase 的底层存储依赖于 HDFS 文件系统。
  19. 查看 HDFS 磁盘使用情况的命令是 hdfs dfsadmin -report(查看整体报告)或 hdfs dfs -du(查看指定目录)。
  20. 启动 Hadoop 集群的命令是 start-all.sh 或 start-dfs.sh 和 start-yarn.sh(在主节点执行)。
  21. 在 HBase Shell 中,创建表的命令是 create '表名', '列族名'。
  22. Hadoop 集群中,通常用于资源调度的组件是 YARN。
  23. 在 MapReduce 编程中,用户自定义的 Mapper 类需要继承自 org.apache.hadoop.mapreduce.Mapper,其输出的 Key 和 Value 必须是 Hadoop 自定义的 Writable 类型。
  24. 要使用 Java API 将本地文件 /home/data/input.txt 上传到 HDFS 的 /user/test 目录下,需要使用 FileSystem 类的 copyFromLocalFile 方法。
  25. 在 Hive 中,如果一张表的元数据被删除,但 HDFS 上的数据文件仍然保留,那么这张表是 外部表(EXTERNAL TABLE)。
  26. HBase 的数据存储结构是 表(Table),它由 行键(Row Key)、列族(Column Family) 和 时间戳(Timestamp) 唯一确定一个单元格(Cell)。

重要知识点补充 ​

HDFS 配置

  • 块大小: Hadoop 1.x = 64MB, Hadoop 2.x/3.x = 128MB
  • 副本数: 默认 3 个
  • 端口: Hadoop 2.x = 50070, Hadoop 3.x = 9870

MapReduce 数据类型

常见的 Writable 类型对应:

  • Java String → Text
  • Java int → IntWritable
  • Java long → LongWritable
  • Java boolean → BooleanWritable

HBase 数据模型

  • 行键(RowKey): 唯一标识
  • 列族(Column Family): 列的集合
  • 列(Column): 具体数据列
  • 时间戳(Timestamp): 版本控制

配置文件

  • workers/slaves: 指定 DataNode 和 NodeManager 节点
  • core-site.xml: 核心配置
  • hdfs-site.xml: HDFS 配置
  • yarn-site.xml: YARN 配置
  • mapred-site.xml: MapReduce 配置

四、 简答题 ​

📝 Hadoop 集群部署与运维 ​

1. 简述 Hadoop 伪分布式部署和完全分布式部署的主要区别。 ​

  • 伪分布式部署 (Pseudo-Distributed Mode):
    • 节点数量: 仅使用一台物理机器或虚拟机。
    • 角色分配: 所有的 Hadoop 核心组件(如 NameNode、DataNode、ResourceManager、NodeManager)都运行在同一台机器上。
    • 目的: 主要用于测试、开发和学习 Hadoop,模拟分布式环境,但不具备真正的横向扩展和高可用性。
  • 完全分布式部署 (Fully Distributed Mode):
    • 节点数量: 使用多台物理机器或虚拟机组成的集群。
    • 角色分配: 不同的 Hadoop 核心组件分布在不同的机器上(例如,NameNode 在一台机器,多个 DataNode 分布在多台机器)。
    • 目的: 用于生产环境,提供高可用性、容错性、横向扩展和高性能的数据存储和处理能力。

2. 简述 Hadoop 集群部署前的准备工作。 ​

成功的 Hadoop 部署需要充分的准备工作:

  • 硬件与网络准备:
    • 准备多台物理机或虚拟机,并确保它们之间网络互通。
    • 保证足够的内存和磁盘空间。
  • 操作系统配置:
    • 设置 静态 IP 地址。
    • 配置 主机名 (hostname) 和 /etc/hosts 文件,以便通过主机名互相访问。
    • 关闭防火墙(或配置正确的端口访问规则)。
    • 关闭 SELinux。
  • 软件环境准备:
    • 安装和配置 JDK,设置 $JAVA_HOME。
    • 配置 SSH 免密登录:实现 NameNode/ResourceManager 到所有 DataNode/NodeManager 节点的免密连接。
    • 同步所有节点上的系统时间,通常通过 NTP 服务实现。

3. 简述 Hadoop 伪分布式集群的部署步骤(至少包含 5 个关键步骤)。 ​

伪分布式部署在单机上模拟了分布式环境,主要步骤如下:

  1. 环境准备: 安装 Java Development Kit (JDK) 并配置 $JAVA_HOME 环境变量。
  2. 下载与解压: 下载 Hadoop 安装包并解压到指定目录。
  3. 配置文件修改: 修改核心配置文件,特别是配置 core-site.xml(配置 HDFS 的 NameNode 地址)和 hdfs-site.xml(配置 DataNode 数据存储目录和副本数)。
  4. SSH 免密登录配置: 配置本机到本机的 SSH 免密登录,这是启动和管理 Hadoop 进程所必需的。
  5. 格式化 NameNode: 首次启动前,执行 hdfs namenode -format 格式化文件系统。
  6. 启动集群: 执行 start-all.sh(或 start-dfs.sh 和 start-yarn.sh)启动所有 Hadoop 进程。
  7. 验证: 使用 jps 命令检查 NameNode、DataNode 等进程是否成功启动。

4. 📝简述 Hadoop 集群部署的主要步骤(至少 4 步)。 ​

Hadoop 完全分布式集群部署的主要步骤简述:

1. 基础环境准备(所有节点) ​

这是集群部署的前提,必须在所有参与的机器上完成:

  • 硬件与网络: 准备多台物理机或虚拟机,确保它们之间网络互通。
  • 安装 JDK: 在所有节点上安装 Java Development Kit (JDK),并配置正确的 $JAVA_HOME 环境变量。
  • 主机名与 hosts 配置: 设置每台机器的静态 IP 和主机名,并修改 /etc/hosts 文件,确保集群内各节点能通过主机名互相解析。
  • 关闭防火墙/SELinux: 禁用防火墙或正确配置端口访问权限,并关闭 SELinux,确保组件间通信畅通。
  • 时间同步: 配置 NTP 服务,同步集群中所有机器的系统时间。

2. SSH 免密登录配置(主节点到所有节点) ​

  • 在主节点(通常是 NameNode 和 ResourceManager 所在的机器)上生成 SSH 密钥对。
  • 将主节点的公钥 (id_rsa.pub) 复制到所有从节点(DataNode 和 NodeManager)的授权文件 (authorized_keys) 中。
  • 目标是实现主节点可以免密码登录到所有从节点,以便启动和管理集群服务。

3. Hadoop 软件安装与环境变量配置(所有节点) ​

  • 下载并解压 Hadoop 安装包到指定目录(如 /usr/local/hadoop)。
  • 配置 $HADOOP_HOME 和 $PATH 环境变量,并将 Hadoop 相关的环境变量(如 $JAVA_HOME)同步到 $HADOOP_HOME/etc/hadoop/hadoop-env.sh 中。

4. 核心配置文件修改(主节点) ​

在主节点的 $HADOOP_HOME/etc/hadoop 目录下,根据集群规划修改以下关键文件:

配置文件关键配置项作用
core-site.xmlfs.defaultFS设置 NameNode 的 URI(集群入口)。
hadoop.tmp.dir设置 Hadoop 共享的临时文件目录。
hdfs-site.xmldfs.replication设置文件块的默认副本数(通常为 3)。
dfs.namenode.http-addressNameNode 的 Web UI 地址。
yarn-site.xmlyarn.resourcemanager.hostname设置 ResourceManager 的主机名。
yarn.nodemanager.aux-services启用 Shuffle 服务,支持 MapReduce。
workers (或 slaves)DataNode/NodeManager 主机名列表包含所有 DataNode 和 NodeManager 的主机名。

5. 文件分发与同步(主节点到从节点) ​

  • 将修改完成的整个 $HADOOP_HOME 目录(特别是配置文件夹 etc/hadoop)同步复制到所有从节点上,确保配置一致性。

6. 首次格式化与集群启动(主节点) ​

  • 格式化 NameNode: 在 NameNode 节点上执行 hdfs namenode -format。(注意:仅在首次部署时执行!)
  • 启动 HDFS: 执行 start-dfs.sh 启动 NameNode 和所有 DataNode 进程。
  • 启动 YARN: 执行 start-yarn.sh 启动 ResourceManager 和所有 NodeManager 进程。

7. 集群验证与测试 ​

  • 进程检查: 在所有节点上使用 jps 命令,验证 NameNode、DataNode、ResourceManager 和 NodeManager 进程是否正常启动。
  • Web UI 检查: 通过浏览器访问 NameNode (例如 http://namenode_hostname:9870) 和 ResourceManager (例如 http://resourcemanager_hostname:8088) 的 Web UI,检查集群健康状态、活动节点数和容量信息。
  • 功能测试: 运行一个简单的 WordCount 示例 Job 或进行 HDFS 文件操作,确保集群功能正常。

5.列举 Hadoop 生态系统中至少 5 个常用组件,并简要说明它们的作用 ​

Hadoop 生态系统是一个庞大的软件集合,旨在解决大数据存储、处理和分析等问题。

序号组件名称英文缩写核心作用简述
1HDFSHDFS分布式文件存储系统: 为 Hadoop 集群提供底层高容错、高吞吐量的存储服务,适合存储大规模数据集。
2YARNYARN资源管理和调度系统: 负责整个集群的资源分配(CPU、内存)和任务调度,允许多种计算框架(如 MapReduce、Spark)运行在同一个集群上。
3MapReduceMR分布式批处理计算框架: 一种编程模型和执行引擎,用于对存储在 HDFS 中的海量数据进行并行计算和批处理分析。
4HiveHive数据仓库工具: 提供 HQL(类似 SQL)查询语言接口,将用户的 SQL 语句转换为 MapReduce/Tez/Spark 任务,用于离线数据分析和报表生成。
5HBaseHBase分布式 NoSQL 数据库: 一个面向列的稀疏存储数据库,构建于 HDFS 之上,提供对海量数据的实时、随机读写访问。
6ZooKeeperZK分布式协调服务: 为分布式应用提供配置管理、命名服务、分布式同步和集群状态维护等服务,常用于 NameNode/ResourceManager 的高可用 (HA) 协调。
7FlumeFlume日志采集工具: 一个用于将大量日志数据从各种来源高效地收集、聚合和移动到 HDFS 或 HBase 等存储系统中的服务。
8SqoopSqoop关系型数据导入导出工具: 用于在 Hadoop(HDFS, Hive, HBase)与传统关系型数据库(如 MySQL, Oracle)之间进行高效数据传输。

6. 简述 Hadoop 集群中 NameNode 和 DataNode 的作用及区别。 ​

特性NameNode(名称节点/主节点)DataNode(数据节点/从节点)
作用元数据管理: 存储文件系统的命名空间(目录树)、文件和数据块的映射关系、以及数据块的副本信息等。是 HDFS 的核心。数据存储: 存储实际的文件数据块。负责读写请求、执行数据块的创建、删除、复制等操作。
数量一个(高可用模式下通常是两个:Active 和 Standby)。多个(负责横向扩展和容错)。
职责接收客户端请求,分配数据块存储位置,管理文件系统操作。定期向 NameNode 发送心跳和块报告,告知其存储的数据块信息。
重要性至关重要。它的故障会导致整个文件系统无法访问(除非配置了高可用性 HA)。可容错。一个或多个 DataNode 故障只会导致部分数据块丢失,HDFS 会自动进行副本恢复。

7. 简述如何扩容 Hadoop 集群(增加 DataNode 节点)。 ​

增加 DataNode 是 Hadoop 集群最常见的扩容方式:

  1. 新节点环境准备: 在新 DataNode 机器上安装 JDK,配置主机名、/etc/hosts,并保证与集群时间同步。
  2. 安装 Hadoop: 将 Hadoop 安装包复制到新节点,并配置 $HADOOP_HOME 环境变量。
  3. 配置文件同步: 将主节点上的 core-site.xml、hdfs-site.xml 等配置文件同步到新 DataNode 节点。
  4. 启动 DataNode: 在新节点上执行 hdfs --daemon start datanode(仅启动 DataNode 进程)。
  5. 验证:
    • 在主节点上通过 hdfs dfsadmin -report 命令或访问 NameNode Web UI 检查新 DataNode 是否成功加入并报告心跳。
    • 在 DataNode 上使用 jps 检查 DataNode 和 NodeManager 进程是否运行。

8. Hadoop 集群日常运维中需要检查哪些关键指标? ​

日常运维主要关注集群的健康状态、性能和资源利用率:

关注组件关键检查指标
HDFS 存储集群健康状态(NameNode Web UI):Live Nodes 数量、Dead Nodes 数量、总存储容量、已用容量、文件副本丢失率(Under-replicated blocks)。
YARN 计算ResourceManager 状态:Active Nodes、Lost Nodes、Unhealthy Nodes、集群资源利用率(总内存、已用内存、CPU 核数)。
系统层面各节点负载:CPU 利用率、内存使用情况、网络 I/O、磁盘 I/O。
日志与异常各组件(NameNode, DataNode, ResourceManager, NodeManager)的日志文件中是否存在 WARN 或 ERROR 级别的错误信息。
安全性用户权限、认证状态(如 Kerberos 票据有效期)。

📝 HDFS 核心概念与运维 ​

1. 列举 HDFS 的三个主要配置文件及其作用。 ​

配置文件名称作用核心配置项示例
core-site.xmlHadoop 核心通用配置。 定义了 HDFS 的 NameNode 地址(文件系统入口),以及 Hadoop 集群的通用设置。fs.defaultFS (NameNode 的 URI)
hdfs-site.xmlHDFS 专属配置。 定义了 HDFS 的具体参数,如文件副本数、NameNode 和 DataNode 的数据存放目录、权限等。dfs.replication (文件副本数)
yarn-site.xmlYARN 专属配置。 定义了 YARN 资源管理系统的参数,如 ResourceManager 地址、NodeManager 的资源限制等。(**注:**虽然是 YARN 的配置,但它是 Hadoop 2.x/3.x 集群的必配项,与 HDFS 协同工作。)yarn.resourcemanager.hostname (RM 主机名)
补充说明: mapred-site.xml 配置文件则用于 MapReduce 框架的配置。

2. 简述 HDFS 读取文件的基本流程。 ​

HDFS 读取文件的过程涉及客户端、NameNode 和 DataNode 的协同工作:

  1. 客户端请求: 客户端调用 FileSystem 对象的 open() 方法。
  2. 获取元数据: DistributedFileSystem(HDFS 客户端)向 NameNode 发送 RPC 请求,请求文件数据块的列表以及每个数据块所在的 DataNode 地址。
  3. 返回地址: NameNode 检查权限后,返回数据块列表及其对应的 DataNode 位置信息(通常按距离远近排序)。
  4. 数据传输: 客户端选择一个 DataNode(通常是离自己最近的),并直接连接该 DataNode。
  5. 循环读取: 客户端通过输入流从 DataNode 流式读取数据。读取完一个数据块后,关闭与当前 DataNode 的连接,并继续请求下一个数据块。
  6. 读取完毕: 所有数据块读取完毕后,关闭输入流。

3. 简述 HDFS 的优缺点。 ​

方面优点 (Advantages)缺点 (Disadvantages)
适用性1. 高容错性: 通过数据块多副本机制,保证数据不丢失。1. 不适合低延迟数据访问: HDFS 为高吞吐量而设计,牺牲了延迟,不适合毫秒级的快速查询。
数据特性2. 适合大规模数据存储: 文件大小通常在 GB 或 TB 级别。2. 不适合大量小文件存储: 每个文件、每个数据块的元数据都由 NameNode 管理,大量小文件会耗尽 NameNode 内存。
系统架构3. 流式数据访问: “一次写入,多次读取” (WORM),适合数据分析。3. 不支持任意修改文件: 文件一旦创建,只能追加数据,不能在文件任意位置进行修改。

4. 描述 HDFS 写数据的基本流程(从客户端到最终存储)。 ​

HDFS 写数据的过程是一个流水线 (Pipeline) 传输和确认的过程:

  1. 客户端请求: 客户端调用 create() 方法,向 NameNode 发送 RPC 请求,要求创建文件。
  2. NameNode 响应: NameNode 检查权限,确保文件不存在,然后返回创建成功的响应。
  3. 数据流切分: 客户端开始将文件数据切分成一个个 数据块 (Block)。
  4. DataNode 选址: 客户端向 NameNode 请求存放第一个数据块的 DataNode 列表(根据副本数和机架感知原则选择 N 个 DataNode)。
  5. 数据写入流水线:
    • 客户端将数据块流式传输给第一个 DataNode (DN1)。
    • DN1 接收数据的同时,将其转发给第二个 DataNode (DN2)。
    • DN2 接收数据的同时,将其转发给第三个 DataNode (DN3) (假设副本数为 3)。
    • 整个过程形成一个数据传输流水线。
  6. 确认与关闭: 当 DataNode 链中的最后一个节点 (DN3) 确认数据写入成功后,反向沿着流水线发送确认信息给客户端。客户端收到确认后,关闭数据流,并向 NameNode 报告文件写入完成。

5. HDFS 的主要特点有哪些?(至少 3 点) ​

HDFS 的设计特点使其成为大数据存储的理想选择:

  1. 高容错性 (Fault Tolerance): 核心特点。通过多副本机制(通常 3 个副本)将数据块分散存储在不同的 DataNode 上,即使部分节点故障也不会丢失数据。
  2. 适合大规模数据 (Large Data Sets): HDFS 采用数据块抽象,并支持超大文件(GB、TB 级别)的存储。
  3. 高吞吐量 (High Throughput): 采用流式数据访问(Sequence Access)模式,并且通过并行 I/O 提升了读写速度,适用于大规模数据批处理应用。
  4. 硬件成本低 (Low-Cost Hardware): HDFS 运行在商用硬件(Commodity Hardware)之上,降低了存储成本。

6. 简述 HDFS 的三个核心角色(进程)及其主要职责。(偏运维) ​

角色/进程名称主要职责运维/部署要点
NameNodeHDFS 的主节点。 负责管理文件系统的元数据(命名空间、数据块与 DataNode 的映射关系)。接收客户端的读写请求。单点风险: 必须配置高可用 (HA) 机制(如 Active/Standby NameNode)来避免单点故障。内存: 对内存要求极高,需存储整个文件系统的元数据。
DataNodeHDFS 的从节点。 负责存储实际的数据块。执行数据块的读写操作、复制、删除。横向扩展: 集群扩容主要通过增加 DataNode 节点实现。磁盘: 对磁盘空间和 I/O 性能有要求。心跳: 需定期向 NameNode 发送心跳和块报告。
Secondary NameNodeNameNode 的辅助进程。 并非 NameNode 的热备。 它的主要职责是合并 NameNode 的编辑日志 (edits log),以减轻 NameNode 的工作负担,并周期性地备份命名空间映像 (fsimage)。运维: 周期性执行合并操作。在非 HA 集群中,用于帮助 NameNode 恢复元数据。在 HA 集群中,该角色被 JournalNode 或 QJM 取代。

📝 MapReduce 执行流程与原理 ​

1. MapReduce 程序的执行过程分为哪两个主要阶段?并简单说明每个阶段主要负责的功能。 ​

MapReduce 程序的执行过程从逻辑功能上可以分为两个主要阶段:Map 阶段 和 Reduce 阶段。

  1. Map 阶段 (Mapping Phase):
    • 主要功能: 分布式处理和数据转换。
    • 详细说明: 负责将大规模的输入数据并行地切分和处理。对每条记录应用用户定义的 map() 函数,将原始数据转换为一系列中间键值对。这个阶段强调数据的独立处理。
  2. Reduce 阶段 (Reducing Phase):
    • 主要功能: 数据聚合和结果计算。
    • 详细说明: 接收 Map 阶段的输出(经过 Shuffle 传输并按 Key 排序),对所有具有相同 Key 的 Value 集合应用用户定义的 reduce() 函数,进行最终的统计、求和、计数等聚合操作,并生成最终结果。这个阶段强调数据的汇总计算。

注意: Shuffle 阶段是连接 Map 和 Reduce 的一个关键过渡阶段,是 MapReduce 框架自动完成的,不属于用户自定义的编程逻辑,但对性能至关重要。

2. 简述 MapReduce 的基本执行流程(包括 Map、Shuffle、Reduce 阶段)。 ​

MapReduce 是一种用于处理和生成大数据集的编程模型。其执行流程主要分为以下三个核心阶段:

阶段名称核心角色核心作用
Map 阶段Map Task并行处理数据。 接收输入数据(通常是 HDFS 上的数据块),对数据进行解析、过滤,并执行用户自定义的 map() 函数。输出一系列键值对 (Key-Value Pair)。
Shuffle 阶段Map Task & Reduce Task数据重组和传输。 负责将 Map 阶段的输出数据,根据 Key 进行分区、排序,并通过网络传输到正确的 Reduce Task 节点。这是 Map 和 Reduce 之间的数据桥梁。
Reduce 阶段Reduce Task汇总和计算。 接收 Shuffle 阶段传来的所有相同 Key 的数据,对其执行用户自定义的 reduce() 函数,进行聚合、统计等最终计算,并将结果写入 HDFS。

3. 简述 MapReduce 的执行流程,包括主要阶段及各阶段的核心作用。 ​

MapReduce 的完整执行流程主要由五个逻辑步骤和三个核心阶段构成:

  1. 输入分片 (Splitting): JobClient 将输入文件逻辑上切分成若干个 InputSplit,每个 Split 会分配给一个 Map Task 处理。
  2. Map 阶段: Map Task 读取 InputSplit,执行 map() 函数,生成中间结果 <K2, V2>。
  3. 排序与分区 (Sorting & Partitioning):
    • Map 输出的中间结果先在本地进行分区 (Partitioning),决定发送给哪个 Reduce Task。
    • 然后进行排序 (Sorting) 和合并 (Spilling) 到磁盘。
  4. Shuffle 阶段(核心): Reduce Task 从所有 Map Task 的输出中拉取 (Pull) 自己所需的数据(即 Shuffle),并在本地进行二次合并和排序。
  5. Reduce 阶段: Reduce Task 接收到所有属于自己的 Key 对应的 Value 集合后,执行 reduce() 函数进行最终聚合计算,并将结果写入 HDFS。

4. 什么是 MapReduce 的 Shuffle 阶段?它包含哪些主要过程? ​

Shuffle 阶段是 MapReduce 中最复杂、最耗费资源(尤其是网络 I/O)的阶段,它负责连接 Map 阶段的输出和 Reduce 阶段的输入。

核心作用: 确保所有具有相同 Key 的数据(无论它们在哪个 Map Task 中产生)都被路由到同一个 Reduce Task 进行聚合处理。

主要过程 (Map 端到 Reduce 端):

过程描述发生地点
Partition (分区)Map Task 根据 Key 的 Hash 值和 Reduce Task 的数量,决定将当前键值对发送给哪个 Reduce Task。Map Task 端
Spill (溢写)Map Task 内存缓冲区达到阈值后,将数据按 Key 排序后溢写到本地磁盘文件。Map Task 端
Merge (合并)Map Task 将所有溢写到磁盘的中间文件进行合并,生成一个或几个最终的输出文件。Map Task 端
Copy (复制/拉取)Reduce Task 启动后,主动通过 HTTP 请求从所有已完成的 Map Task 所在节点拉取属于自己分区的数据。Reduce Task 端
Sort & Merge (排序与合并)Reduce Task 在内存中对拉取到的数据进行归并排序和合并,将所有相同 Key 的 Value 集合在一起,作为 reduce() 函数的输入。Reduce Task 端

📝 Hive、HBase 与传统数据库对比 ​

1. 简述 Hive 与传统关系型数据库的区别。 ​

特性Hive传统关系型数据库 (RDBMS)
数据模型基于 HDFS,是数据仓库,本质上是文件,没有索引。基于关系模型,有严谨的表结构、索引。
查询语言HQL (Hive Query Language),非常接近标准 SQL,但底层转换为 MapReduce/Tez/Spark 任务执行。SQL (Structured Query Language),底层通过查询优化器和执行引擎直接操作数据。
事务支持弱支持或有限支持(仅在 Hive 3.x 以后支持 ACID)。强支持 ACID (原子性、一致性、隔离性、持久性) 事务。
数据处理批处理 (Batch Processing),适合离线分析、数据挖掘。延迟高。OLTP (联机事务处理),适合实时事务操作。延迟低。
数据存储通常存储在 HDFS 上。存储在本地文件系统,使用特定的存储引擎。

2. 简述 Hive 的作用及适用场景。 ​

  • 作用:
    • Hive 是一个基于 Hadoop 的数据仓库工具。
    • 它提供了一个 HQL(类似 SQL)的查询接口,允许用户通过熟悉的 SQL 语法来查询和管理存储在 HDFS 或其他 Hadoop 兼容文件系统上的大规模数据。
    • 它的本质是将 HQL 语句转换成底层的 MapReduce、Tez 或 Spark 等计算任务来执行。
  • 适用场景:
    • 离线数据分析: 例如每月、每周或每天的报表生成。
    • 大规模数据挖掘和 ETL: 复杂的数据清洗、转换和加载(Extract, Transform, Load)。
    • 数据仓库构建: 作为企业数据仓库的存储和查询层。

3. 说明 Hive 和 HBase 的主要区别及各自的应用场景。 ​

特性Hive (数据仓库)HBase (NoSQL 数据库)
数据模型结构化/半结构化;逻辑上的表结构,底层是 HDFS 文件。列式存储的 Key-Value 数据库;稀疏、多维度的 Map。
查询延迟高延迟(秒级到分钟级),为高吞吐量设计。低延迟(毫秒级),为快速随机读写设计。
应用场景离线批处理、数据分析、报表、ETL。实时随机读写、海量数据存储、历史订单查询、数据版本控制。
操作类型全表扫描、聚合查询。随机点查 (Get)、范围扫描 (Scan)。

4. 说明 HBase 适合处理哪类数据,并举一个典型应用场景。 ​

  • 适合处理的数据类型:
    • 海量稀疏数据: 数据量巨大 (PB 级别),但每行数据的列可能很少被完全填满。
    • 实时读写数据: 需要毫秒级响应的随机读取和写入操作。
    • 需要版本控制的数据: HBase 天生支持数据的多版本存储。
    • Key-Value 形式的数据: 数据可以自然地被抽象为 RowKey 和列族/列的值。
  • 典型应用场景:
    • 实时用户画像/标签系统: 存储数亿用户的实时标签数据,供推荐系统或广告系统进行毫秒级查询。
    • 电子商务交易历史: 存储数年的海量订单和交易记录,供用户进行历史查询。
    • 物联网 (IoT) 时间序列数据: 存储传感器每秒产生的海量数据点,并按时间戳作为 RowKey 进行快速查询。

5. 简述 HBase 的 RowKey 设计原则及其重要性。 ​

RowKey (行键) 是 HBase 中每行数据的唯一标识符,所有数据都是围绕 RowKey 存储和索引的,因此其设计至关重要。

  • RowKey 设计原则:
    1. 散列性 (Salting/Hash): 确保 RowKey 的设计能够将数据均匀分布到 HBase 集群的所有 RegionServer 上,避免热点问题。例如,如果使用时间戳作为前缀,则同一时间的数据会集中在一个 RegionServer 上。
    2. 长度适中: RowKey 是一个字节数组。过长会占用存储和网络带宽;过短则可能影响散列性和可读性。
    3. 唯一性: 确保每一行数据的 RowKey 是唯一的。
    4. 行键序 (Row-key Ordering): HBase 按照 RowKey 的字典序存储数据。如果需要进行范围扫描 (Scan),应将相关的、经常一起访问的数据设计成在字典序上相邻。
  • 重要性:
    • 决定数据分布: RowKey 直接决定数据在集群中的分布位置,是避免热点和保证集群负载均衡的关键。
    • 影响查询性能: HBase 的所有查询操作(Get 或 Scan)都必须通过 RowKey 或 RowKey 范围来实现。设计不当(如热点)将导致查询延迟极高。

五、 实操题 ​

📝 一、 集群部署基础配置的关键步骤(配置项) ​

写出 Hadoop 集群部署基础配置的关键步骤(填写配置项即可)

包括但不限于:

· JDK 配置

· SSH 免密登录

· core-site.xml

· hdfs-site.xml

· yarn-site.xml

· workers/slaves 文件(写主要内容即可)

Hadoop 完全分布式集群部署过程中,在配置文件中需要设置的关键配置项。

1. JDK 配置(所有节点) ​

在 $HADOOP_HOME/etc/hadoop/hadoop-env.sh 文件中配置:

bash
export JAVA_HOME=/path/to/your/jdk

2. SSH 免密登录(主节点到所有节点) ​

配置步骤(非配置项):

  • 生成密钥: ssh-keygen -t rsa -P ''
  • 复制公钥: ssh-copy-id user@hostname (对所有节点执行,包括自己)

3. core-site.xml 配置 ​

定义文件系统默认入口和临时目录:

配置项 (<name>)对应值 (<value>)作用
fs.defaultFShdfs://namenode_hostname:9000指定 NameNode 的 URI,作为 HDFS 的访问入口。
hadoop.tmp.dir/path/to/your/hadoop/tmpHadoop 共享的临时文件目录,必须在所有节点创建。

4. hdfs-site.xml 配置 ​

定义 HDFS 副本数和 NameNode/DataNode 数据位置:

配置项 (<name>)对应值 (<value>)作用
dfs.replication3设置文件块的默认副本数。
dfs.namenode.name.dirfile://${hadoop.tmp.dir}/dfs/nameNameNode 元数据(fsimage, edits log)存放目录。
dfs.datanode.data.dirfile://${hadoop.tmp.dir}/dfs/dataDataNode 实际数据块的存放目录。
dfs.namenode.http-addressnamenode_hostname:9870NameNode Web UI 访问地址。

5. yarn-site.xml 配置 ​

定义 YARN 资源管理器和节点管理器服务:

配置项 (<name>)对应值 (<value>)作用
yarn.resourcemanager.hostnameresourcemanager_hostname设置 ResourceManager 的主机名。
yarn.nodemanager.aux-servicesmapreduce_shuffle启用 NodeManager 上的 MapReduce Shuffle 服务。
yarn.nodemanager.aux-services.mapreduce.shuffle.classorg.apache.hadoop.mapred.ShuffleHandler指定 Shuffle 服务的实现类。

6. mapred-site.xml 配置 ​

定义 MapReduce 运行框架:

配置项 (<name>)对应值 (<value>)作用
mapreduce.framework.nameyarn指定 MapReduce 运行在 YARN 框架上。

7. workers/slaves 文件(内容) ​

该文件(位于 $HADOOP_HOME/etc/hadoop/)用于指定所有 DataNode 和 NodeManager 所在的机器主机名。

datanode_hostname_1
datanode_hostname_2
datanode_hostname_3
...

完成上述配置后,需要将配置好的文件同步到所有节点,然后才能进行 NameNode 格式化和集群启动。


💻 二、 伪分布式 Hadoop 集群实操关键命令 ​

假设你需要在一台Linux服务器上搭建一个伪分布式Hadoop集群(版本3.3.4),请写出以下步骤的关键命令或操作:

(1)解压安装包到指定目录(如/usr/local/hadoop);

(2)配置环境变量(HADOOP_HOME和PATH);

(3)修改core-site.xml配置文件(设置默认文件系统和临时目录);

(4)格式化NameNode;

(5)启动HDFS服务并验证是否成功(通过jps命令查看进程)。

假设目标安装目录为 /usr/local/hadoop,Hadoop 安装包名为 hadoop-3.3.4.tar.gz。

(1) 解压安装包到指定目录 ​

bash
sudo tar -zxvf hadoop-3.3.4.tar.gz -C /usr/local
sudo mv /usr/local/hadoop-3.3.4 /usr/local/hadoop

(2) 配置环境变量(HADOOP_HOME 和 PATH) ​

修改 /etc/profile 文件(或 $HOME/.bashrc):

bash
# HADOOP_HOME 
export HADOOP_HOME=/usr/local/hadoop
# 将 Hadoop 的 bin 和 sbin 目录加入 PATH
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

使配置生效:

bash
source /etc/profile

(3) 修改 core-site.xml 配置文件 ​

在 $HADOOP_HOME/etc/hadoop/core-site.xml 中添加:

xml
<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://localhost:9000</value>
  </property>
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/usr/local/hadoop/tmp</value>
  </property>
</configuration>

(4) 格式化 NameNode ​

注意: 仅在首次部署时执行!

bash
hdfs namenode -format

(5) 启动 HDFS 服务并验证是否成功 ​

  • 启动命令:

    bash
    start-dfs.sh
  • 验证进程:

    bash
    jps

    预期结果: 应该能看到 NameNode 和 DataNode 进程。如果 YARN 也启动了(start-yarn.sh),则还会看到 ResourceManager 和 NodeManager。


📑 三、 Hadoop 集群部署配置题(关键配置项) ​

Hadoop集群部署配置题

请完成以下配置文件的关键配置项填写:

core-site.xml配置:

hdfs-site.xml配置:

这里将完整展示在完全分布式或伪分布式中常用的配置项。

core-site.xml 配置: ​

xml
<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://namenode_hostname:9000</value> 
  </property>
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/opt/data/hadoop/tmp</value>
  </property>
</configuration>

hdfs-site.xml 配置: ​

xml
<configuration>
  <property>
    <name>dfs.replication</name>
    <value>3</value>
  </property>
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>file://${hadoop.tmp.dir}/dfs/name</value>
  </property>
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>file://${hadoop.tmp.dir}/dfs/data</value>
  </property>
  <property>
    <name>dfs.namenode.http-address</name>
    <value>namenode_hostname:9870</value>
  </property>
</configuration>

💻 HDFS 命令行操作题 ​

1. 假设您的 Hadoop 集群已经正常运行。请写出完成下列操作的 HDFS 命令行: ​

操作描述HDFS 命令行
在 HDFS 的 / 目录下创建一个名为 data 的文件夹。hdfs dfs -mkdir /data
将本地 Linux 系统下的 /home/local/log.txt 文件上传到 HDFS 的 /data 文件夹中。hdfs dfs -put /home/local/log.txt /data
查看 HDFS 的 /data 目录下有哪些文件。hdfs dfs -ls /data
将 HDFS 上的 /data/log.txt 文件内容下载到本地的 /tmp 目录下,并重命名为 download.txt。hdfs dfs -get /data/log.txt /tmp/download.txt

2. 请写出在 Hadoop 集群运维中,以下操作对应的命令: ​

操作描述HDFS 命令行或集群运维命令
(1) 关闭 HDFS 集群stop-dfs.sh
(2) 查看 HDFS 中根目录下的文件列表hdfs dfs -ls /
(3) 在 HDFS 中创建名为 student 的目录hdfs dfs -mkdir /student
(4) 查看 DataNode 节点的运行状态hdfs dfsadmin -report (该命令可查看集群所有节点状态,包括 DataNode)

3. 使用 HDFS Shell 命令完成以下任务: ​

任务描述HDFS 命令行
(1) 在 HDFS 根目录下创建名为 "exam" 的目录;hdfs dfs -mkdir /exam
(2) 将本地当前目录下的 "data.txt" 文件上传到 HDFS 的 "/exam" 目录;hdfs dfs -put data.txt /exam
(3) 查看 "/exam/data.txt" 文件的内容;hdfs dfs -cat /exam/data.txt
(4) 统计 "/exam" 目录下所有文件的总大小(以字节为单位);hdfs dfs -du -s /exam
(5) 删除 "/exam" 目录及其所有内容。hdfs dfs -rm -r /exam

4. 写出完成以下操作的 HDFS 命令: ​

操作描述HDFS 命令行
(1) 在 HDFS 上创建目录 /user/datahdfs dfs -mkdir -p /user/data
(2) 上传本地文件 test.txt 到 HDFS 的 /user/data 目录hdfs dfs -put test.txt /user/data
(3) 查看 HDFS 上 /user/data 目录下的所有文件hdfs dfs -ls /user/data
(4) 下载 HDFS 上的 /user/data/test.txt 到本地 /home 目录hdfs dfs -get /user/data/test.txt /home
(5) 删除 HDFS 上的 /user/data/test.txt 文件hdfs dfs -rm /user/data/test.txt

5. 写出常用 HDFS 命令 5 条并说明其功能 ​

序号HDFS 命令功能说明
1hdfs dfs -mkdir <path>创建目录: 在 HDFS 指定路径创建目录。使用 -p 参数可以递归创建父目录。
2hdfs dfs -put <local_path> <hdfs_path>上传文件: 将本地文件或目录上传到 HDFS 上的指定路径。copyFromLocal 亦可。
3hdfs dfs -ls <path>查看文件列表: 列出 HDFS 指定目录下的文件和目录。
4hdfs dfs -cat <hdfs_file>查看文件内容: 将 HDFS 文件内容输出到标准输出(屏幕)。
5hdfs dfs -rm -r <path>删除文件/目录: 删除 HDFS 上的文件。-r 参数用于删除非空目录。
6hdfs dfs -get <hdfs_path> <local_path>下载文件: 将 HDFS 上的文件或目录下载到本地文件系统。copyToLocal 亦可。

💻 HiveQL 语句操作题 ​

1. Hive 操作题 ​

序号操作描述HiveQL 语句
(1)创建一个名为 "student" 的表,包含字段 id(int)、name(string)、age(int),按 id 分区。CREATE TABLE student (name STRING, age INT) PARTITIONED BY (id INT);
(2)向 "student" 表中插入一条记录:(1, "Alice", 20)。INSERT INTO student PARTITION(id=1) VALUES ('Alice', 20); 或使用动态分区: INSERT INTO student PARTITION(id) VALUES (1, 'Alice', 20);
(3)查询年龄大于 18 岁的学生信息。SELECT * FROM student WHERE age > 18;
(4)计算学生平均年龄。SELECT AVG(age) FROM student;
(5)删除 "student" 表。DROP TABLE student;

2. Hive 操作题(针对表 student) ​

假设表结构:student(id INT, name STRING, score INT, class STRING)。

操作描述HiveQL 语句
查询所有学生的姓名(name)和分数(score),并按照分数降序排列。SELECT name, score FROM student ORDER BY score DESC;
查询每个班级(class)的平均分数,并将结果命名为 avg_score。SELECT class, AVG(score) AS avg_score FROM student GROUP BY class;
查询分数大于 80 分的学生总人数。SELECT COUNT(*) FROM student WHERE score > 80;
修改表 student 的名称为 student_info。ALTER TABLE student RENAME TO student_info;

3. Hive 操作题(针对员工表 employee) ​

给定员工表 employee(id int, name string, dept string, salary int)。

操作描述HiveQL 语句
创建表 employeeCREATE TABLE employee ( id INT, name STRING, dept STRING, salary INT );
向表中插入一条记录:(1, '张三', '技术部', 8000)INSERT INTO employee VALUES (1, '张三', '技术部', 8000);
查询每个部门的平均工资SELECT dept, AVG(salary) AS avg_salary FROM employee GROUP BY dept;
查询工资高于 5000 的员工姓名和部门SELECT name, dept FROM employee WHERE salary > 5000;

4. 给出 Hive 中建表 + 加载数据 + 简单查询的 SQL 示例 ​

假设有一个本地文件 /tmp/user_data.txt,内容如下:

1,Tom,Sales
2,Jerry,HR
3,Mike,Sales
步骤HiveQL 语句备注
创建表CREATE TABLE users ( uid INT, uname STRING, udept STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ','; ROW FORMAT DELIMITED 指定了数据的分隔符。
加载本地文件LOAD DATA LOCAL INPATH '/tmp/user_data.txt' INTO TABLE users; LOCAL 表示文件在 Hive 客户端所在的本地文件系统。若无 LOCAL,则表示文件在 HDFS 上。
GROUP BY 查询SELECT udept, COUNT(uid) AS dept_count FROM users GROUP BY udept HAVING COUNT(uid) > 1; 统计人数大于 1 的部门及其人数。

💻 HDFS Java API 编程实现 ​

1. 任务一:在 HDFS 上创建新文件并写入内容 ​

目标:创建 /user/test/hello.txt,并写入 "Hello Hadoop!"。

java
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;

public class HdfsFileWriter {

    public static void main(String[] args) {
        // HDFS 目标文件路径
        Path hdfsFilePath = new Path("/user/test/hello.txt");
        // 要写入的内容
        byte[] content = "Hello Hadoop!".getBytes();

        // 1. 获取 Configuration 实例,用于配置连接信息
        Configuration conf = new Configuration();
        // 设置 NameNode 地址,如果未在 core-site.xml 中配置,需要手动设置
        // conf.set("fs.defaultFS", "hdfs://namenode_hostname:9000"); 

        FileSystem fs = null;
        FSDataOutputStream outputStream = null;

        try {
            // 2. 获取 FileSystem 实例,连接 HDFS
            fs = FileSystem.get(conf);
            
            // 3. 检查父目录是否存在,不存在则创建
            if (!fs.exists(hdfsFilePath.getParent())) {
                fs.mkdirs(hdfsFilePath.getParent());
                System.out.println("Created parent directory: " + hdfsFilePath.getParent());
            }

            // 4. 创建文件,如果文件存在则覆盖 (false 表示不覆盖)
            // 默认副本数为3,块大小为128MB
            outputStream = fs.create(hdfsFilePath, true); 
            
            // 5. 写入内容
            outputStream.write(content);
            System.out.println("Successfully wrote 'Hello Hadoop!' to " + hdfsFilePath);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 6. 关闭文件流和 FileSystem 资源
            if (outputStream != null) {
                try {
                    outputStream.close(); // 关闭文件流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fs != null) {
                try {
                    fs.close(); // 关闭 FileSystem 连接
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

2. 任务二:将本地文件上传到 HDFS ​

目标:将本地 /home/user/data.txt 上传到 HDFS 的 /user/hadoop/input 目录下。

java
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.IOException;

public class FileUploader {

    public static void main(String[] args) {
        // 本地文件路径
        Path localFilePath = new Path("/home/user/data.txt"); 
        // HDFS 目标目录路径
        Path hdfsDestDir = new Path("/user/hadoop/input");
        
        // 1. 获取 Configuration 实例
        Configuration conf = new Configuration();
        // 设置 HDFS URI (如果不是默认配置)
        // conf.set("fs.defaultFS", "hdfs://namenode_hostname:9000");

        FileSystem fs = null;

        try {
            // 2. 获取 FileSystem 实例
            fs = FileSystem.get(conf);

            // 3. 检查目标目录是否存在,不存在则创建
            if (!fs.exists(hdfsDestDir)) {
                fs.mkdirs(hdfsDestDir);
                System.out.println("Created HDFS directory: " + hdfsDestDir);
            }

            // 4. 执行文件上传操作
            // 参数1: 源文件路径 (本地)
            // 参数2: 目标目录路径 (HDFS)
            // 参数3: 是否删除源文件 (false 表示不删除)
            fs.copyFromLocalFile(false, localFilePath, hdfsDestDir); 
            
            System.out.println("Successfully uploaded " + localFilePath + " to " + hdfsDestDir);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 5. 关闭 FileSystem 资源
            if (fs != null) {
                try {
                    fs.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

MapReduce编程题 ​

编写一个简单的 MapReduce WordCount 示例(可写伪代码或简介代码框架)

完整的WordCount程序代码

方案一:Java完整实现 ​

java
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;
import java.util.StringTokenizer;

public class WordCount {

    // ==================== Mapper类 ====================
    public static class TokenizerMapper 
            extends Mapper<Object, Text, Text, IntWritable> {
        
        // 定义输出的value值为1
        private final static IntWritable one = new IntWritable(1);
        // 定义输出的key
        private Text word = new Text();

        @Override
        public void map(Object key, Text value, Context context) 
                throws IOException, InterruptedException {
            
            // 将输入的一行文本转换为字符串
            String line = value.toString();
            
            // 使用空格分词
            StringTokenizer tokenizer = new StringTokenizer(line);
            
            // 遍历每个单词
            while (tokenizer.hasMoreTokens()) {
                // 设置单词
                word.set(tokenizer.nextToken());
                // 输出 <word, 1>
                context.write(word, one);
            }
        }
    }

    // ==================== Reducer类 ====================
    public static class IntSumReducer 
            extends Reducer<Text, IntWritable, Text, IntWritable> {
        
        // 定义输出的value
        private IntWritable result = new IntWritable();

        @Override
        public void reduce(Text key, Iterable<IntWritable> values, Context context) 
                throws IOException, InterruptedException {
            
            // 初始化计数器
            int sum = 0;
            
            // 遍历相同key的所有value值,进行累加
            for (IntWritable val : values) {
                sum += val.get();
            }
            
            // 设置结果
            result.set(sum);
            
            // 输出 <word, sum>
            context.write(key, result);
        }
    }

    // ==================== Driver主程序 ====================
    public static void main(String[] args) throws Exception {
        // 创建配置对象
        Configuration conf = new Configuration();
        
        // 创建Job对象
        Job job = Job.getInstance(conf, "word count");
        
        // 设置Jar包类
        job.setJarByClass(WordCount.class);
        
        // 设置Mapper类
        job.setMapperClass(TokenizerMapper.class);
        
        // 设置Combiner类(可选,用于本地聚合)
        job.setCombinerClass(IntSumReducer.class);
        
        // 设置Reducer类
        job.setReducerClass(IntSumReducer.class);
        
        // 设置输出key的类型
        job.setOutputKeyClass(Text.class);
        
        // 设置输出value的类型
        job.setOutputValueClass(IntWritable.class);
        
        // 设置输入路径
        FileInputFormat.addInputPath(job, new Path(args[0]));
        
        // 设置输出路径
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        
        // 提交作业并等待完成
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

方案二:伪代码框架(简化版) ​

// ==================== Mapper伪代码 ====================
class Mapper:
    function map(key, value):
        // value是输入的一行文本
        // 将文本按空格分词
        words = split(value, " ")
        
        // 遍历每个单词
        for each word in words:
            // 输出 <word, 1>
            emit(word, 1)


// ==================== Reducer伪代码 ====================
class Reducer:
    function reduce(key, values):
        // key是单词
        // values是该单词对应的所有value值列表 [1, 1, 1, ...]
        
        // 初始化计数器
        sum = 0
        
        // 遍历values列表,累加求和
        for each value in values:
            sum = sum + value
        
        // 输出 <word, sum>
        emit(key, sum)


// ==================== 执行流程 ====================
输入数据: "hello world hello hadoop"

Mapper输出:
<hello, 1>
<world, 1>
<hello, 1>
<hadoop, 1>

Shuffle阶段(框架自动完成):
<hello, [1, 1]>
<world, [1]>
<hadoop, [1]>

Reducer输出:
<hello, 2>
<world, 1>
<hadoop, 1>

方案三:Python版本(使用Hadoop Streaming) ​

python
# ==================== mapper.py ====================
#!/usr/bin/env python3
import sys

# 从标准输入读取数据
for line in sys.stdin:
    # 移除首尾空白字符
    line = line.strip()
    
    # 按空格分词
    words = line.split()
    
    # 输出每个单词和计数1
    for word in words:
        # 输出格式: word\t1
        print(f"{word}\t1")


# ==================== reducer.py ====================
#!/usr/bin/env python3
import sys

current_word = None
current_count = 0

# 从标准输入读取Mapper的输出
for line in sys.stdin:
    # 移除首尾空白字符
    line = line.strip()
    
    # 解析输入:word\t1
    word, count = line.split('\t')
    count = int(count)
    
    # Hadoop保证相同的key会连续出现
    if current_word == word:
        # 累加计数
        current_count += count
    else:
        # 输出前一个单词的统计结果
        if current_word:
            print(f"{current_word}\t{current_count}")
        
        # 开始统计新单词
        current_word = word
        current_count = count

# 输出最后一个单词的统计结果
if current_word:
    print(f"{current_word}\t{current_count}")

核心知识点解析 ​

1. Mapper阶段 ​

  • 输入: <LongWritable, Text> - 行偏移量和文本内容
  • 处理: 将文本按分隔符分词
  • 输出: <Text, IntWritable> - 每个单词输出一个<word, 1>键值对

2. Shuffle阶段(框架自动完成) ​

  • 对Mapper输出按key进行排序
  • 将相同key的数据分组
  • 分发到对应的Reducer

3. Reducer阶段 ​

  • 输入: <Text, Iterable<IntWritable>> - 单词和该单词所有计数值的迭代器
  • 处理: 遍历values列表,累加求和
  • 输出: <Text, IntWritable> - 单词和总计数

4. 执行流程示例 ​

输入文件内容:
hello world
hello hadoop
hadoop mapreduce

Mapper输出:
<hello, 1>
<world, 1>
<hello, 1>
<hadoop, 1>
<hadoop, 1>
<mapreduce, 1>

Shuffle后分组:
<hadoop, [1, 1]>
<hello, [1, 1]>
<mapreduce, [1]>
<world, [1]>

Reducer输出:
hadoop    2
hello     2
mapreduce 1
world     1

六、多选题 ​

  1. Hadoop集群的角色包括()

全部正确

  • A. NameNode ✓ - HDFS的主节点,管理文件系统命名空间和元数据
  • B. DataNode ✓ - HDFS的从节点,负责实际数据存储
  • C. ResourceManager ✓ - YARN的资源管理器,负责集群资源分配
  • D. NodeManager ✓ - YARN的节点管理器,管理单个节点资源
  • E. SecondaryNameNode ✓ - 辅助NameNode,定期合并fsimage和edits日志

  1. 以下属于HDFS特点的有()

正确答案:A、B、D、E

  • A. 高容错性 ✓ - 通过数据副本机制实现容错
  • B. 适合大文件存储 ✓ - 设计目标就是存储大文件(GB到TB级别)
  • C. 支持数据的随机读写 ✗ - HDFS不支持随机写,只支持追加写和顺序读
  • D. 数据自动备份 ✓ - 默认3个副本自动备份
  • E. 流式数据访问 ✓ - 采用"一次写入,多次读取"的流式访问模式

  1. MapReduce程序的核心组件包括()

全部正确

  • A. Mapper ✓ - 映射阶段,处理输入数据
  • B. Reducer ✓ - 归约阶段,汇总处理结果
  • C. Driver ✓ - 驱动程序,配置和提交作业
  • D. Combiner ✓ - 本地合并器,减少数据传输量(可选组件)
  • E. Partitioner ✓ - 分区器,决定Map输出发送到哪个Reducer

  1. Hadoop集群运维中常用的监控指标有()

全部正确

  • A. HDFS磁盘使用率 ✓ - 监控存储空间使用情况
  • B. DataNode存活状态 ✓ - 监控节点健康状况
  • C. NameNode堆内存使用情况 ✓ - 防止NameNode内存溢出
  • D. MapReduce任务执行时间 ✓ - 监控任务性能
  • E. 网络带宽占用 ✓ - 监控数据传输效率

  1. 在IDEA中开发Hadoop程序需要添加的依赖包括()

正确答案:A、B、C、E

  • A. hadoop-common ✓ - Hadoop核心公共库
  • B. hadoop-hdfs ✓ - HDFS客户端API
  • C. hadoop-mapreduce-client-core ✓ - MapReduce核心库
  • D. mysql-connector-java ✗ - MySQL连接器,不是Hadoop必需依赖
  • E. hadoop-client ✓ - Hadoop客户端综合依赖包(包含common、hdfs、mapreduce等)

基于 Vite 强力驱动 | 纯静态轻量托管