HDFS源码分析之编辑日志编辑相关双缓冲区EditsDoubleBuffer
EditsDoubleBuffer是为edits准备的双缓冲区。新的编辑被写入第一个缓冲区,同时第二个缓冲区可以被flush。为edits准备的双缓冲区。新的编辑被写入第一个缓冲区,同时第二个缓冲区可以被flush。在其内部,有两个重要的缓冲区成员变量,如下:
- // 当前被写入的缓冲区bufCurrent
- private TxnBuffer bufCurrent; // current buffer for writing
- // 正在进行flush的缓冲区bufReady
- private TxnBuffer bufReady; // buffer ready for flushing
- // 初始化缓冲区大小initBufferSize
- private final int initBufferSize;
其中,bufCurrent是当前被写入的缓冲区,当前被写入的缓冲区是正在进行flush的缓冲区,而initBufferSize则是初始化缓冲区大小。我们再看下EditsDoubleBuffer的构造函数,如下:
- // 构造函数
- public EditsDoubleBuffer(int defaultBufferSize) {
- // 根据入参赋值initBufferSizeinitBufferSize
- initBufferSize = defaultBufferSize;
- // 创建当前被写入的缓冲区bufCurrent
- bufCurrent = new TxnBuffer(initBufferSize);
- // 创建正在进行flush的缓冲区bufReady
- bufReady = new TxnBuffer(initBufferSize);
- }
根据入参赋值initBufferSizeinitBufferSize,然后分别创建上述两个缓冲区:创建当前被写入的缓冲区bufCurrent、创建正在进行flush的缓冲区bufReady。
而EditsDoubleBuffer最基本的写入功能有两个,一个是用于写入操作符的writeOp()方法,另外一个就是用于写入事务的writeRaw()方法,代码分别如下:
- // 写入操作符至bufCurrent
- public void writeOp(FSEditLogOp op) throws IOException {
- bufCurrent.writeOp(op);
- }
- // 写入事务至bufCurrent
- public void writeRaw(byte[] bytes, int offset, int length) throws IOException {
- bufCurrent.write(bytes, offset, length);
- }
均是将操作符或事物写入bufCurrent缓冲区。而在准备flush前,需要先调用setReadyToFlush()方法,设置缓冲区可以进行flush,代码如下:
- // 设置双缓冲区为可以进行flsuh
- public void setReadyToFlush() {
- // 确保之前的数据已经被flush完毕,调用isFlushed()方法判断bufReady的大小是否为0即可
- assert isFlushed() : "previous data not flushed yet";
- // 交换bufReady、bufCurrent
- TxnBuffer tmp = bufReady;
- bufReady = bufCurrent;
- bufCurrent = tmp;
- }
它首先会确保之前的数据已经被flush完毕,调用isFlushed()方法判断bufReady的大小是否为0即可,然后交换bufReady、bufCurrent。
接着,我们需要调用flushTo()方法,将bufReady的内容写入指定输出流,并清空bufReady。此时不交换任何缓冲区,代码如下:
- /**
- * Writes the content of the "ready" buffer to the given output stream,
- * and resets it. Does not swap any buffers.
- * 将bufReady的内容写入指定输出流,并清空bufReady。此时不交换任何缓冲区。
- */
- public void flushTo(OutputStream out) throws IOException {
- bufReady.writeTo(out); // write data to file
- bufReady.reset(); // erase all data in the buffer
- }
而bufCurrent、bufReady都是一个TxnBuffer类型的缓冲区,这个TxnBuffer是对DataOutputBuffer的一个封装,保存了第一个事务艾迪firstTxId、事务数量numTxns、写入者writer等变量,它主要的两个方法,一个是写入操作符的writeOp()方法,实现如下:
- // 写入操作符
- public void writeOp(FSEditLogOp op) throws IOException {
- // 首次事务艾迪firstTxId被赋值为操作符的事务ID
- if (firstTxId == HdfsConstants.INVALID_TXID) {
- firstTxId = op.txid;
- } else {
- // 之后确保操作符的事务ID永远大于首次事务ID
- assert op.txid > firstTxId;
- }
- // 调用writer写入操作符
- writer.writeOp(op);
- // 事务数量numTxns累加
- numTxns++;
- }
首次事务艾迪firstTxId被赋值为操作符的事务ID,之后确保操作符的事务ID永远大于首次事务ID,然后调用writer写入操作符,并将事务数量numTxns累加。
HDFS源码分析之编辑日志编辑相关双缓冲区EditsDoubleBuffer的更多相关文章
- HDFS源码分析EditLog之获取编辑日志输入流
在<HDFS源码分析之EditLogTailer>一文中,我们详细了解了编辑日志跟踪器EditLogTailer的实现,介绍了其内部编辑日志追踪线程EditLogTailerThread的 ...
- HDFS源码分析EditLog之读取操作符
在<HDFS源码分析EditLog之获取编辑日志输入流>一文中,我们详细了解了如何获取编辑日志输入流EditLogInputStream.在我们得到编辑日志输入流后,是不是就该从输入流中获 ...
- HDFS源码分析数据块校验之DataBlockScanner
DataBlockScanner是运行在数据节点DataNode上的一个后台线程.它为所有的块池管理块扫描.针对每个块池,一个BlockPoolSliceScanner对象将会被创建,其运行在一个单独 ...
- HDFS源码分析心跳汇报之数据块汇报
在<HDFS源码分析心跳汇报之数据块增量汇报>一文中,我们详细介绍了数据块增量汇报的内容,了解到它是时间间隔更长的正常数据块汇报周期内一个smaller的数据块汇报,它负责将DataNod ...
- HDFS源码分析心跳汇报之BPServiceActor工作线程运行流程
在<HDFS源码分析心跳汇报之数据结构初始化>一文中,我们了解到HDFS心跳相关的BlockPoolManager.BPOfferService.BPServiceActor三者之间的关系 ...
- HDFS源码分析之UnderReplicatedBlocks(一)
http://blog.csdn.net/lipeng_bigdata/article/details/51160359 UnderReplicatedBlocks是HDFS中关于块复制的一个重要数据 ...
- HDFS源码分析数据块复制监控线程ReplicationMonitor(二)
HDFS源码分析数据块复制监控线程ReplicationMonitor(二)
- HDFS源码分析数据块复制监控线程ReplicationMonitor(一)
ReplicationMonitor是HDFS中关于数据块复制的监控线程,它的主要作用就是计算DataNode工作,并将复制请求超时的块重新加入到待调度队列.其定义及作为线程核心的run()方法如下: ...
- HDFS源码分析之UnderReplicatedBlocks(二)
UnderReplicatedBlocks还提供了一个数据块迭代器BlockIterator,用于遍历其中的数据块.它是UnderReplicatedBlocks的内部类,有三个成员变量,如下: // ...
- HDFS源码分析之LightWeightGSet
LightWeightGSet是名字节点NameNode在内存中存储全部数据块信息的类BlocksMap需要的一个重要数据结构,它是一个占用较低内存的集合的实现,它使用一个数组array存储元素,使用 ...
随机推荐
- 【Linux】可重入函数和线程安全的区别与联系【转】
转自:http://blog.csdn.net/scenlyf/article/details/52074444 版权声明:本文为博主原创文章,未经博主允许不得转载. *****可重入函数 函数被不同 ...
- AC日记——集合位置 洛谷 P1491
集合位置 思路: 次短路: 先走一遍最短路: 记录最短路径,然后依次删边走最短路: 最短的长度就是次短路: 来,上代码: #include <queue> #include <cma ...
- 2018年东北农业大学春季校赛 E 阶乘后的0【数论】
链接:https://www.nowcoder.com/acm/contest/93/E来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...
- Codeforces 906D Power Tower(欧拉函数 + 欧拉公式)
题目链接 Power Tower 题意 给定一个序列,每次给定$l, r$ 求$w_{l}^{w_{l+1}^{w_{l+2}^{...^{w_{r}}}}}$ 对m取模的值 根据这个公式 每次 ...
- POJ1655 Balancing Act(树的重心)
题目链接 Balancing Act 就是求一棵树的重心,然后统计答案. #include <bits/stdc++.h> using namespace std; #define REP ...
- shell高级-----创建函数
基本脚本函数 1.创建函数 有两种格式可以用来在bash shell脚本中创建函数.第一种采用关键字function.后跟分配给该代码的函数名. function name { commands } ...
- Data structure basics - Java Implementation
Stack & Queue Implementations FixedCapacityQueue package cn.edu.tsinghua.stat.mid_term; import j ...
- 【spring boot logback】日志logback 生成日志文件在本项目下,而不在指定的日志文件目录下/指定日志文件到达最大值后不按照配置进行切割
原本的日志文件配置如下: <?xml version="1.0" encoding="UTF-8"?> <configuration scan ...
- Flutter接入极光推送
(1)搜索 https://pub.dartlang.org/packages/jpush_flutter ,安装插件,并且按照官方配置 /android/app/build.gradle andro ...
- nginx phase handler的原理和选择
nginx phase handler的原理和选择 PHASE HANDLER的种类 nginx在接收并解析完请求行.请求头之后.就会依次调用各个phase handler. phase handle ...