HDFS append操作

HDFS append操作

本篇背景是需要向HDFS写入文件,但写入文件数据是按照小时为单位生成的,那么我们需要将
每小时产出数据,聚类到一个文件,这时就需要用到HDFS append操作

代码

 public void append(String body, String fileName, String filePath) {
        FSDataOutputStream out = null;
        Path f = new Path(filePath);
        try {
            if (!fileSystem.exists(f)) {
                out = fileSystem.create(f);
            } else {
                out = fileSystem.append(f);
            }

            out.write(body.getBytes(CharsetNames.UTF_8));
        } catch (Exception e) {
            log.error("append file to hdfs is error: ", e);
        } finally {
            IOUtils.closeQuietly(out);
        }
    }

可能存在问题

上面的代码会存在一个问题,如果我们写入过程是个异步,那么在对HDFS 做append可能会报如下错误:

org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.hdfs.protocol.AlreadyBeingCreatedException): Failed to APPEND_FILE /文件目录 
on because DFSClient_NONMAPREDUCE_-2020766150_154 is already the current lease holder.

因为官方文档也说不支持多线程写入,那么我们怎么解决呢?
最常用的方式加redis锁

 @RedisLock(key = "test_" + "#fileName", waitTime = 10 * 1000, leaseTime = 10 * 1000)
 public void append(String body, String fileName, String filePath) {
        FSDataOutputStream out = null;
        Path f = new Path(filePath);
        try {
            if (!fileSystem.exists(f)) {
                out = fileSystem.create(f);
            } else {
                out = fileSystem.append(f);
            }

            out.write(body.getBytes(CharsetNames.UTF_8));
        } catch (Exception e) {
            log.error("append file to hdfs is error: ", e);
        } finally {
            IOUtils.closeQuietly(out);
        }
    }

redis锁网上有很多实现方式,这里就不在介绍了哈。

©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页