分布式计算框架实验(四) hadoop高可用搭建及mapreduce高可用配置

发布于:2025-04-16 ⋅ 阅读:(26) ⋅ 点赞:(0)

一、实验目的

  1. 掌握Hadoop完全分布式集群的搭建方法,理解多节点协作机制。
  2. 实现Hadoop高可用(HA)架构,消除NameNode和ResourceManager的单点故障。
  3. 配置MapReduce的高可用参数,优化资源管理与容错机制。
  4. 验证集群功能,包括进程状态监控、Web界面访问及WordCount实例运行。

二、实验坏境

类别

配置/版本

虚拟机软件

VMware Workstation 17

操作系统

CentOS 7.9

JDK

1.7.0_67

Hadoop

2.6.5

Shell

FinalShell

ZooKeeper

3.4.6

三、实验内容

任务1:hadoop完全分布式搭建

  1. 配置SSH免密登录:使用ssh-keygen -t rsa -b 4096命令创建密钥,再运行ssh-copy-id l20223613-02,可以获取另外一台虚拟机的密钥,这样可以实现ssh免密登录。
  2. 关闭防火墙通过指令systemctl stop firewalld,systemctl disable firewalld两条指令关闭防火墙,接着使用vim文本编辑工具:vim /etc/sysconfig/selinux,将文件里的SELINUX设置为:disabled。
  3. 设置时区:通过指令date可以查看系统的时间信息,然后通过指令timedatectl set-timezone Asia/Shanghai 将时间修改为上海时区,再通过指令:ntpdate -u ntp.aliyun.com同步时间并开启ntp服务,最后通过命令:systemctl start ntpd和systemctl enable ntpd设置开机自启。
  4. 配置主机名映射:首先找到自己电脑下的hosts,将自己主机名和主机的ip地址填写在文件里面,hosts文件在C:\Windows\System32\drivers\etc目录下面。接着通过vim /etc/hosts命令修改虚拟机里面的hosts文件,修改内容同前面一样。
  5. jdk安装,配置环境变量打开软件FinalShell,通过主机名和密码连接自己的主机,上传jdk文件到虚拟机,通过指令rpm -ivh jdk-7u67-linux-x64.rpm指令解压jdk,解压完成之后可以通过whereis java指令查看java文件夹解压到哪个位置,方便后面配置环境变量。接着运行指令:vim + /etc/profile,在文件最后加上:

export JAVA_HOME=/usr/java/jdk1.7.0_67

PATH=$PATH:$JAVA_HOME/bin

保存之后,执行命令. /etc/profile时文件生效,接着进入验证阶段,输入:以下三个指令

java -version 验证是否配置好java

javac -version 验证java编译文件是否配置好

jps 查看进程,验证jdk有没有完全配置好

        6.部署hadoop坏境:打开软件FinalShell连接主机,然后上传hadoop-2.6.5.tar.gz文件到虚拟机里面,通过指令:tar -xvf hadoop-2.6.5.tar.gz -C /export/server/指令解压到export/server/目录下,通过指令:vim /etc/profile进入文件配置Hadoop环境变量,在文件后面加上:

export HADOOP_HOME=/export/server/hadoop

export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

保存之后,执行命令. /etc/profile时文件生效,接着进入最重要的一步,修改配置文件(以我自己的例子为例):

①配置workers文件(把自己的虚拟机主机名写在这个文件里面):

l20223613-01
l20223613-02
l20223613-03
l20223613-04
l20223613-05

②配置core-site.xml文件:

    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://l20223613-01:8020</value>
</property>
<property>
     <name>hadoop.tmp.dir</name>
     <value>/export/server/hadoop/ha</value>
</property> 
    <property>
        <name>io.file.buffer.size</name>
        <value>131072</value>
    </property>

③配置hdfs-site.xml文件:

   <property>
        <name>dfs.datanode.data.dir.perm</name>
        <value>700</value>
</property>
<property>
      <name>dfs.replication</name>
      <value>3</value>
