首家大数据培训挂牌机构 股票代码: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

日志池(journal spool)机制

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

分享到:


6.2.3日志池(journal spool)机制

在第2阶段的BackupNode中,采用了日志池(journalspool)的机制,用于缓存NameNode发送过来的来不及处理的日志记录。通常情况下,BackupNode可以实时地处理接收的日志记录,将其合并更新到内存元数据之中,但在一些情况下,BackupNode的负载较重,如正在做Checkpoint合并元数据,或者将元数据输出到磁盘时,此时如果接收到新的日志记录,就有可能来不及处理。为保证数据的一致性,有必要先将日志缓存起来,待负载较轻时再进行处理。

总的来说,日志池机制包括三个对象:

日志生产者:日志生产者由NameNode担任,当它发现BackupNode不能及时处理数据时,就会通知BackupNode创建日志池,并将日志记录以流的方式追加到日志池的尾部;

日志池:日志池是一个先进先出的结构,可以有效保证日志记录顺序的一致性,并且具有多种状态,可以实现动态创建与销毁;

日志消费者:日志的消费者由BackupNode担任,它从日志池依次取出日志记录,将其合并更新到内存元数据中,并将更新写入磁盘上的日志文件。

 


由于日志的产生速度是有限的,而日志处理可快速进行,因此,日志池最终会变空,此时日志池也就失去了存在的意义,BackupNode将和NameNode进行协商销毁日志池,并最终切换到日志实时处理模式。

Journalspool的实现代码在BackupStorage.java中,并未单独形成一个类。

Journalspool通过一个名为edit.new的文件来实现的数据存储。Journalspool有三种状态:

l  OFF表示未创建Journalspool,此时,日志正常写入Edits

l  INPROGRESS表示Journalspool可用,此时日志将被写入Journalspool,即edit.new

l  WAIT表示BackupNode正在对Journalspool操作,需要等待。

状态转换分析如下:

1)初始化时,未创建Journalspool,因此状态为OFF

2)当需要创建Journalspool时,会调用startJournalSpool进行创建,将创建edit.new文件作为日志文件,此时状态转为INPROGRESS

3)写入Journal时,会进行判断,如果此时状态是OFF,则写入Editlog文件,如果状态是INPROGRESS,则写入Journalspool,即edit.new文件。

4)当checkpoint结束后,BackupNode会将Journalspool中的记录更新到内存的NameSpace。它首先会读入edit.new文件内容,将状态置为WAIT,然后进行更新,最后将edit.new重命名为edits,销毁Journalspool,状态置为OFF

代码分析如下:

Journalspool初始状态为OFF

BackupStorage.java

BackupStorage() {

super();

jsState = JSpoolState.OFF;

}

startJournalSpool方法,用来创建JournalSpool

BackupStorage.java

synchronized void startJournalSpool(NamenodeRegistration nnReg)

throws IOException {

……

// 1.状态判断,如果已经创建了,则直接返回

……

// 2.创建 Journal Spool 目录

……

// 3.创建 Edits 文件

……

// 4.创建指向 Journal Spool 文件的流

// 5.状态置为 INPROGRESS

jsState = JSpoolState.INPROGRESS;

}

Journal方法,写入日志。

BackupStorage.java

synchronized void journal(int length, byte[] data) throws IOException {

……

try {

switch(jsState) {

case WAIT:

case OFF:

// 如果是 WAIT,则一直等待到 Journal Spool 销毁

waitSpoolEnd();

// 更新内存中的 NameSpace

backupInputStream.setBytes(data);

editLog.loadEditRecords(getLayoutVersion(),

backupInputStream.getDataInputStream(), true);

getFSNamesystem().dir.updateCountForINodeWithQuota();

break;

case INPROGRESS:

break;

}

//如果已经创建了 Journal Spool,将日志记录写入文件

// 如果当前状态是 OFF,则写入 edits 文件

// 如果状态是 INPROGRESS,则写入 edit.new 文件

editLog.logEdit(length, data);

// 日志内容同步,防止并发写出现问题

editLog.logSync();

} finally {

backupInputStream.clear();

}

}

convergeJournalSpool方法,写入日志。

BackupStorage.java

void convergeJournalSpool() throws IOException {

……

if(jSpoolFile.exists()) {

// 加载 edits.new 文件

EditLogFileInputStream edits = new

EditLogFileInputStream(jSpoolFile);

DataInputStream in = edits.getDataInputStream();

numEdits += editLog.loadFSEdits(in, false);

// 1 次将 edits.new 的内容读完,置 WAIT

jsState = JSpoolState.WAIT;

numEdits += editLog.loadEditRecords(getLayoutVersion(), in,

true);

getFSNamesystem().dir.updateCountForINodeWithQuota();

edits.close();

}

// 销毁 edits.new,将 edits.new 重命名为 edits,后面的日志记录将写入 edits

editLog.revertFileStreams(STORAGE_JSPOOL_DIR + "/" +

STORAGE_JSPOOL_FILE);

……

// 唤醒 Journal writer,置 OFF

synchronized(this) {

jsState = JSpoolState.OFF;

notifyAll();

}

……

}

convergeJournalSpool方法调用时机。

Checkpointer.java

void doCheckpoint() throws IOException {

……

getNamenode().endCheckpoint(backupNode.getRegistration(), sig);

bnImage.convergeJournalSpool();

……

}