HDFS写入监控链路调研设计

1. 背景:

    线上HDFS的DataNode中频繁出现Slow write日志

     HDFS写入监控链路调研设计_第1张图片

     从日志分析来看,Slow write分为write to mirror和write to disk两类
     为便于分析网络或者磁盘写入的情况,设计了HDFS的写入监控链路,采集DataNode中出现的slow日志收集,供后续分析。

 

2. HDFS的源码分析

    下面从源码角度简要分析下HDFS的block写入流程:

     HDFS写入监控链路调研设计_第2张图片

    如图所示,写入的大致流程如下:
      1) DFSClient通过Sender.writeBlock方法触发一个写数据块请求;
      2) 该请求通过数据流管道传送到每一个数据节点,最后一个数据节点回复请求确认,该确认消息通过数据流管道逆向送回DFSClient;
      3) DFSClient收到确认消息后,将待写入的数据切分成若干个数据包(packet),然后依次向数据流管道发送这些数据包;
      4) 数据包首先到达DataNode1,写入磁盘之后,再发送给DataNode2,依次类推;
      5) 当数据包到达DataNode3时,DataNode3会对数据包进行校验,如果校验成功,则发送确认消息,并且逆向通过数据流管道传回DFSClient;
      6) 当所有的数据包都发送完毕之后,DFSClient会发送一个空的数据包标识当前数据快发送完毕,至此,整个数据块流程发送完毕。

     写入过程涉及到的主要类包括:

     1) DataNode启动时会创建一个DataXceiverServer类用于监听客户端的读写请求:

         HDFS写入监控链路调研设计_第3张图片

          在其run方法中,对于每个客户端连接创建一个DataXceiver用于处理读写请求。

     2) DataXceiver中写入数据块的逻辑在writeBlock方法中:

         首先创建一个blockReceiver对象:

         HDFS写入监控链路调研设计_第4张图片

         连接到下游节点:

         HDFS写入监控链路调研设计_第5张图片

         调用blockReceiver的receiveBlock方法接收数据块

         HDFS写入监控链路调研设计_第6张图片

     3) BlockReceiver类负责接收上游的数据块,保存到当前节点,并写入到下游节点,核心逻辑在receiveBlock方法中:

         首先读取packet至本地缓存

         HDFS写入监控链路调研设计_第7张图片

         写入数据流到下一个节点:

         HDFS写入监控链路调研设计_第8张图片

         如果接收到了完整的数据块,并且启动了sync标识,则写入数据到本地磁盘
         否则验证数据包的校验和

         HDFS写入监控链路调研设计_第9张图片

          将数据写入本地磁盘

           HDFS写入监控链路调研设计_第10张图片

 

3.  写入链路埋点设计

     DataNode中对以下四种slow情况(超过300ms)进行了warning:

1) Slow BlockReceiver write packet to mirror
2) Slow BlockReceiver write data to disk
3) Slow flushOrSync
4) Slow manageWriterOsCache

     为了追踪记录这4种耗时情况,在BlockReceiver类中对这四种耗时的地方打印出日志,字段格式如下:

{
  blkId: block的id
  time:  时间戳
  srcAddress: 当前节点地址
  dstAddress: 目标节点地址
  slowType: 四种slow的类型
  duration: slow write的耗时
}

     在BlockReceiver类中添加以下代码打印日志:

      HDFS写入监控链路调研设计_第11张图片

     将日志打印到单独的文件中,通过filebeat收集到kafka中,再通过spark-streaming写入到es中,打印出的日志如下图所示:

     

     收集到es之后,通过相关的聚合条件可以查询出不同slow write的耗时情况:

      HDFS写入监控链路调研设计_第12张图片

 

4. 部署方式:

    将修改后的hadoop源码重新打包,得到hadoop-hdfs-2.6.0-cdh5.5.0.jar包,替换掉hadoop路径中的jar包。

    在CDH的DataNode高级配置中的日志记录高级配置代码段中添加以下配置:

log4j.appender.PACKET_TRACE=org.apache.log4j.RollingFileAppender
log4j.appender.PACKET_TRACE.Threshold=INFO
log4j.appender.PACKET_TRACE.File=${hadoop.log.dir}/packet_trace.log
log4j.appender.PACKET_TRACE.Append=true
log4j.appender.PACKET_TRACE.MaxFileSize=30MB
log4j.appender.PACKET_TRACE.MaxBackupIndex=10
log4j.appender.PACKET_TRACE.layout=org.apache.log4j.PatternLayout
 
log4j.logger.packet-trace = INFO, PACKET_TRACE
log4j.additivity.packet-trace = false

     重启该DataNode,则日志信息会记录到packet_trace.log文件中。

     同时在该节点上部署filebeat,收集packet_trace.log文件的信息,写入到kafka中。

你可能感兴趣的:(HDFS写入监控链路调研设计)