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存储元素,使用 ...
随机推荐
- 移动WEB前端开发资源的一些素材
meta篇: <meta name="viewport" content="width=device-width,initial-scale=1.0,user-sc ...
- 【转】Resharper上手指南
原文发布时间为:2011-02-16 -- 来源于本人的百度文章 [由搬家工具导入] 我是visual studio的忠实用户,从visual studio 6一直用到了visual studio 2 ...
- [论文]CA-Tree: A Hierarchical Structure for Efficient and Scalable Coassociation-Based Cluster Ensembles
作者:Tsaipei Wang, Member, IEEE 发表:IEEE TRANSACTIONS ON SYSTEMS, MAN, AND CYBERNETICS—PART B: CYBERNET ...
- ext2/3/4的inode结构说明
系统环境:Ubuntu15.10/ext4 今天在复习<鸟哥的私房菜-基础学习篇>,看到inode大小为128bytes,想看下这128字节里面到底是什么样的. 于是我查了下google, ...
- Python学习杂记_6_字典常用操作
字典操作 字典是由一对花括号括起来的一组“键值对”,每个键值对就是字典的一个元素,元素在字典中是无序的,常见操作如下: info = { 'name':'xiaoming', 'sex':'nan', ...
- 常用公共DNS服务器地址
DNS,全称Domain Name System,即域名解析系统,帮助用户在互联网上寻找路径,它在互联网的作用是把域名转换成为网络可以识别的IP地址.目前国内电信运营商通过使用DNS劫持和DNS污染的 ...
- PowerDesigner中如何生成主键和自增列
1.SQL Server版本: 第一步,首先要建立与数据库的连接,方法较多,这里举个例子: http://www.cnblogs.com/netsql/archive/2010/05/17/17375 ...
- Codeforces 899 A.Splitting in Teams
A. Splitting in Teams time limit per test 1 second memory limit per test 256 megabytes input sta ...
- Java 8 Lambda表达式的使用
lambda表达式允许你通过表达式来代替功能接口.lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块). Lambda表达式还增 ...
- 2017省选集训测试赛(二十五)Problem B recollection
@(XSY)[后缀数组, 启发式合并, ST表] Description Solution 后缀数组 + 启发式合并 + Sparse Table. 这是第一次写树上后缀数组. 对以每个点为根的子树统 ...