</property>
<property>
      <name>dfs.namenode.secondary.http-address</name>
      <value>l20223613-01:50090</value>
</property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/data/nn</value> //nn是放namenode数据的文件夹
</property>
    <property>
        <name>dfs.namenode.hosts</name>
<value>l20223613-01,l20223613-02,l20223613-03,l20223613-04,l20223613-05</value>  
    </property>
    <property>
        <name>dfs.blocksize</name>
        <value>268435456</value>
    </property>
    <property>
        <name>dfs.namenode.handler.count</name>
        <value>100</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/data/dn</value> //dn是放datanodes数据的文件夹
    </property>

④配置hadoop-env-sh文件:

exportJAVA_HOME=/usr/java/jdk1.7.0_67
export HAD00P_HOME=/export/server/hadoop
Export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export HADOOP_LOG_DIR=$HADOOP_HOME/logs

        以上四个文件配置后运行命令:hadoop namenode -format格式化namenode,接着输入命令:start-dfs.sh启动集群,输入指令jps,若显示了DataNode,NameNode,SecondaryNameNode,Jps四个而且在浏览器界面能够看到三个活结点则hadoop部署成功。

任务2:hadoop高可用搭建

1.修改配置hdfs-site.xml文件(在全分布的基础上添加):

<!-- 高可用核心配置 -->
    <property>
    	<name>dfs.replication</name>
    	<value>3</value>
    </property>
    <property>
  	<name>dfs.nameservices</name>
  	<value>mycluster</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/data/nn</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/data/dn</value>
    </property>
    <property>
  	<name>dfs.ha.namenodes.mycluster</name>
  	<value>nn1,nn2</value>
    </property>
    <property>
  	<name>dfs.namenode.rpc-address.mycluster.nn1</name>
  	<value>l20223613-01:8020</value>
    </property>
    <property>
  	<name>dfs.namenode.rpc-address.mycluster.nn2</name>
  	<value>l20223613-02:8020</value>
    </property>
    <property>
  	<name>dfs.namenode.http-address.mycluster.nn1</name>
  	<value>l20223613-01:50070</value>
    </property>
    <property>
  	<name>dfs.namenode.http-address.mycluster.nn2</name>
  	<value>l20223613-02:50070</value>
    </property>
<!-- JournalNode配置 -->
    <property>
  	<name>dfs.namenode.shared.edits.dir</name>
  	<value>qjournal://l20223613-01:8485;l20223613-02:8485;l20223613-03:8485/mycluster</value>
    </property>
    <property>
  	<name>dfs.journalnode.edits.dir</name>
  	<value>/export/server/hadoop/ha/journalnode</value>
    </property>
<!-- 故障转移配置 -->
    <property>
  	<name>dfs.client.failover.proxy.provider.mycluster</name>
  	<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
    <property>
  	<name>dfs.ha.fencing.methods</name>
  	<value>sshfence</value>
    </property>
    <property>
  	<name>dfs.ha.fencing.ssh.private-key-files</name>
  	<value>/root/.ssh/id_dsa</value>
    </property>
    <property>
  	<name>dfs.ha.automatic-failover.enabled</name>
  	<value>true</value>
    </property>
    <property>
  	<name>dfs.journalnode.edits.dir</name>
  	<value>/export/server/hadoop/ha/journalnode</value>
    </property>

2.修改core-site.xml文件(在全分布的基础上添加):

 <property>
        <name>fs.defaultFS</name>
        <value>hdfs://mycluster</value>
    </property>
    <property>
    	<name>hadoop.http.staticuser.user</name>
    	<value>root</value>
    </property>
    <property>
    	<name>hadoop.proxyuser.root.hosts</name>
    	<value>*</value>
    </property>
    <property>
    	<name>hadoop.proxyuser.root.groups</name>
    	<value>*</value>
    </property>
    <property>
        <name>io.file.buffer.size</name>
        <value>131072</value>
    </property>
    <property>
	<name>fs.trash.interval</name>
	<value>1440</value>
    </property>
    <property>
	<name>fs.trash.checkpoint.interval</name>
	<value>120</value>
    </property>
    <property>
  	<name>hadoop.tmp.dir</name>
  	<value>/export/server/hadoop/ha</value>
    </property>
    <property>
  	<name>ha.zookeeper.quorum</name>
  	<value>l20223613-01:2181,l20223613-02:2181,l20223613-03:2181</value>
    </property>

