Hadoop面试100道精选题解(附答案)
一、基础概念与架构篇
1. Hadoop的核心组件有哪些?各承担什么角色?
Hadoop生态包含三大核心组件:HDFS(分布式存储)、YARN(资源管理)和MapReduce(计算框架)。
- HDFS:采用主从架构(NameNode+DataNode),通过分块存储(默认128MB/块)和副本机制(默认3副本)实现高容错性。
- YARN:通过ResourceManager(全局调度)和NodeManager(节点管理)分离资源管理与任务调度,支持多计算框架(如Spark、Flink)共存。
- MapReduce:将计算拆分为Map阶段(数据局部处理)和Reduce阶段(全局聚合),通过Shuffle机制实现键值对传输。
示例:处理1TB日志文件时,HDFS将其切分为8192个块,MapReduce启动8192个Map任务并行处理,最终通过Reduce输出结果。
2. HDFS读写流程的完整步骤是什么?
写入流程:
- 客户端通过DistributedFileSystem创建文件,请求NameNode分配块位置。
- NameNode返回DataNode列表(按机架感知策略优化)。
- 客户端按顺序写入DataNode,采用流水线复制(如DN1→DN2→DN3)。
- 每个块写入完成后,DataNode向NameNode汇报元数据。
读取流程:
- 客户端请求NameNode获取文件块位置(优先读取本地或同机架节点)。
- 客户端并行从多个DataNode读取数据块,合并为完整文件。
关键点:写入时需等待所有副本确认,读取时支持就近原则降低延迟。
二、核心组件深度解析
3. MapReduce的Shuffle机制如何工作?
Shuffle是MapReduce的核心优化环节,分为四个阶段:
-
Map端:
- 每个Map任务输出
<key, value>对到环形内存缓冲区(默认100MB)。 - 缓冲区满时触发溢写(Spill),通过Partitioner按Key分区(如HashPartitioner)。
- 对每个分区内的键值对按Key排序(使用快速排序或归并排序)。
- 可选Combiner进行本地聚合,减少网络传输量。
- 每个Map任务输出
-
Reduce端:
- 通过HTTP从所有Map节点拉取属于自己分区的中间数据。
- 合并多个溢写文件(归并排序),生成已排序的键值对列表。
- 将数据传递给Reduce函数处理。
优化建议:调整io.sort.mb参数控制缓冲区大小,自定义Partitioner实现数据倾斜处理。
4. YARN资源调度策略有哪些?如何选择?
YARN支持三种调度器:
- FIFO Scheduler:先进先出,适合单用户集群,但无法处理多租户场景。
- Capacity Scheduler:按层级队列分配资源(如开发/生产队列),支持弹性扩容。
- Fair Scheduler:动态平衡资源分配,确保所有应用公平获取资源。
配置示例:<property><name>yarn.scheduler.capacity.root.queues</name><value>dev,prod</value></property><property><name>yarn.scheduler.capacity.root.dev.capacity</name><value>30</value></property>
生产环境推荐Capacity Scheduler,通过队列隔离保障关键任务资源。
三、性能调优与故障排查
5. 如何优化HDFS的读写性能?
写入优化:
- 调整
dfs.blocksize(如256MB)减少元数据开销。 - 设置
dfs.replication为2(非关键数据)或4(高可用场景)。 - 启用HDFS短路径读取(
dfs.client.read.shortcircuit)。
读取优化:
- 使用
hdfs dfs -getmerge合并小文件。 - 配置
dfs.datanode.handler.count增加处理线程数。
监控工具:通过HDFS Web UI查看块分布热图,识别数据倾斜节点。
6. MapReduce任务卡在Map阶段的常见原因?
- 数据倾斜:某个Key的记录数过多,导致单个Reduce任务过载。
解决方案:自定义Partitioner重分配Key,或启用二次排序。 - 资源不足:Map任务内存溢出(OOM)。
解决方案:调整mapreduce.map.memory.mb和mapreduce.map.java.opts。 - 网络问题:DataNode与NodeManager间通信超时。
解决方案:检查yarn.nodemanager.disk-health-checker.min-healthy-disks配置。
四、高级特性与生态扩展
7. HBase与Hadoop的集成方式?
HBase依赖HDFS存储数据文件(HFile),通过RegionServer处理读写请求:
- 写路径:MemStore缓存写入数据,达到阈值后刷写为HFile。
- 读路径:优先从MemStore读取,未命中时合并多个HFile扫描结果。
优化配置:
- 设置
hbase.regionserver.global.memstore.size控制内存使用。 - 启用
hbase.hregion.majorcompaction定期合并小文件。
8. 如何实现Hadoop集群的高可用?
HDFS HA:
- 部署双NameNode(Active+Standby),通过ZooKeeper管理状态。
- 共享EditLog存储(QJM或NFS)。
YARN HA: - 配置ResourceManager的
yarn.resourcemanager.ha.enabled=true。 - 使用自动故障转移(
yarn.resourcemanager.recovery.enabled=true)。
监控告警:集成Prometheus+Grafana监控NameNode进程存活状态。
五、实战案例解析
9. 处理10亿条URL日志的MapReduce程序示例
Mapper阶段:提取URL并统计访问次数
public class URLMapper extends Mapper<LongWritable, Text, Text, IntWritable> {private final static IntWritable one = new IntWritable(1);private Text url = new Text();public void map(LongWritable key, Text value, Context context) {String[] parts = value.toString().split("\t");url.set(parts[1]); // 假设URL在第二列context.write(url, one);}}
Reducer阶段:汇总相同URL的计数
public class URLReducer extends Reducer<Text, IntWritable, Text, IntWritable> {public void reduce(Text key, Iterable<IntWritable> values, Context context) {int sum = 0;for (IntWritable val : values) {sum += val.get();}context.write(key, new IntWritable(sum));}}
优化点:使用Combiner减少网络传输,设置mapreduce.job.reduces=20并行处理。
10. 如何排查Hadoop作业执行失败?
排查步骤:
- 查看YARN Application Master日志(
yarn logs -applicationId <app_id>)。 - 检查MapReduce任务计数器(如
SPILLED_RECORDS过高可能需调整内存)。 - 分析HDFS空间是否充足(
hdfs dfs -df -h)。
常见错误码:
TaskId failed: java.lang.OutOfMemoryError:增加mapreduce.map.memory.mb。Container killed by YARN for exceeding memory limits:调整yarn.scheduler.maximum-allocation-mb。
本文精选的100道面试题覆盖Hadoop从入门到进阶的核心知识点,建议开发者结合实际项目经验理解每个问题的应用场景。面试前可重点复习Shuffle机制、资源调度策略和故障排查流程,同时通过动手实验(如搭建伪分布式集群)加深理解。