实操练习手册
24 道题按章节递进:从集群命令到 MapReduce、Hive、HBase、Spark。先自己做,再点开答案。
怎么练① 打开你的集群;② 从第 1 题开始逐条敲;③ 卡住先看"解题思路",再点参考答案;④ 命令类题目重点记"为什么要这么写"。
HDFS 命令(第4章)
01
在 HDFS 上创建 /data/input 目录,并把本地文件 w.txt 上传进去。
提示:hdfs dfs -mkdir -p / -put
解题思路目录要递归创建用 -p;put 是本地→HDFS。
查看参考答案
hdfs dfs -mkdir -p /data/input
hdfs dfs -put w.txt /data/input/
hdfs dfs -ls /data/input02
查看 /data/input/w.txt 的文件大小与块信息,并检查是否有损坏副本。
提示:-du -h 与 fsck
解题思路fsck 是 HDFS 的文件系统检查工具,-files -blocks 能看到块分布。
查看参考答案
hdfs dfs -du -h /data/input/w.txt
hdfs fsck /data/input/w.txt -files -blocks -locations03
把 HDFS 上该文件下载到本地 /home/hadoop/,并递归删除 HDFS 目录 /data/input。
提示:-get / -rm -r
解题思路get 等价 copyToLocal;删除目录必须加 -r。
查看参考答案
hdfs dfs -get /data/input/w.txt /home/hadoop/
hdfs dfs -rm -r /data/input04
把某文件的副本数改为 2,并说明为什么不能设成超过 DataNode 数量。
提示:-setrep
解题思路副本数大于节点数时,HDFS 只能复制到现有节点数量上限。
查看参考答案
hdfs dfs -setrep -w 2 /data/w.txt
# 只有 3 个 DataNode 时设 5 是无效的,实际副本数最多为 305
设置某目录 3 小时后进回收站、7 天后自动清空,并立即清空回收站。
提示:fs.trash.interval / -expunge
解题思路回收站是"删除文件暂存",可防止误删。
查看参考答案
# core-site.xml
<property><name>fs.trash.interval</name><value>180</value></property>
<property><name>fs.trash.checkpoint.interval</name><value>10080</value></property>
# 清空
hdfs dfs -expungeMapReduce(第6章)
06
写出 WordCount 的 Mapper 核心代码(拆分单词并输出 (word,1))。
提示:Mapper<LongWritable,Text,Text,IntWritable>
解题思路每行 value.toString().split 后逐词 context.write。
查看参考答案
public class WcMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
private Text k = new Text();
private IntWritable v = new IntWritable(1);
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
for (String w : value.toString().split("\\s+")) {
if (w.isEmpty()) continue;
k.set(w);
context.write(k, v);
}
}
}07
为什么要给 WordCount 加 Combiner?加它有什么前提条件?
提示:减少 Shuffle 数据量
解题思路Combiner 在 Map 端先聚合;要求运算满足结合律与交换律。
查看参考答案
# 加 Combiner
job.setCombinerClass(WcReducer.class);
# 前提:运算必须满足结合律/交换律
# 求和可以;求平均值不行(先各自平均再平均 ≠ 整体平均)08
把 Reduce 个数设置为 4,并说明输出目录会变成什么。
提示:job.setNumReduceTasks
解题思路一个 Reduce 对应一个输出文件。
查看参考答案
job.setNumReduceTasks(4);
# 输出目录会出现 part-r-00000 ~ part-r-00003 四个文件09
作业报 "Output directory already exists",如何解决?
提示:删除输出目录
解题思路MapReduce 不允许覆盖已存在的输出目录。
查看参考答案
hdfs dfs -rm -r /wc/output
hadoop jar wc.jar com.demo.WcDriver /wc/input /wc/outputHive(第7章)
10
建一张学生表(学号/姓名/性别),逗号分隔、ORC 存储,并查看结构。
提示:ROW FORMAT DELIMITED FIELDS TERMINATED BY
解题思路建表三段式:字段 → 分隔符 → 存储格式。
查看参考答案
CREATE TABLE IF NOT EXISTS student_info(
stu_id STRING COMMENT '学号',
stu_name STRING COMMENT '姓名',
sex STRING COMMENT '性别'
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS ORC;
DESC FORMATTED student_info;11
统计每门课程的平均分(保留两位小数),只显示平均分高于 60 的课程。
提示:GROUP BY + HAVING
解题思路AVG 聚合后用 HAVING 过滤分组结果。
查看参考答案
SELECT course_id,
count(*) AS cnt,
round(avg(score), 2) AS avg_score
FROM score_info
GROUP BY course_id
HAVING avg(score) > 60
ORDER BY avg_score DESC;12
用窗口函数取出每门课程成绩前 3 名的学生。
提示:rank() OVER (PARTITION BY … ORDER BY …)
解题思路窗口函数放子查询,外层筛 rk<=3。
查看参考答案
SELECT * FROM (
SELECT course_id, stu_id, score,
rank() OVER (PARTITION BY course_id ORDER BY score DESC) AS rk
FROM score_info
) t WHERE rk <= 3 ORDER BY course_id, rk;13
写一个 UDF:把输入字符串转小写并拼接后缀 "_hive",并说明注册方式。
提示:继承 UDF,写 evaluate
解题思路UDF 一行进一行出;注册用临时函数。
查看参考答案
public class MyLowerUDF extends UDF {
public Text evaluate(Text input) {
if (input == null) return null;
return new Text(input.toString().toLowerCase() + "_hive");
}
}
-- 注册
ADD JAR /user/hadoop/jars/myudf.jar;
CREATE TEMPORARY FUNCTION my_lower AS 'com.demo.MyLowerUDF';
SELECT my_lower(stu_name) FROM student_info LIMIT 3;14
用 Sqoop 把 MySQL 的 weather 表导入 Hive 的 ods.weather_ods。
提示:--hive-import --hive-database --hive-table
解题思路字段分隔符要和 Hive 表一致;小表用 -m 1。
查看参考答案
sqoop import \
--connect jdbc:mysql://hadoop1:3306/nev --username root --password 123456 \
--table weather --hive-import --hive-database ods --hive-table weather_ods \
--fields-terminated-by '\t' -m 1HBase(第8章)
15
在 HBase 中建表 student(列族 info、score),插入一条记录并查询。
提示:create / put / get
解题思路put 的格式是 表 行键 列族:列 值。
查看参考答案
create 'student', 'info', 'score'
put 'student', '1001', 'info:name', '张三'
put 'student', '1001', 'score:math', '90'
get 'student', '100116
设计一个不会产生热点的 RowKey,用于存放 10 亿条订单记录。
提示:加盐前缀 / 反转时间戳
解题思路单调递增的 RowKey 会让写请求集中到一台 RegionServer。
查看参考答案
# 方案一:hash 加盐(牺牲部分范围扫描能力)
# RowKey = hash(orderId) % 10 + ":" + orderId
#
# 方案二:反转时间戳(便于"最新 N 条"查询)
# RowKey = (Long.MAX_VALUE - ts) + ":" + orderId
#
# 方案三:预分区 + 业务维度前缀(城市/地区)17
用 Phoenix 建表并做一次条件查询、一次建二级索引。
提示:sqlline.py / CREATE TABLE / CREATE INDEX
解题思路Phoenix 把 SQL 翻译成 HBase 操作。
查看参考答案
!connect jdbc:phoenix:hadoop1:2181
CREATE TABLE student (id VARCHAR PRIMARY KEY, info.name VARCHAR, score.math INTEGER);
UPSERT INTO student VALUES ('1001','张三',90);
SELECT * FROM student WHERE info.name = '张三';
CREATE INDEX idx_name ON student (info.name);Spark(第9章)
18
用 Spark 的 Java API 写 WordCount。
提示:flatMap → mapToPair → reduceByKey
解题思路四个算子一条链,最后用行动算子落地。
查看参考答案
JavaRDD<String> lines = sc.textFile("hdfs://hadoop1:9000/wc/input/w.txt");
JavaRDD<String> words = lines.flatMap(l -> Arrays.asList(l.split("\\s+")).iterator());
JavaPairRDD<String, Integer> counts =
words.mapToPair(w -> new Tuple2<>(w, 1)).reduceByKey((a, b) -> a + b);
counts.saveAsTextFile("hdfs://hadoop1:9000/wc/out-spark");19
说明 reduceByKey 与 groupByKey 的区别,并给出选择建议。
提示:是否在 Map 端先聚合
解题思路reduceByKey 会做 map 端 combine,数据量小。
查看参考答案
# reduceByKey:按 key 聚合,Shuffle 前先在 Map 端 combine,网络传输少
# groupByKey:按 key 分组,把同 key 的全部 value 拉到一个节点,数据量大、易 OOM
# 结论:能用 reduceByKey 就别用 groupByKey20
用 spark-submit 把作业提交到 YARN,并说明几个关键参数。
提示:--master yarn --deploy-mode --executor-memory
解题思路提交参数直接决定资源占用与稳定性。
查看参考答案
spark-submit \
--master yarn --deploy-mode cluster \
--executor-memory 2g --executor-cores 2 --num-executors 4 \
--class com.demo.Wc \
wc.jar hdfs:///input hdfs:///output综合(第10章)
21
写 SQL:统计某城市每月平均最高温,并按月份排序。
提示:group by m + avg
解题思路先 cast 成数值再聚合。
查看参考答案
SELECT m, round(avg(high_num), 1) AS avg_high
FROM dwd.weather_clean
WHERE city = '北京' AND y = '2025'
GROUP BY m ORDER BY m;22
写 SQL:统计各城市晴天天数(Top 5)。
提示:LIKE 过滤 + 分组 + 排序 + limit
解题思路weather 字段含"晴"即算晴天。
查看参考答案
SELECT city, count(*) AS sunny_days
FROM dwd.weather_clean
WHERE weather LIKE '%晴%'
GROUP BY city ORDER BY sunny_days DESC LIMIT 5;23
对同一份数据,说明"先去重后分区"与"先分区再去重"的差别。
提示:跨分区重复
解题思路先去重可避免跨分区漏重。
查看参考答案
# 先去重后分区:全局唯一,推荐
# 先分区再去重:每个分区内单独去重,同一城市同一天若落在两个分区就漏重了
# 做法:先 row_number() 全局去重,再 INSERT OVERWRITE ... PARTITION 落表24
给出一个 10 分钟能做完的集群健康检查清单。
提示:jps / 9870 / 8088 / fsck
解题思路从进程、Web、文件系统三层确认。
查看参考答案
1) jps:NameNode/DataNode/RM/NM 齐全
2) hdfs dfsadmin -report:Live datanodes = 3
3) http://hadoop1:9870:Overview 无 Under-replicated blocks
4) http://hadoop1:8088:Active Nodes 正常
5) hdfs fsck / -files -blocks:无 CORRUPT block
6) 提一个 WordCount 小作业验证端到端可用