2017-09-28 9 views
5

MongoDB 3.2から大量のデータを読み込んでHadoopに転送する必要のあるJavaアプリケーションがあります。大きなmongodbデータを読む

このバッチアプリケーションは、1日に6回、4時間ごとに実行されます。

データ仕様:

  • ドキュメント:時間(4時間ごと)で80000
  • サイズ:現在、私はMongoTemplateMorphiaを使用しています

を3GB MongoDBにアクセスする。 次を使用して、このデータを処理するとき、私はOOM例外を取得しかし:

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

このデータを読み、Hadoopのに移入するための最良の方法は何ですか?

  • MongoTemplate::Stream() 1つずつHadoopに書き込みますか?
  • batchSize(someLimit)そして、バッチ全体をHadoopに書き込んでください。
  • Cursor.batch()と1つずつhdfsに書き込みますか?

答えて

1

あなたの問題はasList()コール

であるこれは、メモリ内のすべてを維持する、全体のカーソル(8万ドキュメント数ギグ)を反復処理するドライバを強制します。

batchSize(someLimit)およびCursor.batch()は、バッチサイズに関係なく、カーソル全体を走査する際に役立ちます。

代わりにすることができます:

1)は、カーソルを反復処理:List<MYClass> datalist = datasource.getCollection("mycollection").find()

2)一度に文書1を読み、バッファに文書を送り(

3)のリストを言わせて) Hadoop APIを1000のドキュメントごとに呼び出す場合は、バッファをクリアしてから、もう一度やり直してください。

0

asList()コールは、Mongodbコレクション全体をメモリにロードしようとします。メモリリストオブジェクトを3GB以上の大きさにしようとしています。

カーソルを使用してコレクションを反復すると、この問題が解決されます。これはDatasourceクラスで行うことができますが、Morphiaが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); 
    } 
関連する問題