3.将修改后的配置文件分发到所有节点:

scp core-site.xml hdfs-site.xml l20223613-02:`pwd`
scp core-site.xml hdfs-site.xml l20223613-03:`pwd`
scp core-site.xml hdfs-site.xml l20223613-04:`pwd`

4.Zookeeper集群搭建:

(1)安装与配置: 首先上传Zookeeper-3.4.6文件通过finalshell上传到l20223613-02节点主机,然后解压缩到/export/server目录:tar -xzvf zookeeper-3.4.6.tar.gz -C /export/server/

(2)配置zoo.cfg文件:进入配置目录,复制模板文件并编辑。 进入zookeeper目录的conf目录,使用命令合并文件:mv zoo_sample.cfg zoo.cfg,然后修改zoo.cfg文件配置,这里需要找到dataDir行,修改路径dataDir如下,在下面添加如图所示的代码:

server.1=l20223613-01:2888:3888
server.2=l20223613-02:2888:3888
server.3=l20223613-03:2888:3888
dataDir=/export/server/zookeeper-3.4.6/zk

接着分发配置好的zookeeper-3.4.6文件:

scp -r /export/server/zookeeper-3.4.6 l20223613-01:/export/server/

(3)创建数据目录和myid文件:命令行输入(三台主机都要输入命令):

mkdir -p /export/server/zookeeper-3.4.6/zk //三台主机都输入
echo 1 > /export/server/zookeeper-3.4.6/zk/myid //主机20223613-01,对应zoo.cfg文件中的server.1
echo 2 > /export/server/zookeeper-3.4.6/zk/myid //l20223613-02
echo 3 > /export/server/zookeeper-3.4.6/zk/myid //l20223613-03

(4)配置环境变量:添加环境变量后运行配置文件,并分发:

#环境添加代码
export ZOOKEEPER_HOME=/export/server/zookeeper-3.4.6/bin
PATH=$PATH:$ZOOKEEPER_HOME
#分发文件
scp /etc/profile l20223613-01:/etc/
scp /etc/profile l20223613-03:/etc/
#生效
source /etc/profile

5.启动Hadoop高可用集群:

(1)确保每台主机启动zookeeper,启动命令:zkServer.sh start

(2)启动JournalNode(每台主机),启动命令:hdfs –-daemon start journalnode

(3)格式化HDFS文件系统,格式化命令:hdfs namenode -format

(4)同步NameNode,同步命令:scp -r /data/nn l20223613-02:/data/nn

