7

概括:

是否有可能:

  1. 使用 «MongoDB Connector for Hadoop» 将数据导入 Hadoop。
  2. 使用 Hadoop MapReduce 处理它。
  3. 在单个事务中使用 Sqoop 将其导出。

我正在使用 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 数据库中。

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

4

3 回答 3

10

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

 job.setOutputFormatClass( DBOutputFormat.class );

需要注意的几点:

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

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

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

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

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

  4. 事实上,据我从«MongoDB Connector for Hadoop»:examples中了解,可以在org.apache.hadoop.mapred.lib.db.DBOutputFormat您的 Hadoop MapReduce 作业中指定 a 以将输出写入 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 回答
0

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

于 2013-08-12T16:02:33.990 回答
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)处理数据 -> 将其存储到 hive 表/HDFS -> 使用 sqoop 将数据导出到 mysql。

于 2014-06-03T11:36:59.777 回答