大数据处理之如何确保断电不丢数据

在Hadoop 2.0.2-alpha之前,HDFS在机器断电或意外崩溃的情况下,有可能出现正在写的数据丢失的问题。而最近刚发布的CDH4中HDFS在Client端提供了hsync()的方法调用(HDFS-744),从而保证在机器崩溃或意外断电的情况下,数据不会丢失。这篇文件将围绕这个新的接口对其实现细节进行简单的分析,从而希望找出一种合理使用hsync()的策略,避免重要数据丢失。

 

 

 

HDFS中sync(),hflush()和hsync()的差别

在hsync()之前,HDFS就已经提供了sync()和hflush()的调用,单从方法的名称上看,很难分辨这三个方法之间的区别。咱们先从这几个方法之间的差别介绍起。

 

在HDFS中,调用hflush()会将Client端buffer中的存放数据更新到Datanode端,直到收到所有Datanode的ack响应时结束调用。这样可保证在hflush()调用结束时,所有的Client端都可以读到一致的数据。HDFS中的sync()本质也是调用hflush()。

 

hsync()则是除了确保会将Client端buffer中的存放数据更新到Datanode端外,还会确保Datanode端的数据更新到物理磁盘上,这样在hsync()调用结束后,即使Datanode所在的机器意外断电,数据并不会因此丢失。而hflush()在机器意外断电的情况下却有可能丢失数据,因为Client端传给Datanode的数据可能存在于Datanode的cache中,并未持久化到磁盘上。下图描述了从Client发起一次写请求后,在HDFS中的数据包传递的流程。

 

 

 

hsync()的实现本质

hsync()执行时,实际上会在对应Datanode的机器上产生一个fsync的系统调用,从而将内存中的相关文件的数据更新到磁盘。

 

Client端执行hsync时,Datanode端会识别到Client发送过来的数据包中的syncBlock_字段为true,从而判定需要将内存中的数据更新到磁盘。此时会在BlockReceiver.java的flushOrSync()中执行如下语句:

((FileOutputStream)cout).getChannel().force(true);

 

而FileChannel的force(boolean metadata)方法在JDK中,底层为于FileDispatcherImpl.c中调用fsync或fdatasync。metadata为true时执行fsync,为false时执行fdatasync。

Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this, 
jobject fdo, jboolean md)
{
    jint fd = fdval(env, fdo);
    int result = 0;

    if (md == JNI_FALSE) {
        result = fdatasync(fd);
    } else {
        result = fsync(fd);
    }
    return handle(env, result, "Force failed");
}

 

当Datanode将数据持久化到磁盘上后,会发ack响应给Client端。当收到所有Datanode的ack响应时,hsync()的调用结束。

 

值得注意的是,fsync或fdatasync本身是一个非常耗时的调用,因为磁盘的读写速度远低于内存的读写速度。在不调用fsync或fdatasync的情况下,数据可能保存在各级cache中。

 

最开始笔者在测hsync()的读写性能时,发现不同机器上测试结果hsync()耗时差别巨大,有的集群平均调用耗时为4ms,而有的集群平均调用耗时则需25ms。后来在公司各位大神的点拨下才意识到是跟Linux文件系统的机制有关。在这种情况下,只有一探Linux相关部分的源码才能解开心中的疑惑,下面这节就将从更底层的角度来解析与hsync()密切相关的系统调用fsync及fdatasync方法。

 

 

fsync和fdatasync的大致实现过程

对ext4格式的文件系统来说,fsync和fdatasync方法的实现代码位于fs/ext4/fsync.c这个文件中。在追加写文件的情况下,fsync和fdatasync的流程几乎一致,因为对HDFS的写操作基本都是追加写ÿ

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值