首家大数据培训挂牌机构 股票代码:837906 | EN CN
异常解决方案—NameNode 宕机读写测试
异常解决方案—NameNode 宕机切换实验
异常解决方案—Data Node 配置
异常解决方案—Backup Node配置
异常解决方案—NameNode配置
异常解决方案—6.5.1异常情况分析
安装及配置
5NameNode安装及配置以及6BackupNode安装及配置
6.4.4虚拟机集群架设
6.4.3安装JDK
3.配置操作系统
2.创建虚拟机与安装操作系统
6.4构建实验环境
实验方案说明
故障切换机制
日志池(journal spool)机制
元数据操作情景分——BackupNode更新磁盘上的日志文件
元数据操作情景分——NameNode通过日志输出流......
元数据操作情景分——NameNode将日志写入日志文件
元数据操作情景分——NameNode更新内存镜像
元数据操作情景分——客户端执行命令流程
元数据操作情景分
Hadoop的Backup Node方案——运行机制分析(5)
Hadoop的Backup Node方案——运行机制分析(4)
Hadoop的Backup Node方案——运行机制分析(3)
Hadoop的Backup Node方案——运行机制分析(2)
Hadoop的Backup Node方案——运行机制分析(1)
Hadoop的Backup Node方案——系统架构
Hadoop的Backup Node方案—Backup Node 概述
元数据可靠性机制以及使用说明
Checkpoint 过程情景分析
元数据更新及日志写入情景分析
NameNode启动加载元数据情景分析
Hadoop的元数据备份机制的进行分析
元数据应用场景分析
Format情景分析
磁盘元数据文件
HDFS之代码分析——元数据结构
HDFS之内存元数据结构
什么是HDFS的元数据
Hadoop中DRDB方案和AvatarNode方案
Hadoop中常用各方案的对比
Hadoop的BackupNode方案
Hadoop的CheckpointNode方案
Hadoop的SecondaryNameNode方案
Hadoop的元数据备份方案
影响HDFS可用性的几个因素
什么是高可用性? 详细解析
HDFS系统架构简介
如何安装和配置Hadoop集群
如何在Windows下安装Hadoop
在MacOSX上安装与配置Hadoop
Linux下安装Hadoop的步骤
Hadoop的集群安全策略介绍
Hive的数据管理介绍
HBase的数据管理介绍
HDFS的数据管理介绍
Hadoop计算模型之 MapReduce 简介
Hadoop于分布式开发
Hadoop体系结构介绍
Hadoop的项目结构详解
一文读懂Hadoop

Hadoop的Backup Node方案——运行机制分析(4)

于2018-01-17由小牛君创建

分享到:


4. Register

BackupNodeNameNode注册之前,需要先验证双方的NameSpaceID是否一致,如果不一致,则会抛出异常,退出程序。如果一致,则通过RPC远程调用NameNoderegister接口,并传入自身的注册信息,注册信息包括:rpcAddresshttpAddressFSImageRoleCheckpointTime等。

NameNode根据传入的BackupNode注册信息进行判断,看是否允许该BackupNode进行注册,确保任何时候都只有一个活动的BackupNode注册在NameNode上。

注册成功后,会返回NameNode的注册信息,BackupNode会保存该信息,用于后续的通信与处理。

BackupNode通过RPC调用NameNoderegister方法,向NameNode进行注册,同时获得NameNode自身的注册信息。

BackupNode.java

// 传入的参数是 handshake 时获取的 nsInfo

private void registerWith(NamespaceInfo nsInfo) throws IOException {

// 1. 验证本地镜像的 namespaceID NameNode namespaceID,如果不一致,抛出异常

……

// 2. 注册

setRegistration();

NamenodeRegistration nnReg = null;

while(!isStopRequested()) {

try {

// NameNode RPC 调用

nnReg = namenode.register(getRegistration());

break;

} catch(SocketTimeoutException e) {

……

}

}

// 3. 注册结果处理

……

nnRpcAddress = nnReg.getAddress();

}

// 产生 Backup Node 的注册信息

NamenodeRegistration setRegistration() {

nodeRegistration = new

NamenodeRegistration(getHostPortString(rpcAddress),

getHostPortString(httpAddress), getFSImage(), getRole(),

getFSImage().getCheckpointTime());

return nodeRegistration;

}

NamenodeRegistration getRegistration() {

return nodeRegistration;

}

NameNoderegister方法返回NameNode自身的NamenodeRegistration信息。

NameNode.java

public NamenodeRegistration register(NamenodeRegistration registration)

throws IOException {

verifyVersion(registration.getVersion());

namesystem.registerBackupNode(registration);

return setRegistration();

}

NameNode对注册信息进行验证,确定是否允许注册。

FSNamesystem.java

synchronized void registerBackupNode(NamenodeRegistration registration)

throws IOException {

// 验证 BackupNode NamespaceID NameNode NamespaceID

if(getFSImage().getNamespaceID() != registration.getNamespaceID()){

// 抛出异常

}

// 检查 Backup Node 的有效性,确定是否允许注册

boolean regAllowed =

getEditLog().checkBackupRegistration(registration);

if(!regAllowed)

throw new IOException("Registration is not allowed. " +

"Another node is registered as a backup.");

}

FSEditLog getEditLog() {

return getFSImage().getEditLog();

}

FSImage getFSImage() {

return dir.fsImage;

}

FSImage.java

public FSEditLog getEditLog() {

return editLog;

}

FSEditLog checkBackupRegistration 方法。

FSEditLog.java

synchronized boolean checkBackupRegistration(NamenodeRegistration

registration) {

// 获取 BACKUP 类型的输出日志流

Iterator<EditLogOutputStream> it =

getOutputStreamIterator(JournalType.BACKUP);

// 如果没有输出流,则 regAllowed=true

boolean regAllowed = !it.hasNext();

NamenodeRegistration backupNode = null;

ArrayList<EditLogOutputStream> errorStreams = null;

while(it.hasNext()) {

// 如果有 EditLog 输出流,则判断该输出流对应的 Backup Node 和注册的是否相同

EditLogBackupOutputStream eStream =

(EditLogBackupOutputStream)it.next();

backupNode = eStream.getRegistration();

if(backupNode.getAddress().equals(registration.getAddress()) &&

backupNode.isRole(registration.getRole())) {

// 如果是同一个,则 regAllowed = true

regAllowed = true; // same node re-registers

break;

}

if(!eStream.isAlive()) {

// 如果 EditLog 输出流对应的 Backup Node 不再存在,regAllowed = true

if(errorStreams == null)

errorStreams = new ArrayList<EditLogOutputStream>(1);

errorStreams.add(eStream);

regAllowed = true; // previous backup node failed

}

}

// 如果 backupNode 存在且是 BACKUP,则报警退出

assert backupNode == null || backupNode.isRole(NamenodeRole.BACKUP) :

"Not a backup node corresponds to a backup stream";

processIOError(errorStreams, true);

// 输出流不存在,返回 true

// 输出流存在且该输出流对应的 Backup Node 和注册的是同一个,返回 true

// 输出流存在且该输出流对应的 Backup Node 不存在,返回 true

// 其他情况,返回 false

return regAllowed;

}