hdfs FileStatus的accesstime的变更

背景:

hdfs文件系统有很多小文件,这些小文件会定期合并到大文件中,合并完成之后要删除这些小文件。但是有可能当前其他人正在读取这些小文件,此时如果将这些小文件删除,会导致当前用户无法正确获取到文件。

这一点hdfs做的有点恶心:最初我的理解是如果有线程A正在读取这个小文件,其他线程B删除这个小文件时应该会失败(至少应该要抛出异常)。但是测试发现不是这样的。实际的结果是:线程B默默的将小文件直接删除了,导致线程A只下载了这个文件的一部分,然后就卡在这里不动了。

针对这个问题的一个解决方案是:小文件被合并到大文件之后,保留30分钟后再删除,具体做法是通过FileStatus中的accesstime来获取上次的访问时间,,如果当前时间减去accesstime超过了30分钟才真正的删除这个小文件。(也就是给30分钟的缓冲时间。小文件合并到到文件之后,以后新的请求都是从大文件中下载数据)

但是问题又出现了。

@Testpublic void fileStatusByRead() {

// modification_time=1426037170715; access_time=1426037170138String desPath = "hdfs://******//8000000014268147637640-793038384000000014260371637637117";FSDataInputStream in = null;OutputStream outputStream = null;

// 初始化主集群HDFSSystem hdfsSystem;try {hdfsSystem = new HDFSSystem();

FileStatus fileStatus = hdfsSystem.getFileStatus(new Path(desPath));System.out.println("+++1:" + fileStatus.toString());

Thread.sleep(82 * 1000);

in = hdfsSystem.open(new Path(desPath));

long copySize = 8;outputStream = new FileOutputStream("D:\\input\\ttttt1.txt");

// 读取数据IOUtils.copyBytes(in, outputStream, copySize, true);

fileStatus = hdfsSystem.getFileStatus(new Path(desPath));System.out.println("+++2:" + fileStatus.toString());

} catch (Exception e) {e.printStackTrace();}}

测试发现System.out.println("+++1:" + fileStatus.toString()); 和System.out.println("+++2:" + fileStatus.toString());打印的时间居然一模一样

解决方法:

修改hdfs-site.xml中的

<property> <name>dfs.namenode.accesstime.precision</name> <value>3600000</value> <description>The access time for HDFS file is precise upto this value. The default value is 1 hour. Setting a value of 0 disables access times for HDFS. </description></property>

将默认的一小时改为10分钟。 但是这回带来一定的性能消耗。理想的解决办法是将文件的保留时间修改为1个小时或者2个小时。

只要心中有希望存在,就有幸福存在。

hdfs FileStatus的accesstime的变更

相关文章:

你感兴趣的文章:

标签云: