本節將使用MongoInputFormat類加載MongoDB中的數據導入HDFS中。
準備工作
使用Mongo Hadoop適配器最簡單的方法是從GitHub上克隆Mongo-Hadoop工程,並且將該工程編譯到一個特定的Hadoop版本。克隆該工程需要安裝一個Git客戶端。
本節假定你使用的Hadoop版本是CDH3。
Git客戶端官方的下載地址是:http://git-scm.com/downloads。
在Windows操作系統上可以通過http://windows.github.com/訪問GitHub。
在Mac操作系統上可以通過http://mac.github.com/訪問GitHub。
可以通過https://github.com/mongodb/mongo-hadoop獲取到Mongo Hadoop適配器。該工程需要編譯在特定的Hadoop版本上。編譯完的JAR文件需要複製到Hadoop集羣每個節點的$HADOOP_HOME/lib目錄下。
Mongo Java驅動包也需要安裝到Hadoop集羣每個節點的$HADOOP_HOME/lib目錄下。該驅動包可從https://github.com/mongodb/mongo-java-driver/downloads下載。
操作步驟
完成下面步驟實現將MongoDB中的數據複製到HDFS中。 通過下面的命令實現克隆mongo-hadoop工程:
- git clone https://github.com/mongodb/mongo-hadoop.git
切換到穩定發佈的1.0分支版本:
- git checkout release-1.0
必須保持mongo-hadoop與Hadoop的版本一致。使用文本編輯器打開mongo- hadoop克隆目錄下的build.sbt文件,修改下面這行:
- hadoopRelease in ThisBuild := "default"
修改爲:
- hadoopRelease in ThisBuild := "cdh3"
編譯mongo-hadoop:
- ./sbt package.
這將會在core/target文件夾下生成一個名爲mongo-hadoop-core_cdh3u3-1.0.0.jar的JAR文件。 從https://github.com/mongodb/mongo-java-driver/downloads下載MongoDB 2.8.0版本的Java驅動包。
複製mongo-hadoop和MongoDB Java驅動包到Hadoop集羣每個節點的$HADOOP_ HOME/lib:
- cp mongo-hadoop-core_cdh3u3-1.0.0.jar mongo-2.8.0.jar $HADOOP_HOME/lib
編寫MapReduce讀取MongoDB數據庫中的數據並寫入HDFS中:
- import java.io.*;
- import org.apache.commons.logging.*;
- import org.apache.hadoop.conf.*;
- import org.apache.hadoop.fs.Path;
- import org.apache.hadoop.io.*;
- import org.apache.hadoop.mapreduce.lib.output.*;
- import org.apache.hadoop.mapreduce.*;
- import org.bson.*;
- import com.mongodb.hadoop.*;
- import com.mongodb.hadoop.util.*;
- public class ImportWeblogsFromMongo {
- private static final Log log = LogFactory.
- getLog(ImportWeblogsFrom Mongo.class);
- public static class ReadWeblogsFromMongo extends Mapper<Object, BSONObject, Text, Text>{
- public void map(Object key, BSONObject value, Context context) throws IOException, InterruptedException{
- System.out.println("Key: " + key);
- System.out.println("Value: " + value);
- String md5 = value.get("md5").toString();
- String url = value.get("url").toString();
- String date = value.get("date").toString();
- String time = value.get("time").toString();
- String ip = value.get("ip").toString();
- String output = "\t" + url + "\t" + date + "\t" +
- time + "\t" + ip;
- context.write( new Text(md5), new Text(output));
- }
- }
- public static void main(String[] args) throws Exception{
- final Configuration conf = new Configuration();
- MongoConfigUtil.setInputURI(conf, "mongodb://<HOST>:<PORT>/test.weblogs");
- MongoConfigUtil.setCreateInputSplits(conf, false);
- System.out.println("Configuration: " + conf);
- final Job job = new Job(conf, "Mongo Import");
- Path out = new Path("/data/weblogs/mongo_import");
- FileOutputFormat.setOutputPath(job, out);
- job.setJarByClass(ImportWeblogsFromMongo.class);
- job.setMapperClass(ReadWeblogsFromMongo.class);
- job.setOutputKeyClass(Text.class);
- job.setOutputValueClass(Text.class);
- job.setInputFormatClass(MongoInputFormat.class);
- job.setOutputFormatClass(TextOutputFormat.class);
- job.setNumReduceTasks(0);
- System.exit(job.waitForCompletion(true) ? 0 : 1 );
- }
- }
這個只有map的作業用到了Mongo Hadoop適配器提供的幾個類。從HDFS讀入的數據會被轉換成一個BSONObject對象。該類描述的是一個二進制的JSON值。MongoDB使用這些BSONObject對象來有效地序列化、傳輸和存儲數據。
Mongo Hadoop適配器還提供了一個方便的工具類MongoConfigUtil,使得可以把MongoDB當成是一個文件系統來訪問。 導出爲一個可運行的JAR文件,並運行該作業:
hadoop jar ImportWeblogsFromMongo.jar 驗證weblogs數據是否已經導入HDFS中:
- hadoop fs -ls /data/weblogs/mongo_import
工作原理
Mongo Hadoop適配器提供了一種新的兼容Hadoop的文件系統實現,包括MongoInput Format和MongoOutputFormat。這些抽象實現使得訪問MongoDB和訪問任何兼容Hadoop的文件系統一樣。