簡體   English   中英

HDFS保證從/向文件讀取/寫入數據

[英]HDFS guaranteed read/write of data from/to file

我們要保證一旦生產者完成對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同時改善代碼/設計以確保讀者不會丟失數據的任何建議?

一種解決方案是寫入帶有后綴/前綴的文件,並在寫入完成后重命名該文件:

例如,輸出到文件file1.txt:

  • 寫入名為.file1.txtfile1.txt.tmp的文件
  • 完成后關閉文件
  • 將.file1.txt或file1.txt.tmp重命名為file1.txt
  • 同時,用戶正在等待file1.txt變得可用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM