HDFS源码分析之编辑日志编辑相关双缓冲区EditsDoubleBuffer

简介:         EditsDoubleBuffer是为edits准备的双缓冲区。新的编辑被写入第一个缓冲区,同时第二个缓冲区可以被flush。为edits准备的双缓冲区。新的编辑被写入第一个缓冲区,同时第二个缓冲区可以被flush。

        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累加。






相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
3月前
|
存储 BI 网络安全
正在等待继续编辑 - Python - 基础知识专题 - 配置文件与日志管理
正在等待继续编辑 - Python - 基础知识专题 - 配置文件与日志管理
22 0
|
SQL 设计模式 Java
Mybatis源码分析二-如何优雅的使用主体日志
Mybatis源码分析二-如何优雅的使用主体日志
83 0
|
监控 开发工具 开发者
网站流量日志 Flume收集--hdfs--基于文件闲置策略滚动| 学习笔记
快速学习网站流量日志 Flume收集--hdfs--基于文件闲置策略滚动
142 0
网站流量日志 Flume收集--hdfs--基于文件闲置策略滚动| 学习笔记
|
Java API Maven
01、JUL日志(JDK自带日志框架,包含源码分析)(二)
01、JUL日志(JDK自带日志框架,包含源码分析)(二)
01、JUL日志(JDK自带日志框架,包含源码分析)(二)
|
Java 数据库
01、JUL日志(JDK自带日志框架,包含源码分析)(一)
01、JUL日志(JDK自带日志框架,包含源码分析)(一)
01、JUL日志(JDK自带日志框架,包含源码分析)(一)
|
分布式计算 资源调度 Hadoop
Hadoop运行模式(四)、配置历史服务器、配置日志的聚集、删除HDFS上已经存在的文件、集群启动/停止方式总结、配置mapred-site.xml、配置yarn-site.xml
Hadoop运行模式(四)、配置历史服务器、配置日志的聚集、删除HDFS上已经存在的文件、集群启动/停止方式总结、配置mapred-site.xml、配置yarn-site.xml
Hadoop运行模式(四)、配置历史服务器、配置日志的聚集、删除HDFS上已经存在的文件、集群启动/停止方式总结、配置mapred-site.xml、配置yarn-site.xml
|
存储 消息中间件 RocketMQ
源码分析 RocketMQ DLedger(多副本) 之日志复制-下篇
源码分析 RocketMQ DLedger(多副本) 之日志复制-下篇
源码分析 RocketMQ DLedger(多副本) 之日志复制-下篇
|
消息中间件 存储 文件存储
源码分析 RocketMQ DLedger(多副本) 之日志复制-上篇
源码分析 RocketMQ DLedger(多副本) 之日志复制-上篇
源码分析 RocketMQ DLedger(多副本) 之日志复制-上篇
|
存储 消息中间件 RocketMQ
源码分析 RocketMQ DLedger(多副本) 之日志追加流程
源码分析 RocketMQ DLedger(多副本) 之日志追加流程
源码分析 RocketMQ DLedger(多副本) 之日志追加流程
|
Apache 分布式计算 Spark
Apache Spark Delta Lake 事务日志实现源码分析
Apache Spark Delta Lake 事务日志实现源码分析 我们已经在这篇文章详细介绍了 Apache Spark Delta Lake 的事务日志是什么、主要用途以及如何工作的。那篇文章已经可以很好地给大家介绍 Delta Lake 的内部工作原理,原子性保证,本文为了学习的目的,带领大家从源码级别来看看 Delta Lake 事务日志的实现。
1962 0

热门文章

最新文章