2017-09-28 15 views
5

MongoDB 3.2에서 많은 양의 데이터를 읽고이를 Hadoop으로 전송해야하는 Java 애플리케이션이 있습니다.큰 mongodb 데이터 읽기

이 배치 응용 프로그램은 하루에 6 번 4 시간마다 실행됩니다.

데이터 사양 :

  • 서류 : 한 번에 80,000 (4 시간마다)
  • 크기 : 3GB 것은 내가 MongoTemplate을 현재

사용하고 모르핀에서 MongoDB에 액세스하십시오. 사용하여이 데이터를 처리 할 때 내가 OOM 예외를 얻을 그러나 다음

List<MYClass> datalist = datasource.getCollection("mycollection").find().asList(); 

이 데이터를 읽고 하둡에 채울 수있는 가장 좋은 방법은 무엇입니까?

  • MongoTemplate::Stream() 하나씩 작성 하시겠습니까?
  • batchSize(someLimit) 전체 배치를 Hadoop에 쓰시겠습니까?
  • Cursor.batch() 그리고 하나씩 hdfs에 쓰기?

답변

1

귀하의 문제는 메모리에 모든 것을 유지하면서 asList() 전화

이 전체 커서를 통해 (80,000 문서 몇 연주회)를 반복 할 수있는 드라이버를 강제로 자리 잡고 있습니다.

batchSize(someLimit)Cursor.batch()은 배치 크기에 관계없이 커서 전체를 탐색 할 때 도움이 필요합니다. 대신

을 수행 할 수 있습니다

1) 커서 반복 : List<MYClass> datalist = datasource.getCollection("mycollection").find()

2) 문서를 한 번에 하나씩 읽고 버퍼에 문서를 피드 (의)의 목록을 가정 해 봅시다

3) 1000 개의 문서 (Hadoop API)를 호출 할 때마다 버퍼를 지우고 다시 시작하십시오.

0

asList() 호출은 전체 Mongodb 컬렉션을 메모리에로드하려고 시도합니다. 크기가 3GB보다 큰 메모리 목록 개체를 만들려고합니다.

커서를 사용하여 컬렉션을 반복하면이 문제가 해결됩니다. 데이터 소스 클래스를 사용하여이 작업을 수행 할 수 있지만 DAO 클래스에서 제공하는 형식 안전 추상화를 선호합니다.

class Dao extends BasicDAO<Order, String> { 
    Dao(Datastore ds) { 
     super(Order.class, ds); 
    } 
    } 

    Datastore ds = morphia.createDatastore(mongoClient, DB_NAME); 
    Dao dao = new Dao(ds); 

    Iterator<> iterator = dao.find().fetch(); 
    while (iterator.hasNext()) { 
     Order order = iterator.next; 
     hadoopStrategy.add(order); 
    }