복붙노트

[HADOOP] 파일에 대한 경로가 필요한 생성자가있는 경우 병에 포장 된 경우이를 ""만들 수 있습니까?

HADOOP

파일에 대한 경로가 필요한 생성자가있는 경우 병에 포장 된 경우이를 ""만들 수 있습니까?

이 질문의 문맥은 필자가 작성한 돼지 스크립트에서 maxmind java API를 사용하려고한다는 것입니다 ... 그러나 그 중 하나에 대해 알고있는 것이 질문에 대답하는 것이 필요하다고 생각하지 않습니다.

maxmind API에는 필요한 정보가있는 쉼표로 구분 된 파일 인 GeoIP.dat라는 파일에 대한 경로가 필요한 생성자가 있습니다.

API를 포함하는 jar 파일과 클래스를 인스턴스화하고 사용하는 래핑 클래스가 있습니다. 제 아이디어는 jar 파일에 GeoIP.dat 파일을 패키지화 한 다음 jar 파일의 자원으로 액세스하는 것입니다. 문제는 생성자가 사용할 수있는 경로를 생성하는 방법을 모른다는 것입니다.

API를 보면 파일을로드하는 방법입니다.

public LookupService(String databaseFile) throws IOException {
    this(new File(databaseFile));
}


public LookupService(File databaseFile) throws IOException {
    this.databaseFile = databaseFile;
    this.file = new RandomAccessFile(databaseFile, "r");
    init();
}

필요한 경우 API 자체를 편집하여 API 자체를 편집하는 것을 싫어하기 때문에 붙여 넣기 만하지만 필자는 그러한 기능을 어떻게 복제 할 수 있는지 모릅니다. 이상적으로 파일 형식으로 가져오고 싶습니다. 그렇지 않으면 API를 편집하는 것이 매우 어려울 것입니다.

이것이 가능한가?

해결법

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

    1.시험:

    시험:

    new File(MyWrappingClass.class.getResource(<resource>).toURI())
    
  2. ==============================

    2.데이터를 임시 파일에 덤프하고 임시 파일을 임시 파일로 공급하십시오.

    데이터를 임시 파일에 덤프하고 임시 파일을 임시 파일로 공급하십시오.

    File tmpFile = File.createTempFile("XX", "dat");
    tmpFile.deleteOnExit();
    
    InputStream is = MyClass.class.getResourceAsStream("/path/in/jar/XX.dat");
    OutputStream os = new FileOutputStream(tmpFile)
    
    read from is, write to os, close
    
  3. ==============================

    3.권장되는 방법 중 하나는 분산 캐시를 병에 담기보다는 분산 캐시를 사용하는 것입니다.

    권장되는 방법 중 하나는 분산 캐시를 병에 담기보다는 분산 캐시를 사용하는 것입니다.

    GeoIP.dat를 압축하여 hdfs : // host : port / path / GeoIP.dat.zip에 복사하면됩니다. 그런 다음 Pig 명령에 다음 옵션을 추가하십시오.

    pig ...
      -Dmapred.cache.archives=hdfs://host:port/path/GeoIP.dat.zip#GeoIP.dat 
      -Dmapred.create.symlink=yes
    ...
    

    그리고 LookupService lookupService = 새로운 LookupService ( "./ GeoIP.dat"); 파일은 각 노드의 태스크에 로컬로 존재하므로 UDF에서 작동해야합니다.

  4. ==============================

    4.이것은 나를 위해 작동합니다.

    이것은 나를 위해 작동합니다.

    GeoLiteCity.dat가 포함 된 org.foo.bar.util 패키지가 있다고 가정합니다.

    URL fileURL = this.getClass().getResource("org/foo/bar/util/GeoLiteCity.dat");
    File geoIPData = new File(fileURL.toURI());
    LookupService cl = new LookupService(geoIPData, LookupService.GEOIP_MEMORY_CACHE );
    
  5. ==============================

    5.classloader.getResource (...) 메소드를 사용하여 클래스 경로에서 파일 검색을 수행하면 클래스 경로가 JAR 파일에서 가져옵니다.

    classloader.getResource (...) 메소드를 사용하여 클래스 경로에서 파일 검색을 수행하면 클래스 경로가 JAR 파일에서 가져옵니다.

    즉,로드를 재정의하기 위해 기존 코드를 변경해야합니다. 이를 수행하는 방법에 대한 세부 사항은 기존 코드 및 환경에 크게 의존합니다. 어떤 경우에는 하위 클래스를 하위 클래스로 만들고 프레임 워크에 등록하는 것이 효과적 일 수 있습니다. 다른 경우에는 클래스 경로를 따라 클래스 로딩 순서를 결정하고 클래스 패스에 "이전"으로 동일한 서명 된 클래스를 배치해야 할 수도 있습니다.

  6. ==============================

    6.maxmind geoIP를 사용하는 방법은 다음과 같습니다.

    maxmind geoIP를 사용하는 방법은 다음과 같습니다.

    GeoIPCity.dat 파일을 클라우드에 저장하고 프로세스를 시작할 때 클라우드 위치를 인수로 사용합니다. GeoIPCity.data 파일을 가져 와서 새로운 LookupService를 만드는 코드는 다음과 같습니다.

    if (DistributedCache.getLocalCacheFiles(context.getConfiguration()) != null) {
        List<Path> localFiles = Utility.arrayToList(DistributedCache.getLocalCacheFiles(context.getConfiguration()));
        for (Path localFile : localFiles) {
            if ((localFile.getName() != null) && (localFile.getName().equalsIgnoreCase("GeoIPCity.dat"))) {
                m_geoipLookupService = new LookupService(new File(localFile.toUri().getPath()));
            }
        }
    }
    

    다음은 프로세스를 실행하는 데 사용되는 명령의 축약 된 버전입니다.

    $ HADOOP_HOME / bin / hadoop jar /usr/lib/COMPANY/analytics/libjars/MyJar.jar -files hdfs : //PDHadoop1.corp.COMPANY.com : 54310 / data / geoip / GeoIPCity.dat -libjars / usr / lib /COMPANY/analytics/libjars/geoiplookup.jar

    MindMax 구성 요소를 실행하기위한 중요한 구성 요소는 -files 및 -libjars입니다. GenericOptionsParser의 일반 옵션입니다.

    -files <쉼표로 구분 된 파일 목록> 맵에 복사 할 쉼표로 구분 된 파일 지정 reduce cluster -libjars <쉼표로 구분 된 jar 목록> 클래스 경로에 포함시킬 쉼표로 분리 된 jar 파일을 지정하십시오.

    나는 Hadoop이 GenericOptionsParser를 사용한다고 가정하고 있는데, 왜냐하면 프로젝트 내 어디서나 참조를 찾을 수 없기 때문이다. :)

    GeoIPCity.dat를 can에 넣고 -files 인수를 사용하여 GeoIPCity.dat를 지정하면 매퍼가 설정 기능에서 가져올 수있는 로컬 캐시에 저장됩니다. 설치가 필요하지는 않지만 매퍼마다 한 번만 수행하면되므로 배치하는 것이 좋습니다. 그런 다음 -libjars 인수를 사용하여 geoiplookup.jar을 지정하십시오 (또는 귀하가 호출 한 것). 그러면이를 사용할 수 있습니다. 우리는 geoiplookup.jar을 클라우드에 넣지 않습니다. 나는 hadoop이 필요한만큼 항아리를 분배 할 것이라는 가정하에 굴러 가고있다.

    나는 모두가 의미가 있기를 바랍니다. 내가 hadoop / mapreduce에 상당히 익숙해졌지만, 프로젝트에서 maxmind geoip 구성 요소를 사용하는 부분을 작성하지 않았으므로 여기에있는 설명을 충분히 이해하려면 약간 파고해야했습니다.

    편집 : -files 및 -libjars에 대한 추가 설명 -files files 인수는 Hadoop Distributed Cache를 통해 파일을 배포하는 데 사용됩니다. 위의 예에서는 Max Mind geo-ip 데이터 파일을 Hadoop 분산 캐시를 통해 배포합니다. 사용자의 IP 주소를 적절한 국가, 지역, 도시, 시간대에 매핑하려면 Max Mind geo-ip 데이터 파일에 액세스해야합니다. API는 분산 처리 환경에서 가능하지 않은 데이터 파일을 로컬에 존재하도록 요구합니다 (클러스터에서 어떤 노드가 데이터를 처리하는지 보장하지 않습니다). 적절한 데이터를 처리 노드에 배포하기 위해 Hadoop 분산 캐시 인프라를 사용합니다. GenericOptionsParser 및 ToolRunner는 -file 인수를 사용하여이를 자동으로 지원합니다. 배포하는 파일은 클라우드 (HDFS)에서 사용할 수 있어야합니다. -libjars -libjars는 map-reduce 작업에 필요한 추가 종속성을 분배하는 데 사용됩니다. 데이터 파일과 마찬가지로 작업이 실행될 클러스터의 노드에 종속 라이브러리를 복사해야합니다. GenericOptionsParser와 ToolRunner는 -libjars 인수를 사용하여 자동으로이를 용이하게합니다.

  7. from https://stackoverflow.com/questions/4959762/if-i-have-a-constructor-that-requires-a-path-to-a-file-how-can-i-fake-that-if by cc-by-sa and MIT license