2011-10-06 1 views
4

임 다이빙을 분할로 HDFS에 저장된 파일을 배우려고 노력하고 다른 프로세스로 읽는 똑같이 크기의 파일을 분할 (다른 시스템에.)하둡은

내가 기대하는 것은 내가 1200 개 기록을 포함하는 SequenceFile이있는 경우 12 프로세스에서는 프로세스 당 약 100 개의 레코드가 표시됩니다. 파일을 분할하는 방법은 데이터의 길이를 구한 다음 프로세스 수로 나누고 각 분할에 대한 청크/시작/끝 크기를 얻은 다음 해당 분할을 예를 들어로 전달하는 것입니다. SequenceFileRecordReader, 간단한 while 루프에서 레코드 검색 : 코드는 다음과 같습니다.

private InputSplit getSplit(int id) throws IOException { 
... 
    for(FileStatus file: status) { 
     long len = file.getLen(); 
     BlockLocation[] locations = 
      fs.getFileBlockLocations(file, 0, len); 
     if (0 < len) { 
      long chunk = len/n; 
      long beg = (id*chunk)+(long)1; 
      long end = (id)*chunk; 
      if(n == (id+1)) end = len; 
      return new FileSplit(file, beg, end, locations[locations.length-1].getHosts()); 
     } 
    } 
... 
} 

그러나 결과적으로 각 프로세스에서 계산 된 총 레코드의 합계가 파일에 저장된 레코드와 다릅니다. SequenceFile을 균일하게 덩어리로 나누어 다른 호스트에 배포하는 올바른 방법은 무엇입니까?

감사합니다.

답변

4

나는 왜 그런 일을하려고하는지 궁금해하지 않을 수 있습니다. Hadoop은 파일을 자동으로 분할하고 1200 개의 레코드를 100 개의 레코드로 분할하여 많은 양의 데이터처럼 들리지 않습니다. 자신의 문제가 무엇인지 자세히 설명해 주면 누군가가 더 직접적으로 당신을 도울 수 있습니다.


옵션 1 :

하둡 자동으로 파일을 분할 사용 하둡의 자동 분할 동작 여기

내 두 개의 아이디어입니다. 파일이 분할되는 블록 수는 파일의 전체 크기를 블록 크기로 나눈 값입니다. 기본적으로 하나의 맵 작업이 각 파일이 아닌 각 블록에 지정됩니다.

conf/hdfs-site.xml 구성 파일에는 dfs.block.size 매개 변수가 있습니다. 대부분의 사람들은 이것을 64 또는 128MB로 설정합니다. 그러나 블록 당 100 개의 시퀀스 파일 레코드와 같이 작은 작업을 수행하려는 경우이 값을 1000 바이트로 설정할 수 있습니다. 나는 이것을 원한 사람은 들어 본 적이 없지만 선택 사항입니다.


옵션 2 : MapReduce 작업을 사용하여 데이터를 분할하십시오.

"신원 매퍼"를 사용하십시오 (기본적으로 매퍼를 구현하고 map을 무시하지 마십시오). 또한 직업에 "신원 감속기"(기본적으로 감속기를 구현하고 reduce을 무시하지 마십시오)를 사용하십시오. 축소 자 수를 원하는 분할 수로 설정하십시오. 세 개의 시퀀스 파일을 총 25 개의 파일로 나누고 싶다면 3 개의 파일을로드하고 25 개의 감속기를 25 개로 설정하십시오. 각 감속기에 무작위로 레코드가 전송되며 최종 결과는 다음과 같습니다. 균등 분할.

신원 매퍼와 축소 기가 실제로 아무 것도하지 않기 때문에이 방법이 효과가 있습니다. 따라서 레코드는 그대로 유지됩니다. 기록은 무작위 감속기로 보내지고 감속기 당 하나의 파일은 part-r-xxxx 개의 파일로 기록됩니다. 각 파일에는 시퀀스 파일이 다소 덩어리로 나뉘어 있습니다.