zoukankan      html  css  js  c++  java
  • HDFS源码分析之编辑日志编辑相关双缓冲区EditsDoubleBuffer

    EditsDoubleBuffer是为edits准备的双缓冲区。新的编辑被写入第一个缓冲区,同时第二个缓冲区可以被flush。为edits准备的双缓冲区。新的编辑被写入第一个缓冲区,同时第二个缓冲区可以被flush。在其内部,有两个重要的缓冲区成员变量,如下:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. // 当前被写入的缓冲区bufCurrent  
    2. private TxnBuffer bufCurrent; // current buffer for writing  
    3.   
    4. // 正在进行flush的缓冲区bufReady  
    5. private TxnBuffer bufReady; // buffer ready for flushing  
    6.   
    7. // 初始化缓冲区大小initBufferSize  
    8. private final int initBufferSize;  

            其中,bufCurrent是当前被写入的缓冲区,当前被写入的缓冲区是正在进行flush的缓冲区,而initBufferSize则是初始化缓冲区大小。我们再看下EditsDoubleBuffer的构造函数,如下:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1.  // 构造函数  
    2.  public EditsDoubleBuffer(int defaultBufferSize) {  
    3.    // 根据入参赋值initBufferSizeinitBufferSize  
    4. initBufferSize = defaultBufferSize;  
    5.      
    6. // 创建当前被写入的缓冲区bufCurrent  
    7. bufCurrent = new TxnBuffer(initBufferSize);  
    8.   
    9. // 创建正在进行flush的缓冲区bufReady  
    10.    bufReady = new TxnBuffer(initBufferSize);  
    11.   
    12.  }  

            根据入参赋值initBufferSizeinitBufferSize,然后分别创建上述两个缓冲区:创建当前被写入的缓冲区bufCurrent、创建正在进行flush的缓冲区bufReady。

            而EditsDoubleBuffer最基本的写入功能有两个,一个是用于写入操作符的writeOp()方法,另外一个就是用于写入事务的writeRaw()方法,代码分别如下:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. // 写入操作符至bufCurrent  
    2. public void writeOp(FSEditLogOp op) throws IOException {  
    3.   bufCurrent.writeOp(op);  
    4. }  
    5.   
    6. // 写入事务至bufCurrent  
    7. public void writeRaw(byte[] bytes, int offset, int length) throws IOException {  
    8.   bufCurrent.write(bytes, offset, length);  
    9. }  

            均是将操作符或事物写入bufCurrent缓冲区。而在准备flush前,需要先调用setReadyToFlush()方法,设置缓冲区可以进行flush,代码如下:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1.  // 设置双缓冲区为可以进行flsuh  
    2.  public void setReadyToFlush() {  
    3.     
    4. // 确保之前的数据已经被flush完毕,调用isFlushed()方法判断bufReady的大小是否为0即可  
    5.    assert isFlushed() : "previous data not flushed yet";  
    6.      
    7.    // 交换bufReady、bufCurrent  
    8.    TxnBuffer tmp = bufReady;  
    9.    bufReady = bufCurrent;  
    10.    bufCurrent = tmp;  
    11.  }  

            它首先会确保之前的数据已经被flush完毕,调用isFlushed()方法判断bufReady的大小是否为0即可,然后交换bufReady、bufCurrent。

            接着,我们需要调用flushTo()方法,将bufReady的内容写入指定输出流,并清空bufReady。此时不交换任何缓冲区,代码如下:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. /** 
    2.  * Writes the content of the "ready" buffer to the given output stream, 
    3.  * and resets it. Does not swap any buffers. 
    4.  * 将bufReady的内容写入指定输出流,并清空bufReady。此时不交换任何缓冲区。 
    5.  */  
    6. public void flushTo(OutputStream out) throws IOException {  
    7.   bufReady.writeTo(out); // write data to file  
    8.   bufReady.reset(); // erase all data in the buffer  
    9. }  

            而bufCurrent、bufReady都是一个TxnBuffer类型的缓冲区,这个TxnBuffer是对DataOutputBuffer的一个封装,保存了第一个事务艾迪firstTxId、事务数量numTxns、写入者writer等变量,它主要的两个方法,一个是写入操作符的writeOp()方法,实现如下:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. // 写入操作符  
    2. public void writeOp(FSEditLogOp op) throws IOException {  
    3.     
    4.   // 首次事务艾迪firstTxId被赋值为操作符的事务ID  
    5.   if (firstTxId == HdfsConstants.INVALID_TXID) {  
    6.     firstTxId = op.txid;  
    7.   } else {  
    8.         
    9.     // 之后确保操作符的事务ID永远大于首次事务ID  
    10.     assert op.txid > firstTxId;  
    11.   }  
    12.     
    13.   // 调用writer写入操作符  
    14.   writer.writeOp(op);  
    15.     
    16.   // 事务数量numTxns累加  
    17.   numTxns++;  
    18. }  

            首次事务艾迪firstTxId被赋值为操作符的事务ID,之后确保操作符的事务ID永远大于首次事务ID,然后调用writer写入操作符,并将事务数量numTxns累加。

  • 相关阅读:
    C#学习三之几个关键字Static,ref&out,get&set,readonly
    C#学习二之浅析var类型和enum枚举类型
    C#学习一之HelloWorld
    泛型(二)
    泛型(一)
    JavaScript 使用
    JavaScript
    C# 自定义控件制作和使用实例(winform)
    ThinkPHP 参数绑定原理
    处理jQuery append加入的元素 绑定事件无效的方法
  • 原文地址:https://www.cnblogs.com/jirimutu01/p/5556242.html
Copyright © 2011-2022 走看看