7

概要:

次のことは可能ですか。

  1. «MongoDB Connector for Hadoop» を使用して Hadoop にデータをインポートします。
  2. Hadoop MapReduce で処理します。
  3. 単一のトランザクションで Sqoop を使用してエクスポートします。

MongoDB で Web アプリケーションを構築しています。MongoDB はほとんどの作業でうまく機能しますが、一部の部分ではより強力なトランザクション保証が必要であり、そのために MySQL データベースを使用しています。

私の問題は、データ分析のために大きな MongoDB コレクションを読み取りたいのですが、コレクションのサイズが大きいため、分析ジョブの処理に時間がかかりすぎることです。残念ながら、MongoDB に組み込まれている map-reduce フレームワークはこのジョブにはうまく機能しないため、Apache Hadoopで分析を実行することをお勧めします。

MongoDBからデータを読み取り、Hadoop で MapReduce を使用して処理し、最終的に結果を MongoDB データベースに出力する«MongoDB Connector for Hadoop»を使用して、MongoDB から Hadoop にデータを読み取ることができることを理解しています。

問題は、結果を他の MySQL テーブルとマージする必要があるため、MapReduce の出力を MongoDB ではなく MySQL データベースに入れたいことです。

この目的のために、Sqoop は Hadoop MapReduce の結果を MySQL にエクスポートできることを知っています。

最終的には、MongoDB データを読み込んで Hadoop で処理し、最終的に結果を MySQL データベースに出力したいと考えています。

これは可能ですか?これを行うために利用できるツールはどれですか?

4

3 に答える 3

10

TL; DR: HadoopジョブでRDBSに書き込む出力フォーマッターを設定します。

 job.setOutputFormatClass( DBOutputFormat.class );

注意すべきいくつかの事柄:

  1. Sqoopを使用してMongoDBからHadoopにデータをエクスポートすることはできません。これは、SqoopがSQLベースのデータベースに呼び出しレベルのAPIを提供するJDBCを使用しているが、MongoDBはSQLベースのデータベースないためです。この作業を行うには、«MongoDB ConnectorforHadoop»を参照してください。コネクタはGitHubで入手できます。(編集:アップデートで指摘したとおりです。)

  2. Sqoopのエクスポートは、デフォルトでは1つのトランザクションで行われません。代わりに、Sqoopのドキュメントによると:

    Sqoopはエクスポートプロセスを複数のトランザクションに分割するため、エクスポートジョブが失敗すると、部分的なデータがデータベースにコミットされる可能性があります。これにより、場合によっては挿入の衝突が原因で後続のジョブが失敗したり、他の場合にはデータが重複したりする可能性があります。この問題は、--staging-tableエクスポートされたデータをステージングするために使用される補助テーブルとして機能するオプションを介してステージングテーブルを指定することで解決できます。ステージングされたデータは、最終的に1回のトランザクションで宛先テーブルに移動されます。

  3. «Hadoop用のMongoDBコネクタ»は、あなたが説明するワークフローを強制するようには見えません。ドキュメントによると:

    この接続は、MongoDBデータをHadoopに読み取ること(MapReduceジョブおよびHadoopエコシステムの他のコンポーネントで使用するため)と、Hadoopジョブの結果をMongoDBに書き出すことの両方を可能にするという形をとります。

  4. 実際、«Hadoop用MongoDBコネクタ»の例org.apache.hadoop.mapred.lib.db.DBOutputFormatから理解できる限り、Hadoop MapReduceジョブにを指定して、出力をMySQLデータベースに書き込むことができます。コネクタリポジトリの例に従います。

    job.setMapperClass( TokenizerMapper.class );
    job.setCombinerClass( IntSumReducer.class );
    job.setReducerClass( IntSumReducer.class );
    job.setOutputKeyClass( Text.class );
    job.setOutputValueClass( IntWritable.class );
    job.setInputFormatClass( MongoInputFormat.class );
    /* Instead of:
     * job.setOutputFormatClass( MongoOutputFormat.class );
     * we use an OutputFormatClass that writes the job results 
     * to a MySQL database. Beware that the following OutputFormat 
     * will only write the *key* to the database, but the principle
     * remains the same for all output formatters
     */
    job.setOutputFormatClass( DBOutputFormat.class );
    
于 2012-04-01T15:56:20.427 に答える