(5)格式化ZKFC,格式化命令:hdfs zkfc -formatZK

    (6)启动HDFS:start-dfs.sh,然后jps查看进程信息

    6.测试Hadoop高可用集群的主备切换功能:

    (1)停止 hadoop1的 namenode :hdfs –-daemon stop namenode

    (2)可以看出虚拟机l20223613-01的NameNode已经无法访问,虚拟机l20223613-02的NameNode由standby状态变更为active状态,因此说明HDFS中的NameNode实现了主备切换,具体结果见五、实验结果

    任务3:mapreduce高可用配置

    1.修改配置mapred-site.xml文件:

    <property>
    	<name>mapreduce.framework.name</name>
    	<value>yarn</value>
     </property>
    <property>
    	<name>mapreduce.jobhistory.address</name>
    	<value>l20223613-01:10020</value>
    </property>
    <property>
    	<name>mapreduce.jobhistory.done-dir</name>
    	<value>/data/mr-history/done</value>
    </property>
    <property>
            <name>mapreduce.jobhistory.intermediate-done-dir</name>
            <value>/data/mr-history/tmp</value>
    </property>
    <property>
            <name>mapreduce.jobhistory.webapp.address</name>
            <value>l20223613-01:19888</value>
    </property>
    <property>
            <name>yarn.app.mapreduce.am.env</name>
            <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
    </property>
    <property>
            <name>mapreduce.map.env</name>
            <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
    </property>
    <property>
            <name>mapreduce.reduce.env</name>
            <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
    </property>

    2.修改yarn-site.xml文件(在全分布的基础上添加):

    <property>
       		<name>yarn.nodemanager.aux-services</name>
       		<value>mapreduce_shuffle</value>
    	</property>
    
    	<property>
       	 	<name>yarn.resourcemanager.ha.enabled</name>
        		<value>true</value>
    	</property>
    
    	<property>
       		<name>yarn.log.aggregation-enable</name>
       		<value>true</value>
    	</property>
         <property>
             <name>yarn.resourcemanager.cluster-id</name>
             <value>yarn</value>
         </property>
         
         <property>
             <name>yarn.resourcemanager.ha.rm-ids</name>
             <value>rm1,rm2</value>
         </property>
     
         <property>
             <name>yarn.resourcemanager.hostname.rm1</name>
             <value>l20223613-01</value>
         </property>
     
         <property>
              <name>yarn.resourcemanager.hostname.rm2</name>
              <value>l20223613-02</value>
         </property>
         
         <property>
              <name>yarn.resourcemanager.zk-address</name>
              <value>l20223613-01:2181,l20223613-02:2181,l20223613-03:2181</value>
         </property>
         <property>
        		<name>yarn.log - aggregation.retain-seconds</name>
        		<value>86400</value>
    	</property>
    	<property>
       		<name>yarn.resourcemanager.recovery.enabled</name>
        		<value>true</value>
    	</property>
    	<property>
        		<name>yarn.resourcemanager.store.class</name>
     <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore
        		</value>
    	</property>
    		
    	<property>
      		<name>yarn.resourcemanager.webapp.address.rm1</name>
       		<value>l20223613-01:8188</value>
    	</property>
    	<property>
      	    <name>yarn.resourcemanager.scheduler.address.rm1</name>
    	    <value>l20223613-01:8130</value>
    	</property>
    	<property>
        		<name>yarn.resourcemanager.webapp.address.rm2</name>
        		<value>l20223613-02:8188</value>
    	</property>
    	<property>
       	 	<name>yarn.resourcemanager.scheduler.address.rm2</name>
       		<value>l20223613-02:8130</value>
    	</property>

    3.将修改后的配置文件分发到所有节点:

    scp mapred-site.xml yarn-site.xml l20223613-02:`pwd`
    scp mapred-site.xml yarn-site.xml l20223613-03:`pwd`
    scp mapred-site.xml yarn-site.xml l20223613-04:`pwd`

    4.启动服务:

    启动zookeeper,在主机l20223613-01l20223613-02l20223613-03命令行输入:

    zkServer.sh start

    启动hdfs,在主机l20223613-01命令行输入:

    start-dfs.sh

    启动yarn,在主机l20223613-01命令行输入:

    start-yarn.sh

    启动resourcemanager,在主机l20223613-02l20223613-03命令行输入:

    yarn-daemon.sh start resourcemanager

    5.运行wordcount 运行成功后,查看运行结果。 (这里注意自行创建测试文件,然后使用hdfs上传到/根目录下)命令行输入:

    运行wordcount指令:
    hadoop jar/export/server/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.5.jar wordcount /mr_test/input/wordcount.txt /output
    查看结果:
    hdfs dfs -cat /output/part-r-00000

    6.浏览器查看:查看通讯端口l20223613-01:8088,显示SUCCEEDED即表示成功运行。具体结果截图在五、实验结果中。

    四、出现的问题及解决方案

    问题现象

    解决方案

    原理说明

    ZooKeeper服务未启动(Error contacting service. It is probably not running)

    1. 检查zoo.cfg配置文件中的端口和IP映射是否正确;

    2. 确认所有节点时间同步(使用NTP服务);

    3. 检查/etc/hosts中的IP与主机名是否一致;

    4. 删除dataDir目录下的myid文件后重新生成。

    ZooKeeper依赖时间同步和正确的网络配置,IP映射错误或时间偏差会导致节点无法通信。

    ZooKeeper与JDK版本不兼容(启动时报类加载错误)

    1. 升级ZooKeeper到3.5.x以上版本(支持JDK8+);

    2. 降级JDK至兼容版本(如ZooKeeper3.4.x需JDK6/7)。

    ZooKeeper 3.4.x不支持JDK11+,需版本匹配以避免类冲突。

    NameNode进程消失

    1. 检查磁盘空间是否不足(df -h);2. 查看/var/log/hadoop-hdfs/*.log中的OOM错误,调整HADOOP_HEAPSIZE

    3. 确认hdfs-site.xmldfs.datanode.data.dir路径权限正确。

    磁盘空间不足或内存溢出会导致进程崩溃,权限错误会阻止数据写入。

    ResourceManager启动失败(FATAL ResourceManager: Error starting http server)

    1. 检查yarn-site.xmlyarn.resourcemanager.zk-address是否指向有效的ZooKeeper集群;
    2. 删除ZooKeeper中/rmstore目录并重新格式化;

    3. 调整yarn.scheduler.minimum-allocation-mbyarn.scheduler.maximum-allocation-mb,确保最大值≥最小值。

    ZK目录残留或内存参数配置错误会导致ResourceManager无法初始化。

    Hadoop浏览器状态均为Standby

    1. 执行hdfs haadmin -transitionToActive --forcemanual手动切换Active状态
    2. 重启ZKFC服务(hadoop-daemon.sh start zkfc);

    3. 检查集群时间同步(使用ntpdate命令)。

    时间不同步或ZKFC未正确选举会导致双Standby状态。

    MapReduce任务内存溢出(java.lang.OutOfMemoryError)

    1. mapred-site.xml中设置mapreduce.map.memory.mbmapreduce.reduce.memory.mb
    2. 使用CombineFileInputFormat合并小文件

    3. 调整JVM参数(-Xmx-Xms)。

    小文件过多或内存分配不足会导致任务超出堆内存限制。

    HDFS进入安全模式(Safe mode ON)

    1. 执行hdfs dfsadmin -safemode leave强制退出;
    2. 运行hdfs fsck /检查损坏块并删除;

    3. 增加dfs.replication副本数至合理值。

    副本不足或损坏块超过阈值会触发安全模式保护机制。

    JournalNode未同步元数据(QuorumJournalManager异常)

    1. 检查所有JournalNode进程是否运行;

    2. 确认hdfs-site.xmldfs.journalnode.rpc-address配置一致;<

    3. 重新格式化NameNode(hdfs namenode -format)。

    JournalNode负责元数据共享,进程未启动或配置错误会导致同步失败。

    YARN任务提交失败(ApplicationMaster启动超时)

    1. 增大yarn.app.mapreduce.am.resource.mbyarn.app.mapreduce.am.command-opts
    2. 检查NodeManager的磁盘空间和内存资源;

    3. 调整yarn.nodemanager.vmem-check-enabledfalse

    资源不足或虚拟内存检查过严会阻止ApplicationMaster启动。

    ZKFC无法选举Active节点(脑裂现象)

    1. 配置SSH隔离(sshfence)或Shell脚本隔离;
    2. hdfs-site.xml中设置dfs.ha.fencing.methods

    3. 检查防火墙规则是否阻止隔离命令执行。

    隔离机制未正确配置可能导致多个Active节点同时存在。

    DataNode进程消失

    将原来的DataNode内data文件下的VERSION文件内的Clusterid改成新的id

    可能因为多次格式化NameNode会重新生成新的ClusterId(集群ID),而原来的DataNode内data文件下的VERSION文件内的ClusterId还是原来的ClusterId,所以就会出现与NameNode的ClusterId不匹配。

    错误:找不到或无法加载主类ResourceManager

    要启动yarn需要在对应resourcemanager所在机器启动

    配置没有问题,因为我更换了resourcemanager的节点所在位置。

    五、实验结果

    1.配置好全发布后,查看浏览器:

    2.三台主机启动zookeeper,查看jps和status情况:

    ①主机l20223613-02:

    ②主机l20223613-01:

    ③主机l20223613-03:

    3.三台主机启动journalnode,查看jps情况

    4.测试Hadoop高可用集群的主备切换功能

    ①查看两个NameNode节点的状态信息

    ②浏览器查看主备节点是否完成切换:

    4.运行Hadoop自带的wordcount ,运行成功后,查看运行结果:

    5.hadoop高可用及mapreduce高可用搭建完成的jps查看:

    ①l20223613-01jps查看

    ②l20223613-02jps查看

    ③l20223613-03jps查看

    六、实验思考题

    1.搭建完全分布式,为什么要同步服务器时间?

    (1)确保事件顺序与因果关系的正确性

    事件排序错误风险

    分布式系统中多个节点独立处理事件时,若时间不同步,可能导致事件顺序颠倒。例如两个节点同时进行数据库写操作,时间差异可能导致后发生的操作覆盖先前的数据。

    因果关系依赖

    逻辑时钟(如Lamport时钟)依赖时间戳建立事件的"先于"关系,物理时间不同步会破坏因果逻辑,导致系统无法正确判断事件依赖关系。

    (2)保障分布式事务的一致性

    事务提交顺序控制

    事务处理需全局唯一时间戳确定操作顺序。若节点时间不同步,可能导致事务提交顺序混乱,引发数据不一致(如两阶段提交中的部分成功/失败)。

    避免事务冲突

    时间戳并发控制(MVCC)依赖时间戳判断数据的可见性。时间偏差可能导致事务读取过期数据或误判冲突。

    (3)维护数据一致性

    数据副本同步

    分布式数据库的副本同步需时间戳标记数据版本。时间不同步可能导致副本间数据覆盖或冲突,破坏最终一致性。

    数据可见性控制

    如Google Spanner通过TrueTime实现跨数据中心的时间同步,确保事务在全局时间窗口内可见,避免读取到中间状态。

    (4)避免时钟漂移带来的系统错误

    锁机制失效

    分布式锁(如Redlock)依赖锁的过期时间。若节点时钟漂移,可能导致锁提前释放或持有超时,引发并发操作冲突。

    资源调度混乱

    任务调度系统依赖时间触发作业。时钟漂移可能导致任务重复执行或遗漏,影响系统可靠性。

    (5)实现日志与调试的有效性

    日志关联分析

    跨节点日志需统一时间戳才能重建事件时间线。时间不同步会导致日志顺序错乱,增加故障排查难度。

    安全审计合规性

    金融或监管场景中,操作记录的精确时间戳是审计依据。时间误差可能引发合规风险。

    (6)优化系统性能与资源管理

    减少协调开销

    时间同步可减少事务协调中的重试次数(如Paxos协议中的超时判断),降低网络负载。

    避免资源争用

    分布式资源分配(如CPU调度)依赖时间窗口划分。时钟偏差可能导致资源分配冲突或浪费。

    (7)表格总结:

    类别

    具体影响

    典型场景

    事件顺序

    避免事件排序错误,确保因果关系正确

    数据库写操作、消息队列顺序消费

    事务一致性

    保证全局事务提交顺序,防止部分成功/失败

    两阶段提交(2PC)、多版本并发控制(MVCC)

    数据一致性

    确保副本同步与数据可见性,避免覆盖冲突

    分布式数据库(如TiDB)、跨数据中心数据复制

    时钟漂移控制

    防止锁失效、任务调度错误

    Redis Redlock、定时任务系统

    日志与调试

    统一跨节点日志时间线,支持故障排查

    分布式日志分析(ELK Stack)、安全审计

    性能优化

    减少协调开销与资源争用,提升系统吞吐量

    Paxos/Raft协议、资源调度框架(如Kubernetes)

    2.活跃名称节点和待命名称节点如何实现数据同步?

    (1)基于JournalNode(JN)的EditLog同步

    核心机制:

    Active NameNode(NN)将元数据修改操作(如文件创建、删除)记录到EditLog,并实时写入JournalNode集群(至少半数以上节点确认成功)。

    Standby NN持续监听JN集群的EditLog变化,一旦检测到新日志,立即拉取并合并到自身的内存命名空间,保持与Active NN的元数据一致。

    容错性:

    JN集群采用Quorum机制(如2N+1节点),允许最多N个节点故障,确保日志的持久化和高可用。

    (2)共享存储系统(QJM/NFS/Zookeeper)

    数据共享:

    Active NN通过共享存储(如QJM)将EditLog和FsImage同步到公共存储,Standby NN实时读取更新。

    QJM(Quorum Journal Manager)是Hadoop 2.x的默认方案,基于Paxos协议实现日志的分布式写入和仲裁。

    隔离双写:

    通过epoch编号确保同一时间只有一个NN可写入JN,避免数据冲突。

    (3)Checkpoint机制与元数据快照

    定期合并:

    Standby NN触发Checkpoint,将内存中的元数据与EditLog合并生成新的FsImage,并推送回共享存储。此过程减少EditLog大小,加快故障恢复速度。

    元数据恢复:

    NN重启时,从最新FsImage加载元数据,并重放后续EditLog,保证数据完整性。

    (4)ZKFC(ZooKeeper Failover Controller)的故障转移控制

    健康监测:

    ZKFC定期检查NN的健康状态(如进程存活、磁盘空间),通过Zookeeper维护会话和锁。

    自动选举:

    当Active NN故障时,ZKFC触发选举,Standby NN获取锁后切换为Active,并同步最新元数据。

    隔离机制:

    故障切换前,通过Fencing(如SSH隔离原Active NN)防止“脑裂”问题。

    (5) DataNode的双向心跳与块报告

    块位置同步:

    DataNode同时向Active和Standby NN发送心跳和块位置信息,确保两者掌握相同的数据分布。

    快速接管:

    Standby NN切换为Active后,无需等待DataNode重新注册,可直接处理客户端请求。

    (6)EditLog的传输与持久化流程

    写入流程:

    Active NN将操作写入本地EditLog缓冲区。通过双缓冲机制异步刷新到磁盘,并同步至JN集群。

    读取流程:

    Standby NN从JN拉取EditLog,按顺序合并到内存中的FsImage。周期性生成Checkpoint,减少恢复时间。

    (7)表格总结:

    机制/组件

    功能描述

    关键特点

    JournalNode集群

    存储Active NN的EditLog,确保日志的分布式持久化和高可用。

    基于Quorum机制(2N+1节点),半数以上写入成功即确认;支持快速故障恢复。

    共享存储(QJM)

    提供公共存储空间,协调Active与Standby NN的元数据同步。

    避免单点故障;通过epoch隔离双写,防止数据冲突。

    EditLog传输

    记录元数据变更,通过JN集群实现Active到Standby的实时同步。

    异步写入与同步监听结合;Standby NN主动拉取日志合并。

    Checkpoint机制

    定期合并EditLog与FsImage,生成元数据快照,减少恢复时间。

    由Standby NN触发;生成的新FsImage推送回共享存储。

    ZKFC

    监控NN健康状态,通过Zookeeper实现自动故障转移和选举。

    心跳检测、会话管理、锁竞争;隔离机制防止“脑裂”。

    DataNode双向报告

    DataNode同时向Active和Standby NN发送块位置信息,确保元数据完整性。

    心跳间隔短(默认3秒);故障切换后无需重新注册DataNode。

    隔离(Fencing)

    在故障切换时确保原Active NN无法继续写入,避免数据不一致。

    通过SSH或STONITH(断电)强制终止原Active进程。


    网站公告

    今日签到

    点亮在社区的每一天
    去签到