HDFS中hsync方法介绍

HDFS中hsync方法介绍

原创文章,转载请注明:博客园aprogramer

原文链接:HDFS中hsync方法介绍

1. 背景介绍 

HDFS在写数据务必要保证数据的一致性与持久性,从HDFS最初的版本到2.0版本HDFS提供了两种同步语义。 
1. 将client端写入的数据刷到每个DataNode的OS缓存中,如果每个副本所在的DataNode同时crash时(例如机房断电)就会导致数据丢失(sync和hflush方法)。
2. 将client端写入的数据刷到每个DataNode的磁盘中(hsync方法); 
在Hadoop2.0和cdh4中DFSOutputStream提供了sync,hflush和hsync三个方法,sync和hflush均是语义1,而hsync是语义2,hsync比sync和hflush的同步性更强,下面详细介绍hsync。 

2. Hadoop2.0中hsync的语义

hsync的语义是:client端所有的数据都发送到副本的每个datanode上,并且datanode上的每个副本都完成了posix中fsync的调用,也就是说操作系统已经把数据刷到磁盘上(当然磁盘也可能缓冲数据);需要注意的是当调用fsync时只有当前的block会刷到磁盘中,要想每个block都刷到磁盘,必须在创建流时传入Sync标示。 
通过分析上面的语义,可以确定hsyn涉及到两个角色client和DataNode,下面分别说明这两个角色。

3. DFSClient端逻辑

DFSClient端逻辑主要包括以下几步:

1. 判断是否需要sync,如果当前的数据都已经sync到磁盘了,则不需要再次sync;判断方法是首先调用flushBuffer(true),如果byteCurBlock(当前block的最后一个字节在file中的偏移量)大于上次sync的偏移量,则说明需要sync,否则不需要;
2. 如果需要sync,则将当前package的sync标示设为true;
3. 调用waitAndQueueCurrentPacket()将当前Package放到发送队列中
4. waitForAckedSeqno()等待发送package的确认包
5. 如果当前block没有调用namenode.fsync(),则调用该方法,持久化block元数据
6. 调用streamer.setHflush();
client端的时序图如下所示
 
查看大图:大图

4.DataNode端处理逻辑

DataNode端的改动比较简单,当接收的package的有sync标示,则执行flushOrSync方法(通过调用FileChannel的force方法,force方法会保证将文件内容刷到磁盘中)将block文件及meta文件刷到磁盘。序列图如下:
 
查看大图:大图

5. 性能分析及改进

由于调用hsync会比较耗时,将来可优化的方向:

1. 不是每个副本的DataNode都执行hsync,只有一个DataNode执行hsync;
2. 不同机架上的DataNode执行hsync;
3. hsync可同步进行,而不是等待hsync完成之后再返回给client端response(在这种情况下,client端的hsync方法的返回并不确保sync的完成,只有datanode端能保证)

6. 参考资料

[2]. Hadoop2.0代码
[3]. https://issues.apache.org/jira/browse/HDFS-744 

 

posted on 2014-02-08 15:06  aprogramer  阅读(4891)  评论(0编辑  收藏  举报

导航