Hadoop面试100道精选题解(附答案)

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读写流程的完整步骤是什么?

写入流程

  1. 客户端通过DistributedFileSystem创建文件,请求NameNode分配块位置。
  2. NameNode返回DataNode列表(按机架感知策略优化)。
  3. 客户端按顺序写入DataNode,采用流水线复制(如DN1→DN2→DN3)。
  4. 每个块写入完成后,DataNode向NameNode汇报元数据。

读取流程

  1. 客户端请求NameNode获取文件块位置(优先读取本地或同机架节点)。
  2. 客户端并行从多个DataNode读取数据块,合并为完整文件。
    关键点:写入时需等待所有副本确认,读取时支持就近原则降低延迟。

二、核心组件深度解析

3. MapReduce的Shuffle机制如何工作?

Shuffle是MapReduce的核心优化环节,分为四个阶段:

  1. Map端

    • 每个Map任务输出<key, value>对到环形内存缓冲区(默认100MB)。
    • 缓冲区满时触发溢写(Spill),通过Partitioner按Key分区(如HashPartitioner)。
    • 对每个分区内的键值对按Key排序(使用快速排序或归并排序)。
    • 可选Combiner进行本地聚合,减少网络传输量。
  2. Reduce端

    • 通过HTTP从所有Map节点拉取属于自己分区的中间数据。
    • 合并多个溢写文件(归并排序),生成已排序的键值对列表。
    • 将数据传递给Reduce函数处理。
      优化建议:调整io.sort.mb参数控制缓冲区大小,自定义Partitioner实现数据倾斜处理。

4. YARN资源调度策略有哪些?如何选择?

YARN支持三种调度器:

  • FIFO Scheduler:先进先出,适合单用户集群,但无法处理多租户场景。
  • Capacity Scheduler:按层级队列分配资源(如开发/生产队列),支持弹性扩容。
  • Fair Scheduler:动态平衡资源分配,确保所有应用公平获取资源。
    配置示例
    1. <property>
    2. <name>yarn.scheduler.capacity.root.queues</name>
    3. <value>dev,prod</value>
    4. </property>
    5. <property>
    6. <name>yarn.scheduler.capacity.root.dev.capacity</name>
    7. <value>30</value>
    8. </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.mbmapreduce.map.java.opts
  • 网络问题:DataNode与NodeManager间通信超时。
    解决方案:检查yarn.nodemanager.disk-health-checker.min-healthy-disks配置。

四、高级特性与生态扩展

7. HBase与Hadoop的集成方式?

HBase依赖HDFS存储数据文件(HFile),通过RegionServer处理读写请求:

  1. 写路径:MemStore缓存写入数据,达到阈值后刷写为HFile。
  2. 读路径:优先从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并统计访问次数

  1. public class URLMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
  2. private final static IntWritable one = new IntWritable(1);
  3. private Text url = new Text();
  4. public void map(LongWritable key, Text value, Context context) {
  5. String[] parts = value.toString().split("\t");
  6. url.set(parts[1]); // 假设URL在第二列
  7. context.write(url, one);
  8. }
  9. }

Reducer阶段:汇总相同URL的计数

  1. public class URLReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
  2. public void reduce(Text key, Iterable<IntWritable> values, Context context) {
  3. int sum = 0;
  4. for (IntWritable val : values) {
  5. sum += val.get();
  6. }
  7. context.write(key, new IntWritable(sum));
  8. }
  9. }

优化点:使用Combiner减少网络传输,设置mapreduce.job.reduces=20并行处理。

10. 如何排查Hadoop作业执行失败?

排查步骤

  1. 查看YARN Application Master日志(yarn logs -applicationId <app_id>)。
  2. 检查MapReduce任务计数器(如SPILLED_RECORDS过高可能需调整内存)。
  3. 分析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机制、资源调度策略和故障排查流程,同时通过动手实验(如搭建伪分布式集群)加深理解。