运维常见题-大数据运维
DeepSeek V4 Flash Vision Exp 辅助生成。若您在阅读中发现存疑或矛盾之处,欢迎反馈讨论,笔者将及时核实与修正。🤔 大数据运维核心工作有哪些?
大数据运维围绕“集群稳、数据准、任务快”三大目标:①集群管理(
Hadoop/Spark/Flink组件部署、扩容、调优、高可用)②数据运维(采集、存储、HDFS管理、备份恢复、数据质量)③任务运维(调度、YARN/Spark作业监控、OOM/慢任务排查)④监控告警 + 安全权限。核心:“管集群、护数据、盯任务、保安全”。集群运维(基础设施)
- 组件部署/升级(
HDFS/YARN/Spark/Flink/HBase/ZooKeeper)、配置管理、高可用 - 容量规划(
HDFS存储、YARN计算资源、节点扩缩容)、性能调优(网络/磁盘/参数)
- 组件部署/升级(
数据运维(数据资产)
- 数据采集(日志/数据库/消息接入
HDFS)、存储管理(副本、冷热分层)、HDFS文件策略(NameNode元数据、DataNode磁盘) - 备份恢复、数据质量校验(完整性/一致性)、垃圾数据清理(
Trash/生命周期)
- 数据采集(日志/数据库/消息接入
任务运维(计算引擎)
- 调度运维(
YARN/调度器、队列)、Spark/Flink作业提交/监控/失败重试 - 性能排查(
OOM、慢任务、数据倾斜、资源竞争)、Checkpoint(Spark/Flink)/Savepoint(Flink)管理
- 调度运维(
监控告警 + 安全
- 指标监控(
HDFS容量、YARN资源、节点健康、作业状态——Ambari(HDP管理面板,现多被Cloudera Manager取代)/Prometheus/Grafana) - 告警分级(节点宕机/磁盘满/任务失败/
NameNode异常)、日志采集分析 - 安全(
Kerberos认证、ACL、数据脱敏)、权限治理
- 指标监控(
协助记忆
- 口诀:“集群稳、数据准、任务快——管集群、护数据、盯任务、保安全”。
进阶思考
- 大数据运维和传统运维最本质区别?
- 对象从“单机/服务”变成“分布式集群 + 海量数据 + 计算作业”:要考虑数据分布/副本容错、资源调度、任务并行、数据倾斜,故障也从“服务挂”变为“
NameNode失联/DataNode坏块/作业OOM/数据倾斜”。更强调数据与计算联动。
- 对象从“单机/服务”变成“分布式集群 + 海量数据 + 计算作业”:要考虑数据分布/副本容错、资源调度、任务并行、数据倾斜,故障也从“服务挂”变为“
- 大数据集群最常见故障是什么?
- 磁盘满(
HDFS容量爆)、节点宕机(DataNode/NodeManager失联触发副本/任务重试)、NameNode元数据压力、资源不足(YARN队列抢占致任务饿死)、任务性能差(数据倾斜/OOM)。
- 磁盘满(
- 大数据运维和传统运维最本质区别?
扩展信息
- 核心组件:
HDFS(存储)、YARN(资源调度)、MapReduce/Spark(计算)、HBase(列存)、Hive(SQL)、ZooKeeper(协调)、Flink(流处理) - 监控工具:
Ambari(Hadoop集群管理面板)、Prometheus+Grafana、Cloudera Manager;日志ELK/Flink作业UI
- 核心组件:
🤔 大数据的核心技术栈有哪些?
大数据技术栈按“采集→存储→计算→调度→查询→分析”分层:①采集(
Flume/Kafka/Sqoop/Canal)②存储(HDFS/HBase/Kudu/S3)③计算(MapReduce/Spark/Flink)④调度(YARN/K8s/Airflow)⑤查询(Hive/Spark SQL/Presto/Impala)⑥分析(Zeppelin/ECharts/机器学习MLlib)。核心:“采集进、存储底、计算层『批+流』、调度与查询往上”。数据采集层
- 日志:
Flume/Logstash;消息队列:Kafka(高吞吐缓冲);数据库同步:Sqoop(增量,已停更——1.4.7后入Apache Attic,现多被Flink CDC/SeaTunnel/Debezium取代)/Canal/DataX(增量/实时,现代常选) - 作用:把分散数据接入到大数据平台(
HDFS/HBase)
- 日志:
存储层
- 分布式文件:
HDFS(海量、批处理基础);列存:HBase(KV随机读)/Kudu(实时分析);对象:S3/OSS(云) - 特点:分布式、冗余副本、横向扩展、
PB级存储
- 分布式文件:
计算层(批/流)
- 批处理:
MapReduce(离线、磁盘、慢)→Spark(内存、快、DAG) - 流处理:
Flink(实时、低延迟Checkpoint)/Spark Streaming(微批)
- 批处理:
调度与资源层
- 资源调度:
YARN(Hadoop资源调度)、K8s(云原生容器调度);任务编排:Airflow/Oozie(工作流调度)——两类层级不同
- 资源调度:
查询与 SQL 层
- 离线数仓:
Hive(SQL转MapReduce/Spark);跨源查询:Presto/Impala;交互式:Spark SQL(批);实时流:Flink SQL
- 离线数仓:
分析与应用层
Notebook(Zeppelin/Jupyter)、BI报表、机器学习(Spark MLlib/TensorFlow)
协助记忆
- 口诀:“采集(
Kafka/Flume)→ 存储(HDFS/HBase)→ 计算(Hadoop批、Spark内、Flink流)→ 调度YARN、查询Hive/Presto”。
- 口诀:“采集(
进阶思考
- 批处理和流处理的典型技术演进?
- 早期批处理
MapReduce(磁盘慢)→Spark(内存快)统一批;流处理早期Storm/Spark Streaming(微批)→Flink(真流式、低延迟、Exactly-once)。现代趋势“批流一体”(Spark/Flink都能做批+流)。
- 早期批处理
- 为什么需要
Kafka这一层(采集和存储之间)?- 缓冲削峰(高并发写入不压垮下游)、解耦(采集/消费独立)、持久化(可回溯重放)、多消费(一份数据多方用)。是实时链路的核心枢纽。
- 批处理和流处理的典型技术演进?
扩展信息
- 技术栈全景:采集(
Flume/Kafka/Sqoop/Canal)、存储(HDFS/HBase/Kudu)、计算(MapReduce/Spark/Flink)、调度(YARN/K8s)、查询(Hive/Presto)、分析(MLlib/Zeppelin) - 选型思路:离线批量归
Spark、实时流归Flink、SQL数仓用Hive/Spark SQL、海量KV用HBase
- 技术栈全景:采集(
🤔 Hadoop 的核心组件有哪些?各自的作用是什么?
Hadoop四大核心模块:HDFS(分布式文件存储)、YARN(统一资源调度)、MapReduce(分布式计算框架)、Hadoop Common(公共工具库)。加上配套生态ZooKeeper(协调)/Hive(SQL)。核心:“HDFS存、YARN调度资源、MapReduce算——三驾马车加公共库”。HDFS(分布式文件系统,存储)- 作用:海量数据分布式存储(
NameNode管元数据 +DataNode存数据块),自动副本容错 - 特点:一次写入多次读取、高吞吐、适合海量离线数据
- 作用:海量数据分布式存储(
YARN(资源调度管理器,资源)- 作用:统一管理集群计算资源(
CPU/内存),调度作业(ResourceManager管全局、NodeManager管单点、ApplicationMaster管单个作业) - 特点:资源池化、多计算引擎(
MapReduce/Spark/Flink)共用
- 作用:统一管理集群计算资源(
MapReduce(计算框架)- 作用:离线批处理(
Map分片处理 +Reduce汇总),Hive底层可经它;Spark为独立执行引擎(不经MapReduce) - 特点:磁盘重度、吞吐低(逐步被
Spark取代),但仍是Hadoop经典算法思想
- 作用:离线批处理(
Hadoop Common(公共库)- 作用:公共工具(
FS文件系统抽象、RPC、Config配置、序列化),其他模块依赖
- 作用:公共工具(
生态配套(易问)
ZooKeeper(分布式协调,HDFS/HBase高可用依赖)、Hive(SQL查询)、Sqoop/Flume(数据进出)
协助记忆
- 口诀:“
HDFS存、YARN调度资源、MapReduce算——Common 打底,生态ZK/Hive配套”。
- 口诀:“
进阶思考
HDFS为什么适合海量离线不适合实时?HDFS高吞吐(顺序大文件读)、一次写多次读——适合批处理/归档;但随机小文件读写慢(Block大/元数据集中NameNode)、延迟高,不适合实时小查询(那是HBase/Kafka的事)。
YARN怎么让多个计算引擎共存?YARN只管资源(CPU/内存),不管计算逻辑——MapReduce/Spark/Flink各自提交ApplicationMaster到YARN申请容器跑任务,共用集群资源,按需分配(队列/优先级)。所以集群“一鱼多吃”。
扩展信息
Hadoop发行版:Apache Hadoop、CDH/HDP(商业版,已并入Cloudera);运维常基于发行版 +Ambari/CM管理Hadoop定位:海量离线数据的基础设施;实时/交互场景外移到Spark/Flink/HBase
🤔 Hadoop 集群有哪些关键进程及作用?
HDFS有NameNode(元数据)+DataNode(数据块)+(HA 时ZKFC/JournalNode);YARN有ResourceManager(资源)+NodeManager(节点)+ApplicationMaster(作业)。核心:“NameNode管目录、DataNode管块、RM管资源、NM管单点”。HDFS进程NameNode:管理文件系统元数据(目录/文件/块映射),响应客户端请求;是集群大脑,Active/Standby(HA)DataNode:存储数据块(Block),定期上报NN(心跳+块报告);坏块检测/副本复制JournalNode/ZKFC(HA 时):JournalNode存共享元数据日志(QJM),ZKFC通过ZK自动主备切换SecondaryNameNode:旧版辅助合并EditLog(非备份,生产多用 HA)
YARN进程ResourceManager:全局资源调度(接收作业、分配Container、管理队列),Active/StandbyNodeManager:单节点资源管理器(上报资源、启动/监控Container)ApplicationMaster:每作业一个(申请资源、调度作业内任务、管理生命周期)——作业级临时进程(随作业生灭,非集群常驻守护进程,与RM/NM层级不同)
其他(生态)
ZooKeeper(HDFS/HBase/YARNHA 的协调)、Hive(Metastore)、HBase(HMaster/RegionServer)
协助记忆
- 口诀:“
HDFS:NN管元数据、DN存块;YARN:RM管资源、NM管节点、AM管作业;HA 靠ZKFC+JournalNode”。
- 口诀:“
进阶思考
NameNode挂了集群会怎样?NameNode挂 →HDFS停止服务(DataNode还在但元数据不可读),数据不丢(数据在DataNode);HA 下由Standby经ZKFC自动接管(RPO很小),单NN需人工恢复(从FSImage+EditLog重启)。所以生产必须HA。
DataNode宕机一个会丢数据吗?- 不丢。
DataNode宕机 → 其上的Block副本减少(低于 3),HDFS检测到后自动在健康节点复制补齐副本(replication),不影响数据可用性(只要副本未降到min.replication下限)。
- 不丢。
扩展信息
- 进程端口:
NameNode9870/8020、DataNode9864、ResourceManager8088/8032、NodeManager8042、JournalNode8485 - 运维检查:
jps看各节点进程、hdfs dfsadmin -report看数据节点、yarn node -list看资源节点
- 进程端口:
🤔 简述 HDFS 的工作原理?
HDFS是分布式文件系统:文件被切分成数据块(Block,默认 128MB),块副本(默认 3 份)分布在多个DataNode上;NameNode只需记录元数据(目录/文件→块映射,块→DataNode映射由DataNode上报/心跳动态维护、不持久化),不存数据;读写都先向NameNode查询块位置,再与DataNode传输数据。核心:“NN管元数据 +DN存块副本,读写‘元数据到NN、数据到DN’”。核心设计(主从架构)
NameNode:只管元数据(命名空间、块映射),不存数据——数据流与元数据分离DataNode:存数据块(Block),心跳+块报告上报NN- 数据块(
Block):文件切块(默认 128MB),大于Block的块自动切分;副本默认 3——放置策略是 1 副本本机架、2 副本异机架、第 3 副本与第 2 副本同机架(跨机架容错,非全部相异)
写入流程(客户端)
- ①客户端向
NameNode请求写入(创建文件/申请块)②NN返回DataNode列表(按机架策略选 3 个)③客户端直接与DataNode建立管道(pipeline)写入数据(不经过NN)④逐副本流水线写(DN1→DN2→DN3)⑤写满一个Block再申请下一个,全部确认后NN提交 - 特点:数据流不经过
NN(省NN压力),管线式写副本
- ①客户端向
读取流程(客户端)
- ①向
NameNode查询文件块位置②NN返回块所在的DataNode列表(含副本)③客户端就近选择DataNode直接读,并行读多个块;④DN断连自动切换到其他副本
- ①向
副本管理
- 副本不足自动复制、副本过多自动删除(
replication因子),均衡(balancer),坏块/宕机触发再复制
- 副本不足自动复制、副本过多自动删除(
协助记忆
- 口诀:“
NN管元数据(哪块在哪)、DN存数据(块副本);读走NN查位置、直连DN传数据;块 128M、副本 3、跨机架”。
- 口诀:“
进阶思考
- 为什么数据流不经过
NameNode(关键设计)?NameNode是单点/元数据服务,若数据也流经它 → 成瓶颈 + 单点压力大。所以NN只做“目录服务”(告诉客户端去哪些DN读写),数据直接客户端↔DataNode传输——吞吐高、NN轻。
Block为什么设 128MB 那么大?- 大块减少元数据量(
NN内存有限,块越小元数据越多)、减少MapReduce任务数(块即处理粒度)、顺序读友好(大数据量高吞吐)。但块太大会牺牲小文件/随机读性能。
- 大块减少元数据量(
- 为什么数据流不经过
扩展信息
- 读写命令:
hdfs dfs -put/cat/get、hdfs dfsadmin -report(块/节点)、hdfs fsck(文件完整性检查) - 关键参数:
dfs.blocksize(128M)、dfs.replication(3)、dfs.namenode.name.dir/datanode.data.dir(存储路径)
- 读写命令:
🤔 HDFS NameNode 高可用是怎么实现的?
HDFS HA用“主备NameNode+ 共享元数据 + 自动切换”:两个NN(Active/Standby)共用共享元数据日志(QJM或NFS),ZKFC经ZooKeeper仲裁实现自动故障切换(failover)。核心:“Active提供服务 +Standby实时同步元数据(JournalNode),ZKFC监控并自动切换”。核心组件(QJM 模式)
- 两个
NameNode:Active(读写)、Standby(实时同步元数据,随时接管)——消除单点 JournalNode(QJM = Quorum Journal Manager):一组(≥3 个,奇数)存共享的EditLog——Active NN写日志、Standby NN读日志实时应用(保持元数据一致),JN用仲裁(多数派)ZKFC(ZooKeeper Failover Controller):每个NN旁一个,监控本NN心跳、经ZooKeeper维护Active锁,Active异常时自动触发切换(Standby升Active)ZooKeeper:提供Active锁与会话协调(不直接检测NN故障/选主——真正监控本NN心跳、持ZK锁并触发升Active的是ZKFC;fencing靠znode锁 + 纪元号防脑裂双主)
- 两个
工作流程(HA 原理)
- ①
Active NN写入时把元数据变更写JournalNode(多数派确认)②Standby NN实时从JN读EditLog并应用(保持同步)③ZKFC监控,Active失联 → 抢ZK锁,Standby升Active(先fencing隔离旧Active)④客户端经Namenode虚拟 name(配置自动访问新Active)
- ①
数据保障(关键)
fencing:切换前先隔离旧Active(避免两个NN同时写,脑裂)——QJM的fencing机制(fence 旧节点不再接受写)- 数据不丢:
Standby已同步元数据(RPO≈0),接管后数据完整;DataNode同时向两个NN汇报块信息
存储构建议
NameNode×2 +JournalNode×3(奇数)+ZK×3 → 提供集群元数据高可用(挂一个NN/JN/ZK都不影响)
协助记忆
- 口诀:“双
NN(主备)+JN共享日志 +ZKFC自动切换 +ZK仲裁——fencing防脑裂,数据不丢”。
- 口诀:“双
进阶思考
Standby NameNode是“热备”还是只是备份?- 热备(非备份):它实时从
JN同步元数据(EditLog),保持和Active一致,故障时能即时接管(不像SecondaryNameNode只是周期性合并日志、非实时)。它不做读写,但元数据最新。
- 热备(非备份):它实时从
JournalNode起了什么关键作用?- 它是元数据的“共享存储/传输层”:
Active写、Standby读——让两个NN元数据一致,且用多数派(≥3 挂 1 可用)保证日志不丢。是HA的核心(替代旧版SecondaryNameNode的定期合并方案)。
- 它是元数据的“共享存储/传输层”:
扩展信息
- HA 两种共享方式:
QJM(JournalNode多数派,推荐)+ 旧版NFS共享EditLog;新版还有NameNode滚动升级(rolling upgrade) - 运维检查:
hdfs haadmin -getServiceState(看主备)、hdfs haadmin -failover(手动切换)、ZK状态zkServer status
- HA 两种共享方式:
🤔 简述 YARN 资源调度流程?
YARN资源调度:作业经ResourceManager(全局)+ApplicationMaster(作业级)+NodeManager(节点级)协作——RM分配Container,AM向RM申请容器(allocate)、指派给作业内任务,NM负责启动/监控容器。核心:“RM管全局资源、AM管单作业申请、NM管节点容器”。核心角色
ResourceManager(RM):全局资源调度(接收作业请求、按队列/容量分配Container、管理调度器)——集群资源管理员ApplicationMaster(AM):每作业一个(向RM申请资源、把任务切分、向NM发起容器、监控作业)——作业的“管家”NodeManager(NM):单节点资源管理(上报资源、启动/停止Container、监控)——节点上的“执行者”
作业调度流程(以 MapReduce 为例)
- ①客户端提交作业到
RM(ApplicationMaster请求)②RM分配第一个Container,启动作业的AM③AM初始化作业(切分InputSplit、规划Map/Reduce任务)④AM向RM申请更多Container(按资源需求)⑤RM根据调度器(容量/公平)分配Container(指定节点)⑥AM联系NM启动任务容器(Map/Reduce),NM执行并回报进度⑦任务完成,AM回收资源并通知RM,作业结束
- ①客户端提交作业到
调度器(资源分配策略)
- 容量调度器(Capacity):按队列分配(
yarn.scheduler.capacity,队列内FIFO/资源占比)——生产常用 - 公平调度器(Fair):队列内公平共享(动态分配、支持抢占),适合多用户共享
- 调度器决定“给谁、给多少”——租户/队列隔离、优先级
- 容量调度器(Capacity):按队列分配(
Container(资源单元)- 资源抽象(
CPU核 + 内存 + 等),流程:AM申请 →RM调度器分配 →NM启动,任务在Container里跑
- 资源抽象(
协助记忆
- 口诀:“
RM发资源、AM作业申请、NM跑容器——客户端提交→RM启AM→AM申请→NM执行→回收”。
- 口诀:“
进阶思考
- 为什么引入
ApplicationMaster(相比旧JobTracker集中调度)?- 旧
MapReduce v1的JobTracker既管资源又管作业,单点 + 瓶颈。YARN把“资源管理(RM)”与“作业调度(AM 每个作业一个)”解耦——RM只管资源,各作业AM自行调度,横向扩 + 多计算框架共存(Spark/Flink各自AM)。
- 旧
- 队列/资源隔离怎么用(多租户)?
- 容量调度器按队列划分(
queue_a/queue_b各占资源比例),队列内可设最大/最小资源、优先级、ACL(谁可提交)——实现多部门资源共享又互不挤占,关键作业可保底资源。
- 容量调度器按队列划分(
- 为什么引入
扩展信息
- 调度相关:
CapacityScheduler/FairScheduler、yarn.scheduler.capacity.root.queues队列配置、elastic/preemption抢占 - 运维:
yarn application -list/status、yarn node -list、yarn queue -status(队列状态)、ResourceManagerUI(8088)
- 调度相关:
🤔 YARN 的核心组件有哪些?
YARN四大核心:ResourceManager(全局资源调度)、NodeManager(节点资源)、ApplicationMaster(作业调度)、Container(资源容器)。核心:“RM管全局、NM管节点、AM管作业、Container是资源单元”。ResourceManager(RM)- 全局资源管理(接收作业、调度
Container、维护集群资源状态);HA 时 Active/Standby - 内含
Scheduler(资源分配策略:容量/公平)+ApplicationsManager(作业生命周期管理:接纳作业提交、为AM协商首个Container、跟踪并重启失败AM)
- 全局资源管理(接收作业、调度
NodeManager(NM)- 单节点资源管家(上报节点资源、启动/监控
Container、健康检查),一个节点一个 - 与
RM心跳保持节点存活/资源可用
- 单节点资源管家(上报节点资源、启动/监控
ApplicationMaster(AM)- 每作业一个(向
RM申请Container、切分任务、指派给NM、监控作业);Spark/Flink/MapReduce各有 AM
- 每作业一个(向
Container- 资源抽象(
CPU+内存+其他),是任务的运行单元(在NM上启动的进程) - 生命周期:
AM申请 →RM分配 →NM启动 → 任务完成回收
- 资源抽象(
协助记忆
- 口诀:“
RM全局、NM节点、AM作业、Container资源——四级协同调度”。
- 口诀:“
进阶思考
AM为什么不是集群级而是作业级?- 每个作业一个
AM,作业间调度互不干扰、天然隔离:作业挂只影响自己;多种计算引擎(MR/Spark/Flink)各自实现AM即可接入YARN。这就是YARN“通用资源调度平台”的关键。
- 每个作业一个
NodeManager失联会怎样?RM定时收NM心跳,超时(yarn.nm.liveness-monitor.expiry-interval-ms)判定节点失联 → 其上Container被标记失败、任务重试(AM在其他NM重新分配),资源释放回收。节点恢复后重新上报资源。
扩展信息
- 调度器:
CapacityScheduler/FairScheduler(yarn.resourcemanager.scheduler.class) - 运维命令:
yarn node -list、yarn application -list/-status/-kill、yarn queue -status、jstack/日志(ResourceManager8088 /NodeManager8042UI)
- 调度器:
🤔 Hadoop 集群如何扩容?
Hadoop扩容分两种:加数据节点(HDFS存储扩容,DataNode)和加计算节点(YARN计算扩容,NodeManager)。步骤:新节点准备(环境/依赖)→ 部署DataNode+NodeManager进程 → 加入集群(NN/RM识别)→ 数据均衡(HDFSbalancer,新节点填满)。核心:“加DN扩存储、加NM扩计算,DataNode自动上报、balancer均衡数据”。扩容前准备(新节点)
- 环境就绪(JDK 版本一致、
Hadoop目录/配置复制、主机名/hosts、SSH免密(分发用)、时间同步) - 配置一致(
core-site.xml/hdfs-site.xml/yarn-site.xml与现有集群一致)、slaves/workers文件加入新节点 - 磁盘挂载/数据目录(
datanode.data.dir)就绪
- 环境就绪(JDK 版本一致、
部署进程(
DataNode+NodeManager)- 新节点执行
hdfs datanode(存储)+yarn nodemanager(计算),通过start-dfs.sh/start-yarn.sh或单独启动 DataNode启动后向NameNode注册(上报块),NodeManager向ResourceManager注册(上报资源),自动纳入集群
- 新节点执行
加入与验证
hdfs dfsadmin -report:新DataNode出现在Live datanodes;yarn node -list:新NodeManager显示- 集群状态健康(
NN/RM正常),无异常
数据均衡(
HDFS balancer)- 新
DataNode初始为空——HDFS默认不自动均衡存量数据(不主动把健康副本迁到新节点);只有新写入按放置策略偏向空闲节点;存量分布靠手动hdfs balancer(低峰/定时执行)让数据均匀 balancer参数(带宽/阈值),低峰执行(占IO)
- 新
注意事项
- 只加
DataNode(存)不加NodeManager(算)也行(按需),反之亦然 - 扩容后新写入偏向新节点(
DataNode只承接新增数据);YARN资源自动增加(NodeManager上报);存量数据需hdfs balancer迁移
- 只加
协助记忆
- 口诀:“新节点备环境 → 装
DN/NM→ 自动注册上报 →hdfs balancer均衡数据——加DN扩存储、加NM扩计算”。
- 口诀:“新节点备环境 → 装
进阶思考
- 扩容会中断集群吗?
- 不会。
Hadoop支持在线/水平扩容——新节点加入是渐进的(DataNode上报即服务),旧节点不受影响;数据均衡是后台(balancer)渐进迁移。但要控制balancer带宽避免占满IO影响业务(低峰执行)。
- 不会。
- 数据倾斜(扩容后新旧节点不均)怎么办?
HDFS均衡靠balancer(按DataNode磁盘使用率),不均时手动hdfs balancer -threshold调;YARN资源自动均摊(NM上报)。大数据量迁移慢,分阶段 + 监控磁盘使用率。
- 扩容会中断集群吗?
扩展信息
- 相关命令:
hdfs balancer(数据均衡)、hdfs dfsadmin -report(节点)、yarn node -list、jps(验证进程) - 配置:
slaves/workers文件、dfs.replication、yarn.nodemanager.resource.memory-mb(目标节点资源)、datanode.data.dir(磁盘)
- 相关命令:
🤔 Spark 与 MapReduce 的核心区别是什么?
Spark与MapReduce的核心区别是计算模型与中间存储:MapReduce每步Map/Reduce都要落磁盘(HDFS),迭代慢;Spark用内存的RDD(弹性分布式数据集)+DAG调度,中间结果驻内存、多步算子链式执行,比MR快 10-100 倍。核心:“MR磁盘迭代慢、Spark内存DAG快且统一批流”。计算模型
MapReduce:Map(切分处理)→Shuffle(按 key 分组)→Reduce(汇总);每阶段中间结果落本地盘(mapred.local.dir,非HDFS——仅Reduce最终输出写HDFS),多阶段作业频繁读写磁盘Spark:RDD(内存数据集)算子在DAG上链式执行,中间结果默认驻内存(可缓存/持久化),少落盘;Shuffle也优化
性能(核心差异)
- 迭代计算(机器学习/多轮
join):MR每轮落盘(慢),Spark内存缓存(快 10-100x) - 交互/
Spark SQL查询:Spark响应快
- 迭代计算(机器学习/多轮
编程与抽象
MR:map/reduce函数(Java,繁琐);Spark:RDD/DataFrame/Dataset高层 API(Python/Scala/SQL),transformation(惰性)+action(触发)Spark惰性:转换操作不立即执行,遇action(count/collect)才按DAG调度执行
能力范围
MR:仅批量离线(Hive/MR);Spark:批处理 +Spark SQL+Spark Streaming(微批) +MLlib(机器学习) +GraphX(图)——统一一个引擎- 运行模式:
Spark可用YARN/K8s/Standalone(Mesos已弃用——3.2起弃用、4.0移除)
实际定位
- 老
Hadoop MapReduce仍在(历史兼容),新项目普遍用Spark(内存 + 统一 + 快)
- 老
协助记忆
- 口诀:“
MR磁盘慢、Spark内存快;MR一步一落盘、SparkDAG链式算;Spark批流 SQL 一锅端”。
- 口诀:“
进阶思考
Spark为什么比MR快这么多(除了内存)?- ①内存缓存中间结果(少磁盘
IO)②DAG调度(任务间依赖清晰、stage内并行、避免MR的无谓落盘)③算子优化(Spark把多个操作合并、优化Shuffle)④DataFrame有Catalyst优化器(列式/谓词下推)。内存 + 智能调度 + 优化器共同作用。
- ①内存缓存中间结果(少磁盘
Spark内存不够(OOM)怎么办(和 MR 比)?MR落盘天然内存安全(慢);Spark内存敏感——靠:调spark.executor.memory、数据分区(repartition/coalesce)、序列化、Shuffle分区数、避免大collect。Spark用空间换时间,内存管理是调优核心。
扩展信息
Spark生态:Spark Core(RDD)、Spark SQL(DataFrame)、Spark Streaming(DStream)、MLlib、GraphXMRvsSpark选型:离线大规模、已有MR生态用MR(兼容);交互/迭代/流用Spark(性能)
🤔 Spark 核心组件有哪些?
Spark核心:Spark Core(RDD基础)、Spark SQL(结构化查询/DataFrame)、Spark Streaming(微批流)、MLlib(机器学习)、GraphX(图计算)。运行框架上:Driver(主程序)+Executor(执行器)+Cluster Manager(YARN/K8s/Standalone)。核心:“Core打底 +SQL/Streaming/MLlib/GraphX四组件 +Driver/Executor架构”。核心库(组件)
Spark Core:RDD(弹性分布式数据集)+ 调度(DAG+Stage+Task)+ 运行时——一切的基础Spark SQL:DataFrame/Dataset,SQL查询 +Catalyst优化器 +Hive兼容(thriftserver)Spark Streaming:微批流处理(DStream,把流切成小批);Structured Streaming基于DataFrame/DatasetAPI,属Spark SQL引擎(非DStream子集)MLlib:分布式机器学习(特征/分类/聚类/推荐算法),Pipeline流程化GraphX:图计算(PageRank/社区发现),基于RDD的图 API
运行时架构(
Driver/Executor)Driver:SparkContext/SparkSession——作业入口,切分DAG→Stage→Task,调度分发;管理作业生命周期Executor:Worker上的执行进程(跑Task、缓存RDD),多个Task并行执行Cluster Manager:资源调度(YARN/K8s/Standalone;Mesos已弃用)——Driver和Executor跑在上面
数据抽象
RDD(基础,低层)、DataFrame(Schema化,优化好)、Dataset(类型化,Scala/Java用)——DataFrame/Dataset经Catalyst优化
协助记忆
- 口诀:“
Core打底(RDD),SQL/Streaming/MLlib/GraphX四组件;运行Driver调度 +Executor干活 +Cluster Manager给资源”。
- 口诀:“
进阶思考
Driver挂了会怎样?Driver是作业大脑,挂了作业失败(Executor还在但无人调度/收结果)。生产要Driver高可用(YARN下AM重启、K8s下DriverPod重启),Driver网络/内存要监控。
Executor数/核怎么定?- 影响并行度与资源利用:
Executor数 × 核数 ≈ 集群可并行任务上限;内存给够(别OOM)但别过大(GC压力)。权衡:executor数量、每executor核数/内存、并行度(parallelism)——经典调优三元组。
- 影响并行度与资源利用:
扩展信息
- 生态:
Spark+Hive(ThriftServer支撑SQL)、Spark on YARN最常用、Structured Streaming(现代实时) - 可选:
Spark 3.x的AQE(自适应查询执行)、Dynamic Allocation(动态分配)、PySpark(Python写DataFrame)
- 生态:
🤔 简述 Spark Job 提交后的执行流程?
Spark作业提交后:Driver构建DAG→ 划分Stage(按Shuffle边界)→ 生成Task(按分区)→DAGScheduler提交给TaskScheduler→Cluster Manager分配资源 → 各Executor执行Task→ 结果回Driver。核心:“RDD算子 →DAG→Stage切分 →Task分发执行”。执行流程(分阶段)
- ①客户端
submit作业 →Driver(SparkContext/SparkSession)初始化 - ②
Driver把RDD算子链构建成DAG(有向无环图,记录转换关系) - ③
DAGScheduler把DAG按**Shuffle边界**切成Stage(ShuffleMapStage:写Shuffle;ResultStage:产出结果) - ④
Executor先经Cluster Manager(YARN/K8s/Standalone)在应用启动时分配并注册 - ⑤每
Stage按分区(Partition)生成Task(ShuffleMapTask/ResultTask),TaskScheduler派发给各Executor并行执行 - ⑥
ShuffleMapTask输出Shuffle中间数据;ResultStage的ResultTask计算最终结果 - ⑦
Task结果回Driver(或直接写外部存储)——整个流程由action触发启动(如count/collect)
- ①客户端
关键概念
DAG:算子的依赖图(转换关系)——Driver用它做优化/调度Stage:DAG按Shuffle切分(窄依赖一个Stage,宽依赖Shuffle分Stage),Stage内部Task并行Task:任务最小执行单元(每分区一个),在Executor上跑- 懒执行:
transformation只记DAG,遇action(count/collect/saveAsTextFile)才触发真正执行
失败处理
Task失败自动重试(spark.task.maxFailures)、Stage失败重算、检查点(checkpoint)断点
协助记忆
- 口诀:“
RDD算→DAG图→Shuffle切Stage→分区产Task→Executor并行跑→action触发执行”。
- 口诀:“
进阶思考
- 为什么按
Shuffle划分Stage?Shuffle(如groupByKey/join)需要数据全部到达后按key汇总——是天然的执行边界(Stage边界)。Shuffle前可流水线(窄依赖合并),Shuffle后新Stage。这样Stage内并行、Stage间依赖(Shuffle落盘),任务划分清晰。
DAG调度和MapReduce的作业划分有何不同?MR是固定Map→Shuffle→Reduce两阶段(不管步骤多少都是这两步,多步就多次MR落盘);SparkDAG把整条算子链按Shuffle切Stage,Stage内多算子合并执行(不分步落盘)——更灵活高效。
- 为什么按
扩展信息
- 易混淆:
Job(一个action触发的一个DAG)、Stage(DAG按Shuffle切)、Task(Stage内分区任务)——层级关系:Job→Stage→Task - 运维:
Spark UI(看Job/Stage/Task耗时/Shuffle大小)、日志(Driver/Executor)、event log
- 易混淆:
🤔 Spark 有哪几种运行模式?
Spark四种运行模式(按资源管理/部署):Local(本地单机调试)、Standalone(Spark 自带集群)、YARN(Hadoop生态,生产主流)、K8s(云原生容器)。核心:“本地调试Local、自带集群Standalone、Hadoop上YARN、云原生K8s”。Local模式- 单机多线程(
spark-submit --master local[n]),不启动集群——开发/调试用 - 特点:最快上手,无真实集群/分布式(测试代码用)
- 单机多线程(
Standalone模式Spark自带的简单集群(Master+Worker),不依赖Hadoop——小集群/快速部署- 特点:部署简单、无
YARN生态时用;但资源管理/多租户弱于YARN
YARN模式(生产最常用)- 作业提交到
Hadoop YARN(yarn-client/yarn-cluster),由ResourceManager调度资源,与Hive/MR共用集群——生产主流 - 特点:资源统一管理、多框架共用、高可用(
YARN HA)、队列隔离/配额 yarn-cluster(Driver跑在YARN,AM管理):生产推荐
- 作业提交到
K8s模式(云原生)Spark作业跑在Kubernetes(Pod),K8s调度资源——云原生/容器化环境- 特点:容器隔离、弹性、与云生态集成(
S3/HDFS存储)
选型
- 调试
Local、小集群/自建Standalone、Hadoop生态YARN、云原生K8s——生产多YARN(与Hive共用)或K8s(新架构)
- 调试
提交方式
spark-submit --master yarn --deploy-mode cluster ...;clientvscluster(Driver在哪跑)
协助记忆
- 口诀:“本地调试
local、自带集群standalone、Hadoop上yarn、云原生k8s——生产选yarn/k8s”。
- 口诀:“本地调试
进阶思考
yarn-client和yarn-cluster区别?client:Driver跑在提交客户端(本地机器),适合交互式/调试(Driver在提交机,作业与提交机绑,提交机挂作业挂);cluster:Driver跑在YARN集群的AM容器里(Driver即AM内进程,AM管理其生命周期),提交后客户端可离开——生产用cluster(Driver随AM重启、提交机解耦)。
StandalonevsYARN怎么选?- 已用
Hadoop(有YARN/Hive)→YARN(统一资源、共用集群、队列隔离);刚起步/不想依赖Hadoop、资源管理简单 →Standalone(轻量,但多租户/高可用弱)。
- 已用
扩展信息
Master URL:local[*]、spark://host:7077(standalone)、yarn、k8s://https://...- 配套:
--deploy-mode client/cluster、--num-executors/--executor-memory(YARN下资源)、spark-submit脚本封装
🤔 Flink 集群有哪些核心组件?
Flink集群(Session/Per-job模式)核心:JobManager(作业管理/调度/Checkpoint协调)、TaskManager(执行任务/数据流处理)、Job(客户端提交的作业)+ZK/HA。核心:“JobManager大脑 +TaskManager干活 + 可HA高可用”。JobManager(JM,作业管理器)- 集群主节点——接收作业(
JobGraph)、调度Task到TaskManager、协调Checkpoint/恢复、管理集群状态 - 高可用:
HA部署(ZooKeeper+ 元数据持久化到HDFS),JobManager挂可切换 - 内部:
Dispatcher(接收作业)、ResourceManager(分配TaskManager资源)、JobMaster(每作业一个管理)
- 集群主节点——接收作业(
TaskManager(TM,任务管理器)- Worker 节点——执行
JobManager分配的Task(算子/算子链),管理任务线程与内存/网络 - 一个
TM跑多个Task(Slot资源槽——并发执行的单元,TaskManager.numberOfTaskSlots)
- Worker 节点——执行
Job/客户端- 客户端(
Flink SQL/DataStream程序)打包JobGraph提交到Cluster——flink run/Flink SQLCLI - 作业提交到
Session Cluster(共享集群)或Per-job(独立集群实例)
- 客户端(
HA与协调ZooKeeper([JobManager选主/存储状态])、HDFS/S3(Checkpoint/Savepoint存储)Standalone模式下自建集群;YARN/K8s模式下由外部调度(Flink on YARN/Flink on K8s)
资源抽象
Slot:TaskManager上的并发单位(一个槽跑一个任务),决定并行度上限
协助记忆
- 口诀:“
JobManager大脑(调度/Checkpoint)+TaskManager干活(Slot跑任务)+ 客户端提交;ZK+HDFS做HA/状态存储”。
- 口诀:“
进阶思考
JobManager挂了会怎样(有没有 HA)?- 无
HA:作业中断,从头恢复(丢状态);有HA:ZK选新JobManager,从Checkpoint恢复(断点续算),TaskManager重连。生产必须HA(JobManager× 多 +ZK)。
- 无
TM的Slot数和并行度什么关系?Slot是TM上可并行执行的槽位,总 Slot 数 = 集群能支持的最大并行度(容量上限);作业并行度是独立配置值(env.setParallelism/算子级),需 ≤ 可用Slot才能全部同时运行(超出会快速失败Could not allocate all required slots,非排队),是Flink并发与吞吐的关键。
扩展信息
- 部署模式:
Standalone/Flink on YARN/Flink on K8s(K8s下用Operator部署);Session(共享)/Per-Job/Application模式 - 运维:
Flink Web UI(JobManager地址)、flink list/savepoint/cancel、Checkpoint配置(state.backend/CheckpointStorage)
- 部署模式:
🤔 Flink Checkpoint 是什么?作用?
Flink Checkpoint(检查点)是周期性自动的全局状态快照:每隔一段时间,JobManager协调TaskManager把算子的状态(KeyedState/OperatorState)+ 数据源偏移量一致地存到持久存储(HDFS/S3),用于故障恢复(作业挂了从最近一次Checkpoint重启续算)。核心:“周期自动存一致状态,故障时从检查点恢复,实现Exactly-once”。作用(核心价值)
- 故障恢复:作业/机器挂了,从上次
Checkpoint恢复(状态 + 数据源 offset 对齐)——不丢数据、少重算 Exactly-once语义基础:配合 state + offset 对齐 + 事务输出(两阶段提交),保证处理恰好一次- 是
Flink流处理可靠性的基石(生产必开)
- 故障恢复:作业/机器挂了,从上次
工作机理
CheckpointCoordinator(JobManager)周期触发(checkpoint.interval)屏障(Barrier) 注入数据流Barrier随数据流流动,算子收到Barrier后把状态快照写入CheckpointStorage(HDFS/S3),所有算子快照完成 → 一个Checkpoint成功(n/n完成)- 增量
Checkpoint(RocksDB增量)、对齐(对齐/非对齐)
配置
state.backend(RocksDB/Heap)、checkpoint.interval(频率)、checkpoint.timeout、savepoint(手动)、存储目录(HDFS/S3)Checkpoint自动、周期;Savepoint手动、用户触发
与
Savepoint区别(常问)Checkpoint:自动、周期、触发频率高、用于故障自动恢复、恢复快(默认)Savepoint:手动(flink savepoint)、可指定时间点、用于运维操作(升级/迁移/回滚)、可跨版本恢复
协助记忆
- 口诀:“
Checkpoint周期自动存一致状态(state+offset),故障从它恢复——Exactly-once基石;Savepoint手动存、改代码升级用”。
- 口诀:“
进阶思考
Checkpoint怎么做到“一致”(不重不漏)?- 用屏障对齐:
Barrier随数据流注入,算子收到本通道Barrier后暂停该通道处理、等所有通道Barrier到齐再一起快照——对齐属于检查点一致性机制(保证快照时刻状态与offset严格对应);但端到端Exactly-once还须配合事务输出(两阶段提交),仅对齐不保证语义。
- 用屏障对齐:
Checkpoint太频繁会怎样?- 频率高:状态快照频繁写存储(
IO压力)、影响吞吐;频率低:恢复时从头重算多。权衡:按状态量/吞吐设间隔(如30s-5min),配合增量Checkpoint减小开销。
- 频率高:状态快照频繁写存储(
扩展信息
- 相关:
state.backend(RocksDB/HashMap)、CheckpointStorage(Fs/JobManager)、exactly-once/at-least-once语义、barrier对齐/非对齐 - 运维:
flink savepoint/cancel -s、CheckpointUI(JobManager)、HA存储(HDFS目录)
- 相关:
🤔 Flink Savepoint 是什么?作用?与 Checkpoint 区别?
Flink Savepoint(保存点)是手动触发的全量状态快照,存到持久存储(HDFS/S3)——用于运维操作(升级版本/改并行度/迁移/回滚),可从它restore恢复。与Checkpoint区别:Checkpoint自动周期/故障恢复用;Savepoint手动/运维操作用。核心:“Savepoint手动存做运维,Checkpoint自动存做故障”。Savepoint是什么- 用户手动触发(
flink savepoint <jobId> <dir>)的作业状态 + 数据源 offset 一致快照(全量) - 存到指定路径(
savepoint.dir/命令行指定),是作业的“存档点”(可随时恢复)
- 用户手动触发(
作用(运维场景)
- 升级版本:
Flink/SQL升级前打Savepoint,升级后restore(跨版本恢复) - 改并行度/拓扑:调整并行度后从
Savepoint恢复(状态重新分配) - 迁移/回滚:作业迁移到新集群、改代码后要回滚,
Savepoint恢复到旧状态 - 人工回溯:想重放到某个时间点(
savepoint记录位置)
- 升级版本:
与
Checkpoint区别(重点)- 触发:
Checkpoint自动周期(checkpoint.interval);Savepoint手动(用户命令) - 频率:
Checkpoint频繁(故障恢复);Savepoint低频(运维节点) - 粒度:
Checkpoint可增量状态(RocksDB);Savepoint全量快照 - 生命周期/用途:
Checkpoint临时(故障自动恢复,可删);Savepoint持久(运维存档,长期保留,升级/迁移) - 恢复:作业异常自动从最近
Checkpoint恢复(默认);人工flink run -s <savepoint>从Savepointrestore
- 触发:
使用
- 打点(触发存点):
flink savepoint <jobId> [targetDir](-d/--dispose是删除 savepoint);恢复:flink run -s <savepointPath> ...(配合作业同一JobId/代码兼容)
- 打点(触发存点):
协助记忆
- 口诀:“
Checkpoint自动周期、故障恢复用;Savepoint手动、升级/迁移/回滚用——一个保命、一个存档”。
- 口诀:“
进阶思考
- 为什么升级前一定要
Savepoint而不是靠Checkpoint?Checkpoint是为自动故障恢复设计的(可能被清理/过期、依赖配置、不同版本代理可能不兼容);Savepoint是显式存档(全量、指定路径、跨版本设计),改代码/升级后能精确从存档点恢复——运维可预期。
Savepoint恢复条件(容易踩坑)?- 恢复到同一个作业/兼容的算子(
operator ID一致)、依赖默认被state恢复(uid设好)、代码拓扑与Savepoint匹配(uid/哈希)。改代码要保证算子uid稳定,否则恢复失败。
- 恢复到同一个作业/兼容的算子(
- 为什么升级前一定要
扩展信息
- 对比表:
Checkpoint(自动周期/故障恢复/可增量/临时);Savepoint(手动/运维存档/全量/持久)——Flink面试高频对比 - 命令:
flink savepoint <jobId> [dir](打点)、flink stop -s <savepointPath> <jobId>(优雅停止并存点,cancel -s已废弃)、flink run -s <savepoint>(恢复)、--savepoint禁用/删除
- 对比表:
🤔 Hive 是什么?有哪些核心组件?
Hive是把Hadoop数据仓库化的SQL查询引擎:用户写HiveQL(SQL),Hive把它编译成MapReduce/Tez/Spark作业跑在Hadoop上——让不会写Java MapReduce的人用SQL分析大数据。核心组件:Metastore(元数据)、Driver(编译器/优化器/执行器)、HQL解析为 MR 作业。核心:“SQL查Hive表,元数据在Metastore,作业跑Hadoop”。Hive是什么- 数据仓库工具(
Facebook起源):把结构化数据映射成表,SQL查询转MapReduce - 定位:离线大规模数据分析(
ETL/数仓/SQL报表)——SQL-on-Hadoop
- 数据仓库工具(
核心组件
Metastore(元数据服务):存表/库/列/分区等元数据(默认内嵌Derby,生产用MySQL/PostgreSQL),是Hive的“字典”——表和数据的映射关系Driver(驱动/编译器):①解析(Parser把HQL转AST)②语义分析(绑定元数据)③逻辑计划 → 物理计划 ④优化(谓词下推/分区裁剪)⑤生成MapReduce/Tez/Spark作业 ⑥提交执行- 执行引擎:底层由
MapReduce/Tez(更优)/Spark执行(Execution Engine) - 用户界面层:
CLI/Beeline/HiveServer2(JDBC 连接)、ThriftAPI
表类型/HQL 特性
- 管理表/外部表(
External——数据在用户指定路径,Hive不管理其生命周期,DROP外部表不删底层数据)、分区表(partition,按字段分区裁剪)、分桶表(bucket) - 数据格式:
TextFile/Parquet/ORC(列式压缩,快)/Avro;ORC/Parquet性能优
- 管理表/外部表(
存储与执行
- 数据存
HDFS(Hive只管元数据文件位置,数据在HDFS);查询转成后台作业
- 数据存
协助记忆
- 口诀:“
Hive=SQL查数据仓库,Metastore管元数据、Driver编译成MR作业;分区/列式(ORC)提效”。
- 口诀:“
进阶思考
Hive为什么慢(怎么优化)?- 底层是
MapReduce(磁盘、启动开销);优化:①分区裁剪/谓词下推(少扫数据)②列式存储ORC/Parquet③换Tez/Spark执行引擎(比MR快)④SMB Join/Map Join/Bucketing⑤调Reduce数/内存。瓶颈多为全表扫/数据倾斜/引擎性能。
- 底层是
Hive和Spark SQL区别(都是 SQL on Hadoop)?Hive元数据(Metastore)+SQL引擎,底层多MR(慢但代码兼容);Spark SQL基于Spark(内存快 +Catalyst优化器),也能读Hive元数据(HiveMetastore共享)。现代更多用Spark SQL查询(性能),Hive表元数据可复用。
扩展信息
- 生态:
Beeline/HiveServer2(JDBC 客户端)、ThriftServer、HiveMetastore(共享给Spark/Presto)、LLAP(Hive交互式加速) - 数仓分层:
ODS(原始)→DWD(明细)→DWS(汇总)→ADS(应用),Hive/Spark SQL做ETL各层
- 生态:
🤔 HBase 是什么?有哪些核心组件?
HBase是Hadoop生态的分布式宽列/列族存储(Key-Value,非传统列存):海量结构化/半结构化数据的随机实时读写(HDFS做批处理、HBase做单点查询)。核心组件:HMaster(管理/分区)、RegionServer(数据服务)、ZooKeeper(协调/选主),底层存HDFS。核心:“HMaster管分区、RegionServer服务读写、数据在HDFS”。数据模型
- 表 → 行键(
RowKey)+ 列族(Column Family)+ 列限定符(Qualifier)+ 时间戳(Version)+ 值 - 稀疏(未定义的列不占存储)、按
RowKey字典序排序、可多版本——适合海量随机读 + 列动态扩展
- 表 → 行键(
核心组件
HMaster(主节点):管理表/Region分配(RegionServer负载均衡、故障转移)——不直接收发数据;Region分裂由RegionServer触发并执行(flush→split→生成子Region),HMaster只协调分配RegionServer(数据节点):服务一个或多个Region(数据分区),处理客户端读写请求(Get/Scan)、MemStore(内存写)+HFile(磁盘落盘)→HDFS、WAL日志ZooKeeper(协调):HMaster选主(HA)、RegionServer注册/心跳、hbase:meta表位置(客户端路由)HDFS:底层存储(HFile数据持久化)
存储流程(写)
- 客户端 →
ZK找meta→ 定位RegionServer→RegionServer写WAL(日志)+MemStore(内存缓冲)→ 达到阈值刷写(flush)成HFile落HDFS;Region大则分裂(split)
- 客户端 →
适用场景
- 海量(
TB-PB)+ 随机实时读写(时序/日志/用户画像/推荐)——HBase;批处理/离线分析用Hive/Spark
- 海量(
协助记忆
- 口诀:“
HBase= 列式KV随机读;HMaster管分区、RegionServer服务读写、ZK协调、数据在HDFS;写走WAL+MemStore再落HFile”。
- 口诀:“
进阶思考
HBase和HDFS什么关系(覆盖还是并列)?HBase构建在HDFS之上:HBase是把数据组织成KV列式、提供随机读写逻辑层,物理数据块存HDFS。HDFS只提供文件存储(无随机按 key 查),HBase在其上加索引/一致性/实时读写。
HBase为什么读快写也快(和Hive比)?- 写:
WAL(顺序写日志)+MemStore(内存写缓冲)+ 批量刷HFile(顺序写)——随机写变顺序写;读:MemStore内存 +BlockCache缓存 +HFile索引(按RowKey定位,BloomFilter加速)——按 key 直接寻址。Hive是全表扫(MR),HBase是按RowKey点查。
- 写:
扩展信息
RowKey设计:RowKey决定分布(热点考虑,前缀MD5/加盐避免热点)、长度/顺序(前缀匹配查询优化)——HBase性能关键- 运维:
hbase shell(count/scan/get)、Region分裂/合并、RegionServer崩溃恢复(WAL重放)、HmasterUI(16010)、hbasemeta
🤔 HBase 读写流程是怎样的?
HBase读写都先经ZooKeeper定位RegionServer:读走MemStore+BlockCache+HFile(RowKey点查/Scan范围扫);写走WAL(日志)+MemStore(内存缓冲)再异步刷写HFile落HDFS。核心:“写先日志后内存、读按行键定位(内存缓存 + 磁盘HFile)”。定位(路由,读写的公共前提)
- ①客户端访问
ZooKeeper找hbase:meta表的RegionServer位置②读meta表(缓存),得知要读/写的RowKey落在哪个Region/RegionServer③直连对应RegionServer读写(meta会缓存,减少ZK往返)
- ①客户端访问
写入流程
- ①客户端
Put→ 定位到RegionServer②RegionServer写 **WAL(Write-Ahead Log,顺序写日志,先记后写防丢)**③写 **MemStore(内存写缓冲,按RowKey排序)**④MemStore到达阈值 →flush刷写成HFile落HDFS(StoreFile)⑤Region过大 →split分裂为子Region;HFile定期合并(compaction) - 特点:写是顺序日志 + 内存,快;数据先内存后
HFile
- ①客户端
读取流程
- ①
Get(点查)/Scan(范围扫)按RowKey定位RegionServer②先从BlockCache(读缓存) 找 ③再从MemStore(最新未刷写) 找 ④最后查 **HFile(磁盘,RowKey索引 +BloomFilter加速)**⑤多文件版本合并(Read时MVCC),返回最新数据 - 特点:缓存优先(冷数据落盘),
RowKey定位快速
- ①
一致性/可靠性
WAL保证宕机不丢写(RegionServer崩,HMaster拆分其WAL并重分配Region,由新RegionServer重放WAL恢复——HBase 2.x走分布式SplitLog)、MVCC(多版本并发控制)保证读一致性、Region分裂/合并自动
协助记忆
- 口诀:“定位走
ZK+meta;写:WAL→MemStore→flush成HFile;读:BlockCache→MemStore→HFile(按RowKey)”。
- 口诀:“定位走
进阶思考
- 为什么写要先写
WAL再进MemStore?MemStore数据在内存(易丢),宕机内存数据全没——WAL是持久化日志(HDFS落盘),先记日志再写内存,宕机后从WAL重放恢复所有MemStore未刷写的数据(不丢)。顺序写日志快,是“写入必持久化”的关键。
HBase读放大/写放大是什么?- 写放大:数据频繁
flush/compaction(写多份),MemStore阈值/compaction策略影响;读放大:读要查缓存+内存+多个HFile(版本/MVCC),HFile多读就慢。compaction合并文件减读放大、但增写放大——权衡(compaction策略)。
- 写放大:数据频繁
- 为什么写要先写
扩展信息
RowKey与读优化:前缀过滤(scan起止RowKey)、加盐避开热点、Column Family别太多(少量大表查询)- 运维:
Region分裂/合并(split/merge)、major_compact、hbase hbck(一致性修复)、性能参数(BlockCache/MemStore大小)
🤔 HBase RegionServer 故障如何排查与恢复?
RegionServer故障排查:先看ZK/HMaster/进程/日志定位,再按“宕机(HMaster自动接管Region、WAL重放)→ 慢(GC/热点/Region分裂)→ 数据(HFile/WAL损坏)”处理。核心:“宕机靠HMaster+WAL自愈,慢/异常查 GC/热点/磁盘/分裂”。第一步:定位故障类型
HMaster UI/hbase shell看RegionServer状态;ZK看RegionServer是否失联(心跳)- 现象分类:宕机(失联/
Master重分配Region)、慢(Region在但响应慢)、单Region异常、HFile/数据损坏
第二步:宕机排查(数据不丢)
RegionServer挂 →HMaster检测(ZK心跳)→ 把其Region重新分配到其他RegionServer→ 从WAL(该机器HDFS上的日志)重放恢复未刷写数据- 检查:
HMaster日志(RegionServer失联/Region重新上线)、Region是否恢复、网络/磁盘/GC(为何挂) - 重点:
RegionServer宕机不丢数据(WAL+副本),但恢复期间Region短暂不可用
第三步:慢/异常排查
GC停顿:RegionServer大GC(Full GC)卡住——调JVMGC 参数/MemStore/BlockCache(MSLAB/off-heap优化)、GC日志分析- 热点:
RowKey设计不当(单一RowKey集中某RegionServer)——加盐/前缀分散 Region分裂/合并过多:频繁split/compaction占资源——调分裂/合并策略- 磁盘/
HDFS:HFile读写慢(磁盘满/HDFS节点异常)、StoreFile过多
第四步:极端数据损坏
HFile损坏/WAL异常 →HBase 2.x用HBCK2(hbck2,一致性检查/修复;1.x 用hbase hbck)、hbase hfile(查看/校验HFile)、必要时从副本/快照恢复- 数据恢复:
Snapshot(表快照)恢复某表
协助记忆
- 口诀:“
RegionServer挂了HMaster接管 +WAL重放(不丢数据);慢/异常查GC/热点/分裂/磁盘——先宕机自愈、再性能排查”。
- 口诀:“
进阶思考
RegionServer宕机数据会丢吗(为什么)?- 不丢。写数据先落
WAL(HDFS持久化)+MemStore;宕机时MemStore数据虽在内存,但WAL已记录,HMaster重分配Region后从WAL重放回放——数据恢复。这是HBase可靠性的关键(写必日志)。
- 不丢。写数据先落
- 一个
RegionServer挂了会影响多少数据?- 影响它管理的那几个
Region(短暂不可用,Master重分配期间);其他RegionServer不受影响——Region是数据分布单位,故障影响面=该RegionServer的Region。Region分布均衡(Master平衡)让故障影响局部化。
- 影响它管理的那几个
扩展信息
- 相关命令:
hbase shell(status/regioninfo)、HMaster UI(16010)、hbase hbck、snapshot(快照)、RegionSplit/MajorCompact - 优化:
GC调参(HBASE_REGIONSERVER_OPTS)、MSLAB/off-heap BlockCache、RowKey加盐、隔离(RegionServer不同HDFS)
- 相关命令:
🤔 ZooKeeper 在大数据体系中的作用是什么?
ZooKeeper是大数据体系的分布式协调服务:提供一致性、选主、配置、命名、状态同步——HDFS HA(ZKFC选主)、HBase(HMaster选主/meta路由)、YARN(RMHA)、Kafka(控制器选主)都依赖它。核心:“ZK做选主/状态存储/命名/协调,是大数据组件高可用的『脑』”。核心能力
- 选主(分布式锁/Leader 选举):
HA组件(NameNode/HMaster/ResourceManager)经ZK用临时节点 + 序号选主,主挂自动切换 - 配置/状态存储:存集群配置/状态(
HBase meta位置、Kafka分区状态、ZKFC状态),数据节点(znode)持久化 - 命名/服务注册:组件注册(
Register)、发现(ZK谁在哪),客户端经ZK定位服务 - 协调/同步:分布式同步、锁、
Barrier(协同多节点)
- 选主(分布式锁/Leader 选举):
在大数据组件中的具体作用
HDFS HA:ZKFC经ZK监控NameNode心跳、维护Active锁(选主),自动故障切换HBase:HMaster选主(HA)、RegionServer注册、hbase:meta表位置(客户端路由)、分布式SplitLog协调YARN:ResourceManagerHA(ZK选主 + 状态存储)Kafka(经典ZK版,3.x起已迁移KRaft、4.0完全移除ZK):Controller选主(分区 leader 变更)、元数据(broker/topic)Flume/Storm:配置/状态协调(FlumeZK做负载/高可用)
数据模型
- 树状节点(
znode):持久/临时(ephemeral,会话结束自动删)/顺序(sequential)——选主靠临时+顺序节点 - 监听(
watch):节点变更通知(Watcher)——组件实时感知状态变化
- 树状节点(
部署建议
- 奇数节点(3/5/7),过半
Quorum——少数派不能选主/写;部署在独立机器(不与HDFS/HBase同机抢资源)
- 奇数节点(3/5/7),过半
协助记忆
- 口诀:“
ZK做协调:选主(HA)、存状态(meta/配置)、命名注册、watch通知——HDFS/HBase/YARN/Kafka的高可用靠它”。
- 口诀:“
进阶思考
- 为什么大数据 HA 都依赖
ZooKeeper(它这么重要)?- 这些组件需要一主多备 + 自动切换:主挂要让备顶上,且不能“脑裂”(双主)。
ZK用临时节点 + 多数派 +watch提供强一致的选主/锁——组件把“谁是主/状态在哪”交给ZK统一仲裁,就能实现可靠 HA。
- 这些组件需要一主多备 + 自动切换:主挂要让备顶上,且不能“脑裂”(双主)。
ZK的Quorum为什么必须奇数?- 选主/写入需多数派确认(
quorum = n/2+1):奇数节点(3/5/7)能以最少节点获得最大容错——3 挂 1、5 挂 2(偶数 4 挂 1 与 3 相同,浪费一台且不增容错)。所以ZK集群用奇数。
- 选主/写入需多数派确认(
- 为什么大数据 HA 都依赖
扩展信息
- 运维:
zkServer.sh status(看follower/leader)、zkCli.sh(查节点/stat)、4lw(ruok/stat四字命令)、zoo.cfg(server.x对称) - 高可用依赖:凡是
HA(HDFS/HBase/YARN/Kafka)都离不开ZK——ZK本身挂是严重故障(先抓ZK再抓上层组件)
- 运维:
🤔 你们的数据是如何进入 Hadoop 的?数据采集方案?
进入
Hadoop的数据采集按来源分:①日志采集(Flume/Kafka收业务/服务器日志)②数据库同步(Sqoop/DataX/Canal整库或增量)③消息实时(Kafka流进HDFS/HBase)④文件/接口(HDFS上传、FTP/API)。核心:“日志走Flume+Kafka、库走Sqoop/Canal增量、实时走Kafka管道,落地HDFS/Hive”。日志采集(最常见)
Flume:多级采集(source收日志 →channel缓冲 →sink写HDFS/Kafka),Agent分布各服务器Logstash/Filebeat:ELK生态(日志采集 + 解析),适合日志检索- 架构:应用日志 →
Flume Agent(采集)→Kafka(缓冲)→HDFS(落地)/Spark实时
数据库同步(结构化数据)
Sqoop:Hadoop与关系库(MySQL/Oracle)批量导入导出(全量/增量--incremental)——已进入低维护/事实弃用(末版1.4.7),现多被Flink CDC/SeaTunnel/DataX取代,仅作存量/备选Canal:伪装MySQLslave读binlog增量(实时同步到Kafka/HDFS)DataX:阿里开源,多源到多目标(MySQL→HDFS/HBase)通用同步
实时/消息流
Kafka:日志/binlog/点击流先入Kafka(缓冲削峰),消费端落HDFS或Spark/Flink实时计算Kafka Connect/flume-kafka、Spark Structured Streaming/Flink消费Kafka写HDFS/Hive
文件/接口
HDFSCLI(hdfs dfs -put上传文件)/WebHDFS(HTTPPUT,curl调REST)、FTP/API采集导入、OSS/S3对象同步
方案设计要点
- 缓冲削峰(
Kafka)、批量/增量(Sqoop增量、Flume批量)、容错/重试(采集失败重试、Kafka重放)、延迟控制(数据新鲜度:离线T+1、实时秒级) - 数据入
Hive/HDFS分区(按天/小时),便于查询裁剪
- 缓冲削峰(
协助记忆
- 口诀:“日志
Flume+Kafka、库Sqoop增量/Canal实时、流Kafka管道落HDFS/Hive——缓冲+批量+分区,离线在线分层”。
- 口诀:“日志
进阶思考
Kafka在数据接入里起了什么作用(为什么都要它)?- 缓冲削峰(高并发写入不压垮下游)、持久化可重放(数据丢了能回溯)、解耦(采集与消费独立扩展)、多消费(一份数据给实时/离线多路)。几乎所有实时链路都把它当“中转枢纽”。
- 离线(T+1)和实时(秒级)怎么一起做?
- 同一份
Kafka数据,一路消费写HDFS/Hive分区表(离线批处理T+1),一路Flink/Spark Streaming实时计算(秒级)——批流分离,一源多吃。数据先统一进Kafka,再分发给离线/实时两条链。
- 同一份
扩展信息
- 工具:
Flume/Filebeat/Logstash(日志)、Sqoop/DataX/Canal(库)、Kafka(消息)、WebHDFS/HDFSCLI(文件) - 数仓接入:
ODS 层(原始数据入库)→ 清洗进DWD;Hive/Spark SQL做ETL
- 工具:
🤔 大数据集群如何做存储容量规划?副本、存储增长率考量?
Hadoop存储容量规划:可用容量 = 裸容量 ×(1/副本数),并预留 20-30% 缓冲防满,按存储增长率(每日新增 × 保留周期)估算需求。核心:“裸容量除副本数,留 20-30% 缓冲,按日增长×保留期预测,HDFS别到full”。容量估算公式
- 裸容量:所有
DataNode磁盘总和(如 30×16T=480T) - 副本损失:默认副本 3 → 可用 = 裸容量/3(约 160T);副本 2 →/2(更省但容错弱)
- 需考虑元数据/临时文件:
HDFS临时、File移动、replication平衡——实际可用再打折 - 预留缓冲:留 20-30%(防冲到
full拒写、临时峰值、block不均衡、数据倾斜——某节点满)
- 裸容量:所有
存储增长率考量(关键)
- 日增量:每日新增数据量(
GB/TB)——日志/业务增长、采集频率 - 保留周期:数据保存天数(
HDFS保留 N 天,过期清理)——T+1数仓保留、原始/中间/结果层保留不同 - 年化增长:按
月均增长 × 12规划 1-2 年扩容节奏 - 公式:
需要容量 = 日增量 × 保留天数 × 副本系数 / 可用率(留 30% 缓冲则/0.7,留 20% 则/0.8——二选一写明)
- 日增量:每日新增数据量(
数据分层与冷热
- 原始层(
ODS)量大短期留、中间层(DWD/DWS)保留、结果层(ADS)小长期留——不同层不同副本/保留 - 冷数据降副本(
replication=2)/迁移(到低成本存储)、HDFS生命周期(Trash/删除策略)
- 原始层(
容量监控
hdfs dfsadmin -report(容量/DataNode使用率)、HDFS使用率告警——80% 是运维告警阈值(非HDFS内置限制,真正拒写在DataNode磁盘近满触及dfs.datanode.du.reserved预留区)- 关注单节点倾斜(某
DataNode满,balancer均衡)、block冗余
协助记忆
- 口诀:“可用 = 裸容量/副本数,留 20-30% 缓冲;按‘日增量 × 保留天数 × 副本 / 0.7’估算,数据分层/冷热降副本”。
进阶思考
- 副本 3 是不是浪费(能不能降)?
- 副本 3 保高可用(容 2 副本挂不丢);成本敏感可:核心/热数据副本 3、冷/可重建数据副本 2(
replication调低)或EC(纠删码,用较少冗余换容量)。权衡容错与成本。
- 副本 3 保高可用(容 2 副本挂不丢);成本敏感可:核心/热数据副本 3、冷/可重建数据副本 2(
- 存储满了(
HDFS快满)怎么应急?- ①清理过期/临时数据(
Trash/生命周期)②降冷数据副本 ③扩容(加DataNode)④balancer均衡倾斜节点(防单点满)⑤检查数据倾斜/block冗余。别等full(拒写阻断业务),提前 80% 告警。
- ①清理过期/临时数据(
- 副本 3 是不是浪费(能不能降)?
扩展信息
- 相关参数:
dfs.replication(副本)、dfs.datanode.du.reserved(预留)、dfs.blocksize(块大小影响元数据量)、trash配置 - 监控:
hdfs dfsadmin -report、Capacity指标、Ambari/Prometheus(HDFS容量/使用率告警)
- 相关参数:
🤔 Ambari 都监控哪些指标?
Ambari(Hadoop集群管理面板)监控分——注:Ambari已进入维护期、被CDP/Cloudera Manager取代(指标底层 HDP 2.x 用Ganglia/Nagios,2.4+ 用AMS):集群健康(HDFS/YARN/HBase/ZK组件状态、NameNode/ResourceManager状态)、资源(集群 CPU/内存/磁盘/网络)、服务级(DFS容量/DataNode块、YARN队列、HBaseRegion)、主机(DataNode/NodeManager版本、磁盘/负载)。核心:“Ambari看集群服务健康 + 主节点状态 + 主机资源,告警驱动运维”。集群/服务健康(重点)
- 服务状态(
HDFS/YARN/HBase/Hive/ZK/MapReduce是否STARTED/INSTALLED/异常) - 主节点
NameNode/ResourceManager/HMaster健康(Active/Standby、fsimage/editlog状态) HDFS状态:dfsadmin report(Live/DeadDataNode、容量、under replication副本不足)、NameNode内存/元数据
- 服务状态(
资源指标(主机/集群)
- CPU 使用率/负载、内存(used/
swap)、磁盘(使用率/IO)——主机级DataNode/NodeManager - 网络(带宽)、
I/O(磁盘吞吐)
- CPU 使用率/负载、内存(used/
YARN指标- 集群资源(
Vcores/内存总量/已用)、队列(Capacity/Fair队列使用率、pending/running)、作业(Application运行/失败/Killed) NodeManager健康、Container使用
- 集群资源(
HBase/Hive指标HBase:RegionServer状态/Region数、MemStore/BlockCache/compaction、HMaster状态Hive:Metastore状态、HiveServer2会话/HQL执行
告警与运维
Ambari内置告警(服务 down、磁盘满、NameNode切换、ZK节点失联),可配阈值/通知(邮件/webhook)- 配合指标(
Grafana/Prometheus)做趋势/容量预警;告警分级(CRITICAL/MAJOR/MINOR)
协助记忆
- 口诀:“
Ambari看服务健康(HDFS/YARN/HBase/ZK)+ 主节点(NN/RM)+ 资源(CPU/内存/磁盘)+ 队列/Region——告警分级驱动运维”。
- 口诀:“
进阶思考
Ambari和Cloudera Manager/Prometheus分工?Ambari/CM:集群管理 + 服务健康(部署/配置/服务状态/告警)——运营层面;Prometheus+Grafana:细粒度指标采集展示(YARN/HDFS/Node性能曲线)——监控层面。常组合:Ambari/CM管集群、Prometheus看指标趋势。
Ambari监控到NameNode切到Standby意味着什么?NameNode故障切换(HA触发)——可能主节点故障/失联/ZKFC判定,要查原Active为何挂(内存/磁盘/GC/网络),并确认新Active接管正常。这是HDFS高可用关键告警。
扩展信息
- 相关:
Ambari指标可在Grafana展示(Ambari Metrices)、Cloudera Manager(CDH版)、Prometheus+node_exporter - 运维建议:
Ambari告警(服务/主机状态)+Prometheus指标(趋势/容量)+ 日志(HDFS/YARN日志分析)三层监控
- 相关:
🤔 简述 HDFS 读写完整流程?
HDFS读写完整流程(客户端):读先向NameNode查块位置,就近从DataNode并行读;写向NN申请块,客户端直连DataNode管线式写副本(数据不经过NN)。核心:“读走NN查位置 + 直连DN并行读;写NN分配 +DN管线写副本”。读取流程
- ①客户端
open('/file')→ 向NameNode请求(getBlockLocations)②NN返回文件各Block的位置(DataNode列表,含副本)③客户端就近选择DataNode(网络近者优先)④直连DataNode读取Block数据(数据流不经NN)⑤多个Block并行/顺序读,DFSInputStream聚合 ⑥读完关闭;某DN故障自动切换到其他副本(read retry)
- ①客户端
写入流程
- ①客户端
create('/file')向NN创建命名空间元数据(校验权限/目录)②写时经addBlock向NN逐个申请Block,NN返回DataNode列表(按机架感知选 3 个写目标)③客户端与第一个DN建立管线(pipeline),packet分包写数据 →DN1→DN2→DN3(逐副本流水线传输、ack按包回传)④一个Block写完再申请下一Block⑤全部写完,客户端调NN关闭(close),NN提交(文件可见) - 特点:数据流经管线各
DN(副本),不经过NN;DN写失败自动换/调整副本
- ①客户端
关键细节
NameNode只做元数据/调度(不传数据),数据路径客户端↔DataNode——NN轻、吞吐高- 副本管线写:
DN间透明传输(DN1从客户端收再转DN2…),DFSOutputStream管理packet/ack - 副本策略(写时选
DN):机架感知(replica分布不同机架)、就近、HDFS写副本的默认放置策略
协助记忆
- 口诀:“读:
NN问位置、就近DN并行读(DN挂换副本);写:NN分配DN、DN管线写 3 副本——元数据走NN、数据走DN”。
- 口诀:“读:
进阶思考
- 为什么读要并行读多个块?
- 大文件切成多个
Block(128M)分布在多个DataNode,客户端DFSInputStream对多个块并行读取——多个DN同时供数据,读吞吐成倍提升(带宽叠加)。这就是HDFS高吞吐的关键之一。
- 大文件切成多个
- 写文件时某
DataNode挂了怎么办?- 管线中断:客户端检测到写失败,
NN重新分配副本(pipeline更新),副本不足先降级写(short-circuit),其余副本继续;恢复后补齐副本(replication)。写不丢(副本容错),但性能/进度受影响。
- 管线中断:客户端检测到写失败,
- 为什么读要并行读多个块?
扩展信息
- 命令:
hdfs dfs -put(写)、-cat/-get(读)、-ls(列表)、hdfs fsck(块检查)、dfsadmin -safemode(安全模式) - 性能:读写缓冲、
block大小、DataNode数量/网络、副本数影响(多/快但占用大)
- 命令:
🤔 HDFS 文件上传、下载、删除和修改的底层机制?
HDFS操作底层机制:上传=管线写块副本;下载=按块并行读;删除=移Trash(可恢复)+ 延迟删块;修改(写):HDFS不支持随机修改(追加append有限支持、改内容需重写文件),元数据被NN记录、数据分布DN。核心:“上传写块、下载读块、删除进Trash、HDFS只追加不随机改”。上传(写)底层
hdfs dfs -put→ 客户端向NN申请块 →DN管线写副本(如前述)——数据切块、副本分布DN、元数据NN记录- 写时流式(
DFSOutputStream,packet分包/ack确认),块满申请新块
下载(读)底层
hdfs dfs -get/cat→NN查块位置 → 客户端就近并行读DN(多块并行、DFSInputStream聚合)→ 合并成完整文件
删除底层
hdfs dfs -rm→ 文件移入Trash(回收站) 可恢复(-rm先删到Trash)——注意fs.trash.interval默认 0=禁用Trash,需显式配置开启(企业发行版常默认启用)Trash过期后真正删除:NN更新元数据(删除文件/块映射),块被标记删除,DataNode后台实际删除块(block删除由DN异步执行)-rm -skipTrash(跳过Trash直接删);回收站防误删
修改底层(关键:
HDFS不支持随机写)HDFS语义“一次写、多次读”——不支持随机覆盖/修改文件中间内容(hdfs无random write)- 支持的修改:追加(
append,-appendToFile尾部追加新数据,dfs.support.append控制、Hadoop 2.x默认true)、重命名(mv元数据变更)、改副本数(setrep只动元数据、触发副本调度,不碰内容)、改权限(chmod) - 所以要改文件内容 → 重写(
overwrite新文件覆盖)或append;这是HDFS与普通文件系统最大差异
协助记忆
- 口诀:“上传管线写块、下载并行读块、删除进
Trash可恢复;HDFS只追加不随机改——改内容=重写/append”。
- 口诀:“上传管线写块、下载并行读块、删除进
进阶思考
- 为什么
HDFS不支持随机修改(设计取舍)?- 为高吞吐/海量而设计:随机写要定位/维护块内偏移(复杂、冲突);而“一次写多次读”适合批处理(
MapReduce/Hive)场景,避免并发写一致性难题。追加/重写已够离线大数据(数据不可变、追加日志类)。
- 为高吞吐/海量而设计:随机写要定位/维护块内偏移(复杂、冲突);而“一次写多次读”适合批处理(
- 删除文件为什么进
Trash而不是马上删?- 防误删(运维/批处理脚本删错能恢复);
Trash过期(可配置天数)后才真正删块,给用户“后悔药”。违反保留期的紧急删除可用-skipTrash(谨慎)。
- 防误删(运维/批处理脚本删错能恢复);
- 为什么
扩展信息
- 相关命令:
-put/-get/-rm/-appendToFile/-mv/-chmod/-setrep、fs.trash.interval/fs.trash.checkpoint.interval(回收站配置) Trash配置:core-site.xml的fs.trash.interval(分钟,0=禁用)、fs.trash.checkpoint.interval(清理检查周期)
- 相关命令:
🤔 HDFS DataNode 坏块产生原因有哪些?如何修复?
DataNode坏块原因:磁盘物理损坏/坏道、DataNode异常宕机/进程崩溃、读写中断(网络/校验失败导致CRC校验不过)、HDFS块校验(checksum)不一致。修复:HDFS自动——检测到坏块 → 从健康副本复制补齐(replication纠错);配合hdfs fsck检查、DataNode报bad块让NN标记、必要时换盘/重新复制。核心:“坏块HDFS自动用副本自愈,fsck检查 + 换盘兜底”。产生坏块的原因
- 磁盘故障:物理坏道/扇区损坏/磁盘彻底损坏(
bad blocks) DataNode宕机:进程崩溃/JVM异常——结果是其块副本缺失/under-replicated(非“坏块corrupt block”,NN调度副本补齐)- 校验失败:读写时
CRC32校验不一致(数据损坏/传输错误,checksum不一致是损坏的表现而非成因)——DataNode读取验checksum - 网络/写入中断:写
block时网络故障/写入不完整(部分写),块被视为坏 - 低版本/配置:
DataNode重启、block与NN记录不一致
- 磁盘故障:物理坏道/扇区损坏/磁盘彻底损坏(
HDFS自动修复机制(副本容错)- ①
DataNode定期向NN报告块(block report),NN对比副本数(expected replication)——副本不足则调度补充 - ②某
DataNode校验失败/坏块 → 上报NN→NN标记该block副本损坏 → 其他健康block副本补上(replicate),坏副本被替换 - ③
DataNode宕机 →NN判dead→ 其块副本在健康节点复制补齐(under replication修复) - 结果:只要副本 ≥1 健康,
HDFS自动复制补齐,数据不丢(副本 3 容 2 坏)
- ①
人工排查/修复
hdfs fsck / -files -blocks:检查文件/块完整性(坏块/缺失副本/under replicated)hdfs fsck / -files -blocks -racks(块分布)、-list-corruptfileblocks(列损坏块)hdfs dfsadmin -report:看DataNode健康/坏盘、hdfs dfsadmin -safemode(安全模式排查)- 坏盘/坏块处理:坏
DataNode磁盘 → 换盘(datanode下线、新盘)或hdfs移除该数据节点(decommission) DataNode重启恢复(临时故障)、fsck修复(-replicate/-delete可选项)
协助记忆
- 口诀:“坏块多因磁盘坏/宕机/校验失败——
HDFS靠副本自动自愈(fsck检查、NN补副本);人工换盘/下线坏节点”。
- 口诀:“坏块多因磁盘坏/宕机/校验失败——
进阶思考
- 为什么
HDFS有副本,坏块数据还能恢复?- 副本 3 分布在多个
DataNode,一个副本坏,其他健康副本在——NN检测倒数(replication不足 3)后,从健康副本复制补齐到健康节点,坏副本被剔除。只要不超容错上限(1-2 副本坏),数据不丢自动修复。
- 副本 3 分布在多个
- 发现坏块高频了(经常 fsck 有坏块)要警惕什么?
- 可能是磁盘老化/大面积坏道(硬件级别),或
DataNode不稳定(内存/JVM/网络)、坏盘未换——需排查磁盘健康(smartctl)、DataNode日志、NN元数据一致性,及时换盘/下线。频繁坏块是硬件/稳定性的预警信号。
- 可能是磁盘老化/大面积坏道(硬件级别),或
- 为什么
扩展信息
- 相关命令:
hdfs fsck(完整性)、hdfs dfsadmin -report(数据节点)、hdfs dfsadmin -metasave、smartctl(磁盘健康) - 预防:磁盘监控(
SMART/RAID)、DataNode巡检、副本数合理、DataNode日志(datanode.log)检查、备份
- 相关命令:
🤔 YARN 集群资源充足,但 MapReduce 任务调度很慢,如何排查?
资源充足但任务调度慢:先看
YARN调度器(队列/DAG 依赖/资源隔离)→ 再看作业(Map/Reduce数量、数据倾斜、Shuffle量)→ 最后看NameNode/网络/日志。常见:小文件多(Map任务数爆炸)、数据倾斜(单Map拖尾)、Reduce数不合理、队列/资源配额(AM排队)、InputSplit切片太大/小。核心:“任务多/倾斜/队列受限/切片问题——看JobHistory/RM UI定位”。第一步:确认“慢”在哪一层
ResourceManager UI看作业状态(Submitted/Running):是排队(资源没给/队列受限)还是运行慢(任务执行慢)YARN日志/JobHistory(jobhistoryserver)看作业Map/Reduce阶段耗时- 区分:调度慢(作业迟迟不跑/排队)vs 执行慢(跑了但单任务慢)——排查方向不同
第二步:排查“调度/排队”
- 队列资源受限:队列
Capacity/Fair配额不够(yarn queue -status看used/pending),作业AM排队——调队列配额/优先级 AM启动限制:yarn.scheduler.maximum-am-resource-percent(AM资源占比上限,AM启动慢多因它);yarn.scheduler.maximum-allocation-mb/-vcores约束所有容器(非AM专属)- 资源碎片/阻塞:
Container请求但无足够连续资源(YARN资源粒度/NodeManager配置)、max-am-resource-percent NodeManager资源:节点vcores/内存上限(yarn.nodemanager.resource.memory-mb/cpu-vcores)
- 队列资源受限:队列
第三步:排查“作业执行慢”
- 小文件多:大量小文件 →
Map任务数爆炸(InputSplit每文件一个),调度/启动开销大——CombineFileInputFormat/归档(Har)/合并小文件 - 数据倾斜:某
Key数据多 → 单个Map/Reduce处理慢(拖尾)——combiner/采样/自定义分区/加盐 Reduce/Map数量不当:Reduce数(mapreduce.job.reduces)过少Reduce慢、过多调度开销;块大小影响Map数Shuffle量大:Reduce拉取Map输出多/慢——Shuffle占网络/磁盘,combiner减传输、speculative推测执行NameNode/HDFS瓶颈:元数据/块读写慢(NN内存/磁盘)、DataNode磁盘 IO 慢
- 小文件多:大量小文件 →
第四步:看日志/工具
JobHistory(mapreduce作业耗时)、RM/NM日志、Map/Reducetask 耗时(Task进度)、hdfs fsck(块健康)YARNWeb UI(8088)看队列/Container/AM、JobTracker(旧)
协助记忆
- 口诀:“先看调度(排队?队列配额/
AM限制)再看执行(小文件/倾斜/Reduce数/Shuffle)——队列限就调配额、任务多/斜就优化作业”。
- 口诀:“先看调度(排队?队列配额/
进阶思考
- 小文件多为什么让调度变慢(不只任务多)?
- 每个小文件一个
InputSplit→ 一个Map任务,任务数成千上万;YARN调度各Map到Container(启动JVM、分配资源)开销巨大,且HDFS读小文件元数据次数多(NameNode压力)——调度/启动开销淹没计算。治理:合并小文件/SequenceFile/归档/CombineFileInputFormat。
- 每个小文件一个
- 数据倾斜怎么判定(常见算法)?
JobHistory看各Map/Reduce耗时(有个别 task 耗时远超平均→倾斜);或Map输出Key分布(Counter/采样看某Key占比高)。处理:combiner(Map端预聚合)、随机加盐(倾斜Key分桶)、自定义分区(TotalOrderPartitioner)。
- 小文件多为什么让调度变慢(不只任务多)?
扩展信息
- 参数:
mapreduce.job.reduces(Reduce数)、mapreduce.input.fileinputformat.split.minsize(切片)、yarn.scheduler.capacity.root.queues(队列)、yarn.nodemanager.resource.memory-mb(节点资源) - 工具:
YARN Web UI、JobHistory、Ganglia/Ambari(资源曲线)、日志(yarn logs -applicationId)
- 参数:
🤔 Spark 作业发生 OOM 内存溢出,如何排查与调优?
SparkOOM分两类:Executor堆内存溢出(ExecutorOOM)与DriverOOM。排查:先看是哪个阶段 OOM(Map/Shuffle/Reduce、collect)→ 再归因(数据倾斜、Shuffle量大、缓存过多、分区小/聚合大、collect到Driver大结果)→ 调优(executor内存/并行度/Shuffle分区/数据倾斜避让)。核心:“OOM多因聚合/Shuffle/cache/collect 放大内存——定位阶段、治倾斜、调资源与分区”。第一步:定位 OOM 在哪
Spark UI(executor日志/Accumulator)看task/stage阶段;OOM常在:groupByKey(无预聚、全量Shuffle到内存)、aggregateByKey(仅聚合中间值极大时)、join(大Shuffle)、collect/take到Driver、cache/persist大RDD- 区分:
Executor OOM(executor 堆不够)vsDriver OOM(collect/广播变量/Driver 侧聚合)
第二步:归因
- 数据倾斜:某
Key数据巨多 → 单task处理超大(聚合/Shuffle分区不均)——最常见 Shuffle分区数不足:spark.sql.shuffle.partitions(SQL)/defaultParallelism少 → 单task数据多、聚合内存大cache/persist过度:把大量/大RDD缓存,占满内存——缓存策略不当- 宽依赖/聚合:
groupByKey(全量Shuffle到内存)比reduceByKey(预聚合)耗内存 collect大结果:collect()全量拉回Driver(大数据量爆内存)- 单条记录大:大字段(
String/数组)堆积(Row内存)
- 数据倾斜:某
第三步:调优(对症)
- 资源:调
spark.executor.memory/--executor-memory、spark.executor.cores、spark.driver.memory(DriverOOM)、spark.memory.offHeap.enabled/spark.memory.offHeap.size(堆外内存,需开启才生效) - 数据倾斜治理:预聚合(
reduceByKey/combineByKey替代groupByKey)、加盐(倾斜 Key 加随机前缀分桶)、广播小表(broadcast join替代大join)、重分区(repartition/coalesce均衡) Shuffle分区:spark.sql.shuffle.partitions调大(并行度↑、单任务数据↓)、spark.default.parallelismcache策略:persist用MEMORY_AND_DISK(溢出到磁盘)、只缓存复用多次的小/中型RDD、unpersist释放- 避免
collect:用show/take/write(输出到存储)替代全量collect;foreach分区处理 - 序列化:
kryo序列化、compress,减少对象内存
- 资源:调
第四步:监控/日志
Spark UI(stage/task内存/Shuffle量)、executor日志(OutOfMemory/GC)、event logjstat/GC日志(GC频繁/Full GC说明内存紧)
协助记忆
- 口诀:“先定位阶段(聚合/
Shuffle/collect/cache),再归因(倾斜/分区少/缓存多),对症:加资源、治倾斜(reduceByKey/加盐/广播)、调分区、慎collect”。
- 口诀:“先定位阶段(聚合/
进阶思考
groupByKey为什么比reduceByKey更易 OOM?groupByKey把每个Key的所有值原样Shuffle到内存(Iterable),无预聚合;reduceByKey在Map端先预聚合(合并部分值)再Shuffle,传输/内存少。大数据聚合用reduceByKey/combineByKey(带预聚合),避免groupByKey。
Shuffle分区不足为什么导致 OOM(而不是慢)?Shuffle分区数决定每个Reduce分区处理的数据量——分区少,单reduce task数据量大、聚合进内存爆;分区多则单任务数据小(内存安全)但任务多。spark.sql.shuffle.partitions设大(如200-2000)防单分区过大,与数据量匹配。
扩展信息
- 参数:
spark.executor.memory/cores/driver.memory、spark.sql.shuffle.partitions、spark.memory.fraction(堆内份额)、spark.serializer=KryoSerializer、spark.broadcast.blockSize - 治理手段:
reduceByKey/aggregateByKey(预聚合)、broadcast join、加盐、repartition、persist(MEMORY_AND_DISK)、AQE(Spark 3自适应)
- 参数:
🤔 Hive 查询慢,如何分步排查优化?
Hive查询慢排查:先看执行计划(EXPLAIN)和是哪个阶段慢(Map/Reduce/Join/聚合)→ 再归因(全表扫/数据倾斜/Reduce数不当/Map任务少/无谓词下推)→ 对症(分区裁剪/列式存储/换Tez/Spark/Map Join/SMB Join/调Reduce数)。核心:“EXPLAIN定位 + 治全表扫/倾斜/Join,换引擎减 MR 开销”。第一步:看执行计划/定位慢点
EXPLAIN <query>看执行计划(Map/Reduce/Join阶段、数据流转);EXPLAIN EXTENDED看细节- 看各阶段耗时(
Tez/SparkUI 或Hive日志):是Map慢(扫/过滤)、Shuffle(倾斜)、Reduce(聚合)还是Join - 看
Hive UI/Azkaban(作业耗时、Map/Reduce数)
第二步:定位常见瓶颈
- 全表扫:缺分区条件/
WHERE未过滤分区列——主因是表未分区或查询没按分区列过滤(谓词下推默认开启、ORC/Parquet自动生效,非“没启用”);用分区裁剪少扫数据 - 数据倾斜:
Join/Group By某Key数据多(单Reduce慢)——hive倾斜优化(hive.optimize.skewjoin/GroupBymap端聚合) Reduce数不当:mapreduce.job.reduces太少(Reduce慢)/太多(启动开销);hive.exec.reducers.bytes.per.reducer(每 reducer 处理字节)Map任务少:大文件块大/split size大 →Map数少(单Map慢;mapred.map.tasks只是上限提示不真增Map数)——调小mapred.max.split.size/合并小文件Join大表:大表Join大表(Shuffle慢)——Map Join(小表广播)/bucketing join/SMB- 无
Map端聚合:Group By没开hive.map.aggr=true(Map端预聚合减Reduce压力)
- 全表扫:缺分区条件/
第三步:优化(对症)
- 分区裁剪/谓词下推:表用分区(
partition)+ 查询WHERE分区列——不扫无关分区;ORC/Parquet列式(读所需列、谓词下推) - 列式+压缩:
ORC/Parquet(比TextFile快、省空间),ZSTD/Snappy压缩 - 换执行引擎:
hive.execution.engine=tez(DAG、内存,比MR快)或spark——大幅提速 Join优化:Map Join(hive.auto.convert.join=true,小表广播内存join)、Bucketing+SMB Join、sort-merge- 聚合优化:
hive.map.aggr=true(Map端预聚)、hive.groupby.skewindata(倾斜分摊)、distinct优化 - 小文件合并:输入小文件多 →
CombineHiveInputFormat/merge(减少Map数);Reduce数匹配 - 其他:分桶(
bucket,join/抽样快)、CBO(hive.cbo.enable=true统计驱动优化)、limit/采样(先小批看数据)
- 分区裁剪/谓词下推:表用分区(
第四步:数据侧
- 看数据是否倾斜(
group by的Key分布)、字段类型(int vs string)、NULL处理(null也会成为Key,hive倾斜优化)
- 看数据是否倾斜(
协助记忆
- 口诀:“先
EXPLAIN定位 → 治全表扫(分区/列式)、倾斜(map聚合/skewjoin)、Reduce数、Join(map join/bucket)——换Tez/Spark提效大头”。
- 口诀:“先
进阶思考
- 为什么换
Tez/Spark引擎能大幅提速(核心)?MapReduce每阶段落磁盘(HDFS),多阶段就多次磁盘IO+ 作业启动开销;Tez用DAG(Map-Map-Reduce链式,中间不强制落盘、AM调度),Spark内存计算——减少磁盘往返,大数据量下快数倍。引擎是Hive提速最快一招。
- 数据倾斜在
Hive里最典型的表现与处理?- 表现:
Group By/Join阶段单个Reduce/Task卡很久,其他Reduce早结束——某Key数据量远大于平均。处理:Map端预聚(map.aggr)、skewindata(两阶段倾斜分摊)、skewjoin(倾斜 Key 单独处理)、加盐/广播小表。
- 表现:
- 为什么换
扩展信息
- 参数:
hive.execution.engine(mr/tez/spark)、hive.map.aggr、hive.auto.convert.join、hive.optimize.skewjoin、mapreduce.job.reduces、hive.cbo.enable - 工具:
EXPLAIN、Tez/Spark UI、HiveServer2日志、Azkaban(调度作业耗时)、Grafana(集群资源)
- 参数: