복붙노트

[HADOOP] MapReduce에서 globStatus를 사용하여 입력 파일 필터링

HADOOP

MapReduce에서 globStatus를 사용하여 입력 파일 필터링

입력 파일이 많으며 끝에 추가 된 날짜를 기준으로 선택한 파일을 처리하려고합니다. 이제 globStatus 메소드를 사용하여 파일을 필터링하는 위치에 대해 혼란스러워합니다.

사용자 정의 RecordReader 클래스가 있고 다음 메소드에서 globStatus를 사용하려고 시도했지만 작동하지 않았습니다.

public boolean next(Text key, Text value) throws IOException {
    Path filePath = fileSplit.getPath();

    if (!processed) {
        key.set(filePath.getName());

        byte[] contents = new byte[(int) fileSplit.getLength()];
        value.clear();
        FileSystem fs = filePath.getFileSystem(conf);
        fs.globStatus(new Path("/*" + date));
        FSDataInputStream in = null;

        try {
            in = fs.open(filePath);
            IOUtils.readFully(in, contents, 0, contents.length);
            value.set(contents, 0, contents.length);
        } finally {
            IOUtils.closeStream(in);
        }
        processed = true;
        return true;
    }
    return false;
}

FileStatus 배열을 반환한다는 것을 알고 있지만 파일을 필터링하는 데 어떻게 사용합니까? 누군가 빛을 비출 수 있습니까?

해결법

  1. ==============================

    1.globStatus 메소드는 2 개의 무료 인수를 사용하여 파일을 필터링 할 수 있습니다. 첫 번째 패턴은 glob 패턴이지만 때때로 glob 패턴이 특정 파일을 필터링하기에 충분히 강력하지 않은 경우 PathFilter를 정의 할 수 있습니다.

    globStatus 메소드는 2 개의 무료 인수를 사용하여 파일을 필터링 할 수 있습니다. 첫 번째 패턴은 glob 패턴이지만 때때로 glob 패턴이 특정 파일을 필터링하기에 충분히 강력하지 않은 경우 PathFilter를 정의 할 수 있습니다.

    glob 패턴과 관련하여 다음이 지원됩니다.

    Glob   | Matches
    -------------------------------------------------------------------------------------------------------------------
    *      | Matches zero or more characters
    ?      | Matches a single character
    [ab]   | Matches a single character in the set {a, b}
    [^ab]  | Matches a single character not in the set {a, b}
    [a-b]  | Matches a single character in the range [a, b] where a is lexicographically less than or equal to b
    [^a-b] | Matches a single character not in the range [a, b] where a is lexicographically less than or equal to b
    {a,b}  | Matches either expression a or b
    \c     | Matches character c when it is a metacharacter
    

    PathFilter는 다음과 같은 인터페이스입니다.

    public interface PathFilter {
        boolean accept(Path path);
    }
    

    따라서이 인터페이스를 구현하고 파일을 필터링하는 논리를 넣을 수있는 accept 메소드를 구현할 수 있습니다.

    Tom White의 훌륭한 책에서 발췌 한 특정 정규식과 일치하는 파일을 필터링하기 위해 PathFilter를 정의 할 수 있습니다.

    public class RegexExcludePathFilter implements PathFilter {
        private final String regex;
    
        public RegexExcludePathFilter(String regex) {
            this.regex = regex;
        }
    
        public boolean accept(Path path) {
            return !path.toString().matches(regex);
        }
    }
    

    작업을 초기화 할 때 FileInputFormat.setInputPathFilter (JobConf, RegexExcludePathFilter.class)를 호출하여 PathFilter 구현으로 입력을 직접 필터링 할 수 있습니다.

    편집 : setInputPathFilter에서 클래스를 전달해야하므로 인수를 직접 전달할 수는 없지만 Configuration을 사용하여 비슷한 작업을 수행 할 수 있어야합니다. RegexExcludePathFilter도 Configured에서 확장하면 원하는 값으로 이전에 초기화 한 Configuration 객체를 다시 가져올 수 있으므로 필터 내에서이 값을 다시 가져와 수락에서 처리 할 수 ​​있습니다.

    예를 들어 다음과 같이 초기화하면

    conf.set("date", "2013-01-15");
    

    그런 다음 필터를 다음과 같이 정의 할 수 있습니다.

    public class RegexIncludePathFilter extends Configured implements PathFilter {
        private String date;
        private FileSystem fs;
    
        public boolean accept(Path path) {
            try {
                if (fs.isDirectory(path)) {
                    return true;
                }
            } catch (IOException e) {}
            return path.toString().endsWith(date);
        }
    
        public void setConf(Configuration conf) {
            if (null != conf) {
                this.date = conf.get("date");
                try {
                    this.fs = FileSystem.get(conf);
                } catch (IOException e) {}
            }
        }
    }
    

    편집 2 : 원래 코드에 몇 가지 문제가있었습니다. 업데이트 된 클래스를 참조하십시오. 더 이상 사용되지 않으므로 생성자를 제거하고 디렉토리인지 확인해야합니다.이 경우 디렉토리의 내용도 필터링 할 수 있도록 true를 반환해야합니다.

  2. ==============================

    2.이 글을 읽는 사람은 "경로를 확인하는 것보다 필터에서 더 복잡한 작업을 수행하지 마십시오"라고 말할 수 있습니까? 구체적으로 : 디렉토리 인 파일을 확인하거나 파일 크기 등을 확인하지 마십시오. 목록 / 글로브 작업이 리턴 될 때까지 기다렸다가 채워진 FileStatus 항목에있는 정보를 사용하여 필터링하십시오.

    이 글을 읽는 사람은 "경로를 확인하는 것보다 필터에서 더 복잡한 작업을 수행하지 마십시오"라고 말할 수 있습니까? 구체적으로 : 디렉토리 인 파일을 확인하거나 파일 크기 등을 확인하지 마십시오. 목록 / 글로브 작업이 리턴 될 때까지 기다렸다가 채워진 FileStatus 항목에있는 정보를 사용하여 필터링하십시오.

    왜? 직접 또는 isDirectory ()를 통해 getFileStatus ()에 대한 모든 호출은 파일 시스템에 대한 불필요한 호출을 수행하며,이 호출은 HDFS 클러스터에 불필요한 이름 노드로드를 추가합니다. 더 중요한 것은 S3 및 기타 객체 저장소에 비해 각 작업에서 여러 개의 HTTPS 요청이 발생할 수 있으며 실제로 측정하는 데 시간이 걸립니다. 더 좋은 점은 S3가 전체 시스템 클러스터에서 너무 많은 요청을하고 있다고 생각하면 제한 할 것입니다. 당신은 그것을 원하지 않습니다.

    호출이 끝날 때까지 기다리십시오. 파일 상태 항목은 일반적으로 HTTPS 요청 당 수천 개의 파일 항목을 반환하는 객체 저장소의 list 명령에서 가져온 것이므로 훨씬 효율적입니다.

    자세한 내용은 org.apache.hadoop.fs.s3a.S3AFileSystem의 소스를 검사하십시오.

  3. from https://stackoverflow.com/questions/14332330/filtering-input-files-using-globstatus-in-mapreduce by cc-by-sa and MIT license