一、
hadoop 集群,负责资源的管理和调度组件
HDFS 操作:使用 hadoop fs 命令查看文件(查看文件名称、文件的大小等)
Hive 中数据的存储格式,了解每一种存储格式的适合存储什么样的类型的数据
Linux 中权限的设置,如:使用命令给目录或文件赋予可读可写的权限
SSH 生成免密登录使用的密钥
MapReduce 过程中,map 阶段、reducer 阶段,采用技术 shuffle 的作用是什么
HDFS 包括 namenode、datanode 各自负责什么
在Hive中,如何使用HQL语句进行分区(按省和市)
YARN资源管理器和HDFSWEBUI分别对应的端口号以及主要有的功能是什么
HDFS编程方式上传文件到FS,对文件进行操作的相应API(特别核心的API)的名称
知道如何去查看NameNode和DataNode的状态
HIVE中,掌握如何将本地文件上传到HDFS服务器上,也掌握如何从HDFS服务器上将文件下载到本地
Map阶段的输出就是Reducer阶段的输入,了解Reducer阶段输入数据类型是什么
HDFS具有很高的可靠性的原因因为采用了副本策略,配置策略(每一台数据节点应该部署多少个副本才是合理的)
在HIVE中区分内部表和外部表,删除外部表和删除内部表,元数据和实际数据会不同的处理策略。
二、
1、HIVE分区表的设计
1)、了解Hive分区表的优缺点
2)、会编写HiveQL(HQL)语句,加载本地(HDFS)数据到某一个表(分区表)中(课堂派上的作业)
3)、会向表中插入数据
1.优点:提升查询性能、高效的数据管理、加速数据加载。
缺点:会生成大量小文件、有查询风险
2.
CREATE DATABASE IF NOT EXISTS db_name; CREATE TABLE IF NOT EXISTS tb_name( ... );3.
LOAD DATA [LOCAL] INPATH '路径' [OVERWRITE] INTO TABLE 表名 PARTITION (分区列 = '值'); LOAD DATA INPATH "hdfs/data/logs.txt" INTO TABLE logs PARTITION(dt="2026-06-26");2、HDFS读写流程(写入数据的流程和读取数据的流程),读写的过程其实是和namenode以及datanode进行交互的一个过程。涉及到数据块的传输过程(pipeline的机制),如何知道写入数据是成功的?
写入:Client 向 NameNode 请求,NameNode 返回 DataNode 列表;Client 将数据分块通过 Pipeline 依次传给多个DataNode;每个DataNode收到后沿管道反向发送 ACK,Client 收到全部 ACK 即成功。
读取:Client 向 NameNode 请求,NameNode返回各块所在 DataNode 列表;Client 从最近的 DataNode 读取各块,若失败则换其他副本。
3、MapReduce 原理和 Shuffle 机制。
1)、给定输入数据‘student teacher student may can can may’,完成单词统计,Map 阶段的完整输出是什么?
2)、会描述 Shuffle 机制对 Map 阶段的处理过程
3)、掌握 Reduce 阶段的输出结果。
1.
<student,1> <teacher,1> <student,1> <may,1> <can,1> <can,1> <may,1>2.分区-排序-合并-归并
3.
student 2 teacher 1 may 2 can 24、Hadoop 集群规划和部署:给定一个集群的场景(部署一个微型的 Hadoop 集群,1 台 master,2 台 slave)
1)、掌握如何将此集群配置起来(了解需要哪些配置文件?重要配置项需要掌握)
2)、运行起来,掌握从格式化到正常启动的整个过程的操作(掌握关键的操作命令)
3)、集群启动完成后,如何验证集群工作是正常的。
1.
| 文件 | 关键配置 |
|---|---|
core-site.xml | fs.defaultFS = hdfs://master:9000 |
hdfs-site.xml | dfs.replication = 2 |
yarn-site.xml | yarn.resourcemanager.hostname = master |
workers | 写入2台slave的主机名或IP |
hadoop-env.sh | 设置JAVA_HOME |
2.
hdfs namenode -format # 仅首次启动前执行 start-dfs.sh # 启动HDFS(NameNode + DataNode) start-yarn.sh # 启动YARN(ResourceManager + NodeManager)3.
jps:Master看NameNode、ResourceManager;Slave看DataNode、NodeManager浏览器:
http://master:9870(HDFS界面)和http://master:8088(YARN界面)命令:
hdfs dfsadmin -report查看DataNode是否存活
三、
例1:Java程序调用HDFSAPI上传文件(8分)
请编写一个Java程序,实现将本地文件系统从HDFS下载到本地文件系统的功能。要求:
(1)导入必要的Hadoop包(罗列至少3个主要的包名称)并写出获取FileSystem实例的程序代码。(2分)
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.FSDatalInputStream; import java.io.*; Configuration conf = new Configuration(); conf.set("fs.defaultFS","hdfs://master:9000"); FileSystem fs = FileSystem.get(conf);(2)指定HDFS源文件路径和本地目标路径。
Path hdfspath = new Path("/user/data/file.txt"); //HDFS源文件路径 Path localPath = new Path("/home/user/file.txt"); //本地目标路径(3)实现文件下载的核心代码,并关闭资源。
fs.copyToLocalFile(hdfspath, localPath); fs.close();(4)添加异常处理机制
try{ Configuration conf = new Configuration(); text[[74, 768, 92, 780]] fs.copyToLocalFile(hdfspath, localPath); fs.close(); System.out.println("下载成功!"); catch(Exception ex){ ex.printStackTrace(); System.out.println("下载文件错误!");import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import java.io.*; public class HDFSDownload { public static void main(String[] args) { try { //(1)获取FileSystem实例 Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://master:9000"); FileSystem fs = FileSystem.get(conf); //(2)指定源路径和目标路径 Path hdfsPath = new Path("/user/data/file.txt"); // HDFS源文件 Path localPath = new Path("/home/user/file.txt"); // 本地目标 //(3)下载文件 + 关闭资源 fs.copyToLocalFile(hdfsPath, localPath); fs.close(); System.out.println("下载成功!"); } catch (Exception ex) { //(4)异常处理 ex.printStackTrace(); System.out.println("下载文件错误!"); } } }例2 HiveQL(HQL)查询操作:现有Hive表,结构如下,请编写HiveQL语句完成如下操作:
| 字段名 | 类型 | 说明 |
|---|---|---|
| stu_no | INT | 学号 |
| stu_name | STRING | 学生姓名 |
| stu_dept | STRING | 系名称 |
| stu_age | INT | 学生年龄 |
| stu_date | STRING | 学生注册日期 |
(1) 创建该内部表student,指定字段分隔符为逗号,存储的格式为TEXTFILE。
(2) 向表中插入三条记录(2321001,'张三','信息工程系',19,'2022-09-15')和'(2321002,'李四','数科系',20,'2023-09-16')和'(2321003,'王五','人工智能学院',18,'2023-09-17')
(3) 查询2023年及以后注册的学生信息,按照学生年龄从大到小排序。
(4) 统计每个系(学院)的学生人数和平均年龄。
1.
CREATE TABLE student ( stu_no INT, stu_name STRING, stu_dept STRING, stu_age INT, stu_date STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE;2.
INSERT INTO TABLE student VALUES (2321001, '张三', '信息工程系', 19, '2022-09-15'), (2321002, '李四', '数科系', 20, '2023-09-16'), (2321003, '王五', '人工智能学院', 18, '2023-09-17');3.
SELECT * FROM student WHERE stu_date >= '2023-01-01' ORDER BY stu_age DESC;4.
SELECT stu_dept, COUNT(*) AS student_count, ROUND(AVG(stu_age), 2) AS avg_age FROM student GROUP BY stu_dept;例3 Shell脚本批量操作HDFS
请编写一个Shell脚本,实现对HDFS日志文件的批处理。假设Hadoop环境变量已配置好:
(1) 在HDFS上创建一个目录/ user/bigdata/zeng (若不存在则创建)
(2) 将HDFS上/ user/bigdata/zeng 目录下所有以txt结尾的文件复制到/ user/bigdata/wang 目录。
(3) 统计/ user/bigdata/zeng 目录下文件的总数量,并输出结果。
#!/bin/bash # (1) 创建目录(不存在则创建) hdfs dfs -mkdir -p /user/bigdata/zeng # (2) 复制所有txt结尾的文件到wang目录(先确保目标目录存在) hdfs dfs -mkdir -p /user/bigdata/wang hdfs dfs -cp /user/bigdata/zeng/*.txt /user/bigdata/wang/ # (3) 统计zeng目录下文件总数并输出 file_count=$(hdfs dfs -ls /user/bigdata/zeng | grep "^-" | wc -l) echo "文件总数量: $file_count"例4 HDFS读写流程:请描述HDFS客户端写入一个400M的文件的完整流程,包括:
(1) 客户端与 NameNode 的交互过程
(2) 数据块(Block)的传输过程和流水线复制(Pipeline)机制
(3) 写入完成后,NameNode 如何确认写入成功?
(1) 客户端与NameNode交互
客户端调用
create(),请求创建文件。NameNode校验:文件是否存在?有无写入权限?
校验通过 → NameNode在元数据中记录文件创建信息(暂不分配块位置)→ 返回
FSDataOutputStream。
(2) Pipeline流水线传输
客户端请求NameNode为第1个块分配DataNode列表(机架感知策略返回3个DN)。
客户端将Block1写入DN1→ DN1推送给DN2→ DN2推送给DN3(形成Pipeline)。
数据以Packet(数据包)为单位传输,每包沿Pipeline反向返回ACK确认。
Block1完成后,重复上述步骤依次传输Block2、Block3、Block4。
(3) NameNode确认写入成功
块级确认:每个块收到Pipeline反向ACK → 客户端认为该块完成。
文件级确认:所有块传完 → 客户端调用
close()。最终确认:NameNode收到关闭请求 → 将所有块信息(块ID、位置)持久化到FsImage和EditLog→ 向客户端返回“写入成功”。
一句话速记
客户端请求NN → NN分配DN列表 → Pipeline流水线传块(DN1→DN2→DN3)+ ACK逐级确认 → 所有块完成 → 客户端close() → NN元数据落盘 → 返回成功
客户端 → NameNode(申请创建) ← FSDataOutputStream 客户端 → DN1 → DN2 → DN3 (Pipeline传输,每包反向ACK) ↓ (Block1完成) 客户端 → DN1 → DN2 → DN3 (Block2、3、4重复) ↓ 客户端 → close() → NameNode → 元数据落盘(FsImage+EditLog) → 返回成功