hdfs写磁盘及jnode

本文详细探讨了HDFS中NameNode的RPC服务器如何处理mkdirs操作,涉及FSEditLog的日志记录、JournalSet的写入流程、JournalNode的处理机制以及在编辑日志同步过程中的细节。在mkdirs操作中,FSEditLog通过logMkDir记录日志,随后将编辑日志同步到各个JournalNode。过程中涉及到多个类如AsyncLogger、QuorumCall和JournalAndStream,以及一系列的检查和同步机制,确保数据的安全性和一致性。
摘要由CSDN通过智能技术生成

namenode rpc server:

mkdirs:细化logEdit,核心类FSEditLog

  1. FSDirectory.getEditLog(),即FSEditLog-》logMkDir-》logEdit-》记录日志
  2. 满足可写入状态后,如果自动同步标识isAutoSyncScheduled为true,则阻塞;否则
  3. 自增txid,赋给线程本地变量,FSEditLogOp设置txid,editLogStream.wirite(op);
    1. JournalSetOutputStream.write-》遍历journals
    2. 先看下journals,包含JournalAndStream的list,在FSEditLog的journalSet初始化
    3. 遍历journal的QuorumOutputStream-》write-》双缓冲调用writeOp,最终MkdirOp序列化inodeid,path等信息到ByteArrayOutputStream
  4. endTransaction
  5. 如果写磁盘,buffer满了,则isAutoSyncScheduled为true,让后续写磁盘阻塞;
  6. logSync-》交互缓冲区,logStream.flush();-》flushAndSync,一个刷新磁盘,另一个我们重点观看
    1. 创建buffer,把数据从备缓存提取出来,sendEdits,每个AsyncLogger代表一个jnode,遍历,调用sendEdits异步发送;
    2. 记录回调到map,把map添加到QuorumCall
    3. waitForWriteQuorum,阻塞等待结果,全部返回结束,一半加1成功返回,一半加1失败返回,否则多次等待,等待时间逐渐缩短,直到超时;
    4. 给每个AsyncLogger设置committedTxId
    5. 超时抛出超时异常,然后调用terminate结束当前进程(继续提供只读服务不也可以吗?并且这样会丢失一些元数据啊,怎么办?)
  7. 接下里看给jnode发送了什么内容?还有,失败的jnode要怎么处理?
    1. IPCLoggerChannel生成请求,journalId, epoch, ipcSerial++, committedTxId(已提交的txid)
    2. segmentTxId(FSEditLog的txid+1), firstTxnId(buffer的第一个txid), numTxns(buffer添加操作的计数), data
    3. 调用journal,看journalnode rpcserver如何处理

FSEditLog:

  • private JournalSet journalSet初始化:管理JournalAndStream,JournalAndStream管理JournalManager和EditLogOutputStream
  1. FSNamesystem.startActiveServices-》initJournals-》读取core-site.xml hdfs-site.xml,解析uri scheme,初始化JournalManager,被添加到JournalAndStream
  2. 如果是file,初始化FileJournalManager(包含buffer容量),被添加到JournalAndStream;否则,该类有多个实现,通过配置文件指定uri scheme指定实现,目前添加的是QuorumJournalManager(包含buffer容量)
  3. 目前有两个JournalAndStream实例,一个是写磁盘一个是写jnode;
  • private EditLogOutputStream editLogStream初始化:
  1. FSNamesystem.startActiveServices-》openForWrite-》startLogSegment-》new JournalSetOutputStream

EditLogOutputStream:

  • EditLogOutputStream继承类有JournalSetOutputStream(editLogStream被初始化为该类,一个操作类),EditLogFileOutputStrem、QuorumOutputStream等;
  • 上面后两个实现使用双缓存EditsDoubleBuffer,DataOutputBuffer继承自jdk.DataOutputStream,里面使用了ByteArrayOutputStream;
  • 根据JournalAndStream中的,JournalManager的实现,初始化,FileJournalManager实现方法startLogSegment-》new EditLogFileOutputStreamQuorumJournalManager实现startLogSegment-》new QuorumOutputStream;

JournalNode:

  • EditLogOutputStream curSegment = new EditLogFileOutputStream,成员变量初始化,该类主要作用写磁盘;
  • 处理,namenode standby通过http发起的,获取日志的请求,/getJournal处理方法;
  • journal
  1. 检查请求的epoch(和namenode启动有关),PersistentLongFile持久化long value,如果小于存储的,抛异常,否则,更新存储的epoch
  2. 判断segmentTxId是否相等,否则异常(收到rpc请求startLogSegment,初始化该值,在namenode启动时,QuorumJournalManager初始化stream时调用startLogSegment,发起rpc请求)
  3. 请求的ipcSerial是否更大,否则异常;更新值;
  4. 请求的committedTxId是否更大,否则异常,更新值;以上四步为检查请求;
  • startLogSegment
  1. 检查请求-》如果存在segment,中断他
  2. FileJournalManager 获取请求txid的file,如果多个,异常;如果存在,可能断链重新链接,获取EditLogFile-》如果isInProgress false,异常;否则扫描文件,如果last和first txid不等,异常
  3. 如果请求的epoch不等,更新
  4. 删除segmentTxid对应的paxosfile
  5. 创建segment,初始化segmenttxid = txid,nextTxid = txid,每次joural请求也会更新nextTxid;

EditLogFile:

private File file;
private final long firstTxId;
private long lastTxId;

private boolean hasCorruptHeader = false;
private final boolean isInProgress;

java,面向对象思想,c 面向过程,c++基于两者之间;

如果看java开源和c++开源就是不一样的感觉;

java,拼命堆类,控制类的大小,各种跳转,各种设计模式;

c++,中性,对象和过程各一半;

​​​​​​​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MyObject-C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值