2010-06-10 3 views
2

Hadoop 프레임 워크를 사용하여 여러 개의 커다란 자바 직렬 객체 (주문 GB 크기)를 처리 (병합)하는 응용 프로그램을 개발 중입니다. Hadoop 저장소는 파일의 블록을 다른 호스트에 배포합니다. 그러나 deserialization은 모든 블록이 단일 호스트에 존재해야하므로 성능이 크게 향상됩니다. 텍스트 파일과 달리 여러 블록을 개별적으로 처리 할 수없는 상황을 어떻게 처리 할 수 ​​있습니까?Hadoop : 대규모 직렬화 된 객체 처리

답변

3

두 가지 문제가 있습니다. 하나는 각 파일을 (초기 단계에서) 전체적으로 처리해야한다는 것입니다. 첫 번째 바이트를 보는 매퍼는 해당 파일의 나머지 부분을 모두 처리해야합니다. 다른 문제는 지역성입니다. 효율성을 극대화하려면 각 파일에 대한 모든 블록을 동일한 호스트에 배치해야합니다. 전체에서


처리 파일 :

하나의 간단한 트릭은 제 1 단계 매퍼 과정을 파일 이름이 아니라 그 내용의 목록을하는 것입니다. 50 개의 맵 작업을 실행하려면 파일 이름 중 해당 부분을 50 개씩 만듭니다. 이것은 쉽고 java 또는 스트리밍과 함께 작동합니다.

또는 분할 가능하지 않은 입력 형식 (예 : NonSplitableTextInputFormat)을 사용하십시오.

자세한 내용은 hadoop 위키의 "How do I process files, one per map?"및 "How do I get each of my maps to work on one complete input-file?"을 참조하십시오.


소재지 :

이 문제 잎

은, 그러나, 당신은에서 읽고있는 블록이 모든 HDFS에 걸쳐 disributed됩니다 : 일반적으로 여기에 성능 향상, 진짜 문제. HDFS에서 특정 블록을 함께 연결하는 방법이 있다고는 생각하지 않습니다.

각 노드의 로컬 스토리지에 파일을 저장할 수 있습니까? 실제로이를 해결하는 가장 효과적이고 쉬운 방법은 각 컴퓨터가 모든 파일을 처리하기 위해 작업을 시작하도록하는 것입니다. /data/1/**/*.data (로컬 파티션과 CPU 코어 수를 효율적으로 사용하는 것이 중요합니다.)

파일이 SAN에서 시작되었거나 s3에서 시작된 것이라면 바로 거기에서 직접 잡아 당겨보십시오. 즉, 웜을 처리하도록 제작되었습니다.


최초의 트릭을 사용에 대한주의 사항 : 파일 중 일부가 다른 사람보다 훨씬 더 큰 경우, 투기 적 실행에 문제를 피하기 위해, 초기 이름의 목록에 혼자 넣어. 어쨌든 작업이 신뢰할 수 있고 여러 번 처리 된 일부 일괄 처리를 원하지 않는 경우 그런 작업에 대한 추측 실행을 해제 할 수 있습니다.

2

기본 (도움이되지 않는) 대답은 MapReduce 패러다임에 직접 맞 닿아 실제로 수행 할 수 없다는 것입니다. 매퍼와 리듀서의 입력 및 출력 단위는 비교적 작은 레코드입니다. Hadoop은 디스크의 파일 블록이 아니라 이러한 측면에서 작동합니다.

귀하의 프로세스가 모든 호스트에 하나씩 필요합니까? 내가 병합으로 설명 할 수있는 것은 그러한 요구 사항이없는 MapReduce처럼 아주 깨끗하게 구현 될 수 있습니다.

특정 감축기에서 특정 키 (및 해당 값)가되도록하려면 Partitioner을 사용하여 감속기 인스턴스에 키가 매핑되는 방법을 정의 할 수 있습니다. 귀하의 상황에 따라, 이것은 귀하가 실제로있는 것일 수 있습니다.

Hadoop MapReduce를 쓰는 대신 HDFS 파일을 조작하려고하는 것처럼 들립니다. 아마 HDFS에 여러 개의 SequenceFile을 열어 놓고 레코드를 읽고 수동으로 병합하는 방법에 관한 질문 일 수도 있습니다. 이것은 Hadoop 질문이 아니지만 한 호스트에 블록이 필요하지는 않습니다.

+0

내 질문을 다시 말해 보겠습니다. 따라서 일반적으로 입력 파일에서 부분적으로 읽고 (텍스트 파일에서와 같이) Mapper 함수로 처리 할 수 ​​있습니다. 필자는 두 개의 Mapper 함수를 사용하려고합니다. 처음에는 이진 파일을 더 작은 (키, 값) 쌍으로 분할하고 두 번째 파일은 더 전통적인 Mapper 용도로 분할합니다. 내 질문은 처리를 시작하기 전에 모든 블록이 동일한 호스트에 있어야하는 바이너리 (이미지, 직렬화 된 오브젝트)를 처리하기 위해 할 수있는 작업입니다. 희망은 내 문제를 설명합니다. 귀하의 답변에 감사드립니다. – restrictedinfinity

+1

모든 블록이 하나의 호스트에 있어야한다고 생각하지 않습니다. 작업자가 HDFS에서 충분한 블록을 전송하여 적어도 하나의 전체 레코드를 읽도록 요구합니다. 하지만 결국 데이터가 근로자에게 최종적으로 도달해야합니다. HDFS가 처리하도록합시다. –

3

입력 파일에 하나의 커다란 직렬화 된 개체가있는 것 같습니다. 그럴까요? 각 항목을 간단한 키로 일련 화 된 값으로 만들 수 있습니까?

예를 들어 이미지의 크기를 병렬화하기 위해 Hadoop을 사용하려는 경우 각 이미지를 개별적으로 직렬화하고 간단한 색인 키를 가질 수 있습니다. 입력 파일은 키 값 쌍이 색인 키인 텍스트 파일이고 직렬화 된 BLOB는 값이됩니다.

하둡에서 시뮬레이션을 수행 할 때이 방법을 사용합니다. 내 직렬화 된 얼룩은 시뮬레이션에 필요한 모든 데이터이며 키는 단순히 시뮬레이션 번호를 나타내는 정수입니다. 이를 통해 그리드 엔진과 같은 Hadoop (특히 Amazon Elastic Map Reduce)을 사용할 수 있습니다.