在分布式存储领域Hadoop分布式文件系统(HDFS)作为Hadoop生态系统的核心存储组件其高可用性(HA)设计一直是程序员们关注的焦点。为什么我们需要高可用在Hadoop 2.0之前HDFS架构中存在一个著名的“单点故障”隐患——NameNode。NameNode作为HDFS的“大脑”负责维护文件系统的元数据目录树、文件块映射等。在早期架构中整个集群只有一个NameNode。一旦它因为硬件故障、内存溢出或网络问题宕机整个HDFS集群将陷入瘫痪所有数据虽然还在磁盘上但无法被访问。对于追求7×24小时不间断服务的企业级应用来说这是不可接受的。因此Hadoop高可用架构应运而生。HDFS高可用的核心架构Hadoop HA的核心思想非常直观冗余。既然一个NameNode会挂那我们就部署两个——一个主用一个备用。但在分布式系统中简单的“主备复制”远比你想象的要复杂。Hadoop HDFS的HA架构主要解决了三个核心难题元数据同步、故障检测与自动切换、以及最棘手的“脑裂”问题。1. 双机热备Active与Standby在HA架构中我们部署两个NameNodeActive NameNode负责处理所有客户端的读写请求是集群的“真命天子”。Standby NameNode处于热备状态它不处理客户端请求但它的核心任务是实时同步Active节点的元数据确保自己随时准备好接管工作。2. 共享存储JournalNodesStandby节点如何知道Active节点做了什么操作这就引入了JournalNode集群。当Active NameNode接收到修改元数据的请求如创建文件时它会先将操作日志持久化写入到JournalNode集群中。Standby NameNode则时刻监控着JournalNode一旦发现有新的日志写入它就会立即读取并应用到自己的内存文件系统中。通过这种机制Standby节点始终与Active节点保持着毫秒级的数据同步。3. 故障转移的指挥官ZKFC谁来监控NameNode是否挂了谁来执行切换答案是ZKFC。ZKFC是一个运行在NameNode所在机器上的进程它主要干两件事健康监控定期向NameNode发送心跳检查其是否健康。自动故障转移如果Active NameNode挂了ZKFC会感知到并通过ZooKeeper发起选举将Standby节点提升为Active。分布式系统的噩梦脑裂与 fencing这是面试中最高频的考点也是理解HA深度的关键。假设一种极端情况Active NameNode并没有挂但是它和ZooKeeper之间的网络断了网络分区。此时ZKFC认为Active挂了于是触发切换让Standby变成了新的Active。现在的局面是旧的Active认为自己是老大新的Active也认为自己是老大。如果两者同时向DataNode写入数据元数据就会彻底混乱。这就是脑裂。Hadoop通过Fencing机制来解决这个问题。当发生切换时新上任的Active NameNode会通过 fencing 机制“干掉”旧节点。常见的手段包括切断电源通过IPMI远程管理卡强制关闭旧节点的电源。切断网络通过防火墙规则隔离旧节点。共享存储锁利用JournalNode的共享存储锁拒绝旧节点的写入请求。只有确保旧节点彻底“闭嘴”新节点才会开始服务从而保证了数据的一致性。此外不仅仅是HDFSYARN的HA除了存储层计算资源管理层YARN同样存在单点故障——ResourceManager。YARN的HA原理与HDFS类似也是采用Active/Standby架构。但它略有不同的是它通常利用ZooKeeper来维护ResourceManager的状态。当Active RM宕机时ZooKeeper会触发选举Standby RM会接管服务并从状态存储中恢复之前运行任务的信息确保计算任务不中断。