是否可以读取MongoDB数据,使用Hadoop处理它,并将其输出到RDBS(MySQL)?

时间:2012-04-01 15:05:38

标签: mysql mongodb hadoop sqoop

  

要点:

     

是否可以:

     
      
  1. 使用«MongoDB Connector for Hadoop»将数据导入Hadoop。
  2.   
  3. 使用Hadoop MapReduce处理它。
  4.   
  5. 在一次交易中使用Sqoop导出它。
  6.   

我正在用MongoDB构建一个Web应用程序。虽然MongoDB适用于大多数工作,但在某些部分我需要更强的事务保证,我使用MySQL数据库。

我的问题是我想阅读一个大的MongoDB集合进行数据分析,但是集合的大小意味着分析工作需要很长时间才能处理。遗憾的是,MongoDB的内置map-reduce框架不适合这项工作,所以我更愿意用Apache Hadoop进行分析。

我知道可以使用«MongoDB Connector for Hadoop»从MongoDB读取数据到Hadoop,它从MongoDB读取数据,在Hadoop中使用MapReduce处理它,最后将结果输出回MongoDB数据库。

问题在于我希望MapReduce的输出进入MySQL数据库而不是MongoDB,因为结果必须与其他MySQL表合并。

为此,我知道Sqoop可以将Hadoop MapReduce的结果导出到MySQL中。

最终,我想读取MongoDB数据然后用Hadoop处理它,最后将结果输出到MySQL数据库。

这可能吗?有哪些工具可以做到这一点?

3 个答案:

答案 0 :(得分:10)

  

TL; DR:设置一个输出格式化程序,写入Hadoop作业中的RDBS:

 job.setOutputFormatClass( DBOutputFormat.class );

有几点需要注意:

  1. 无法使用Sqoop将数据从MongoDB导出到Hadoop。这是因为Sqoop使用JDBC基于SQL的数据库提供调用级API,但MongoDB 不是基于SQL的数据库。您可以查看«MongoDB Connector for Hadoop»来完成这项工作。连接器可用on GitHub。 (编辑:正如您在更新中指出的那样。)

  2. 默认情况下,Sqoop导出不会在单个事务中进行。相反,根据Sqoop docs

      

    由于Sqoop将导出过程分解为多个事务,因此失败的导出作业可能会导致将部分数据提交到数据库。这可能进一步导致后续作业由于某些情况下的插入冲突而失败,或导致其他作业中的重复数据。您可以通过--staging-table选项指定登台表来解决此问题,该选项充当用于暂存导出数据的辅助表。分阶段数据最终在单个事务中移动到目标表。

  3. «MongoDB Connector for Hadoop»似乎没有强制您描述的工作流程。根据文件:

      

    这种连接的形式是允许将MongoDB数据读入Hadoop(用于MapReduce作业以及Hadoop生态系统的其他组件),以及将Hadoop作业的结果写入MongoDB。

  4. 实际上,据我所知«MongoDB Connector for Hadoop»: examples,可以在Hadoop MapReduce作业中指定org.apache.hadoop.mapred.lib.db.DBOutputFormat来将输出写入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 );
    

答案 1 :(得分:0)

我建议你看看Apache Pig(它运行在Hadoop的map-reduce之上)。它将输出到MySql(不需要使用Scoop)。我用它来做你所描述的。可以使用Pig和MySql进行“upsert”。你可以使用Pig的STORE命令和piggyBank的DBStorage和MySql的INSERT DUPLICATE KEY UPDATE(http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html)。

答案 2 :(得分:0)

使用MongoHadoop连接器从MongoDB读取数据并使用Hadoop处理它。

链接: https://github.com/mongodb/mongo-hadoop/blob/master/hive/README.md

使用此连接器,您可以使用Pig和Hive从Mongo db读取数据并使用Hadoop处理它。

Mongo Hive表的示例:

  CREATE EXTERNAL TABLE TestMongoHiveTable
    ( 
    id STRING,
    Name STRING
    )
    STORED BY 'com.mongodb.hadoop.hive.MongoStorageHandler'
    WITH SERDEPROPERTIES('mongo.columns.mapping'='{"id":"_id","Name":"Name"}')
    LOCATION '/tmp/test/TestMongoHiveTable/' 
    TBLPROPERTIES('mongo.uri'='mongodb://{MONGO_DB_IP}/userDetails.json');

将它导出到hive表后,您可以使用Sqoop或Pig将数据导出到mysql。

这是一个流程。

Mongo DB - >使用Mongo DB hadoop连接器(Pig)处理数据 - >将其存储到蜂巢桌/ HDFS - >使用sqoop将数据导出到mysql。