【问题标题】:HDFS guaranteed read/write of data from/to fileHDFS 保证从文件读/写数据
【发布时间】:2012-05-30 15:27:19
【问题描述】:

一旦生产者完成对 HDFS 中文件的写入,我们希望保证消费者进程读取生产者创建的数据。以下是我们正在努力改进的应用程序中使用的一种方法。

制作人:

private void produce(String file, int sleepSeconds) throws Exception {
        Configuration conf = new Configuration();
        conf.addResource(new Path(
                "C:\\dev\\software\\hadoop-0.22.0-src\\conf\\core-site.xml"));
        conf.set("fs.defaultFS", "hdfs://XXX:9000");
        FileSystem fileSystem = FileSystem.get(conf);

        Path path = new Path(file);
        if (fileSystem.exists(path)) {
            fileSystem.delete(path, false);
        }
        System.out.println("Creating file");
        FSDataOutputStream out = fileSystem.create(path);
        System.out.println("Writing data");
        out.writeUTF("--data--");
        System.out.println("Sleeping");
        Thread.sleep(sleepSeconds * 1000L);
        System.out.println("Writing data");
        out.writeUTF("--data--");
        System.out.println("Flushing");
        out.flush();
        out.close();
        fileSystem.close();
        System.out.println("Releasing lock on file");
    }

消费者:

private void consume(String file) throws Exception {
        Configuration conf = new Configuration();
        conf.addResource(new Path(
                "C:\\dev\\software\\hadoop-0.22.0-src\\conf\\core-site.xml"));
        conf.set("fs.defaultFS", "hdfs://XXX:9000");
        FileSystem fileSystem = FileSystem.get(conf);

        Path path = new Path(file);
        if (fileSystem.exists(path)) {
            System.out.println("File exists");
        } else {
            System.out.println("File doesn't exist");
            return;
        }
        FSDataOutputStream fsOut = null;
        while (fsOut == null) {
            try {
                fsOut = fileSystem.append(path);
            } catch (IOException e) {
                Thread.sleep(1000);
            }
        }
        FSDataInputStream in = fileSystem.open(path);
        OutputStream out = new BufferedOutputStream(System.out);
        byte[] b = new byte[1024];
        int numBytes = 0;
        while ((numBytes = in.read(b)) > 0) {
            out.write(b, 0, numBytes);
        }
        in.close();
        out.close();
        if (fsOut != null)
            fsOut.close();
        fileSystem.close();
        System.out.println("Releasing lock on file");
    }

流程应该如何运行的要求如下:

  1. 生产者进程(不是线程)已启动。 thread.sleep 模拟了一堆数据库调用和业务逻辑

  2. 消费者进程(不是线程)在另一台机器上启动,该机器会阻塞直到生产者释放其锁定。消费者读取时,其他进程不应修改数据文件

关于我们如何使用 HDFS java API 在确保阅读器不丢失数据的同时改进此代码/设计的任何建议?

【问题讨论】:

  • 生产者生成了多少文件?
  • 1 个文件由 1 个生产者生成

标签: java file-io hadoop hdfs


【解决方案1】:

一种解决方法是写入一个带有临时后缀/前缀的文件,写入完成后重命名该文件:

例如输出到文件file1.txt:

  • 写入名为.file1.txtfile1.txt.tmp 的文件
  • 完成后关闭文件
  • 将 .file1.txt 或 file1.txt.tmp 重命名为 file1.txt
  • 与此同时,消费者正在等待 file1.txt 可用

【讨论】:

  • 谢谢,这绝对是一个选择
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-12
  • 1970-01-01
  • 2021-06-18
相关资源
最近更新 更多