如何使用MR来读取数据库的数据,并写入HDFS上

在我们的一些应用程序中,常常避免不了要与数据库进行交互,而在我们的hadoop中,有时候也需要和数据库进行交互,比如说,数据分析的结果存入数据库,或者是,读取数据库的信息写入HDFS上,不过直接使用MapReduce操作数据库,这种情况在现实开发还是比较少,一般我们会采用Sqoop来进行数据的迁入,迁出,使用Hive分析数据集,大多数情况下,直接使用Hadoop访问关系型数据库,可能产生比较大的数据访问压力,尤其是在数据库还是单机的情况下,情况可能更加糟糕,在集群的模式下压力会相对少一些。

那么,今天散仙就来看下,如何直接使用Hadoop1.2.0的MR来读写操作数据库,hadoop的API提供了DBOutputFormat和DBInputFormat这两个类,来进行与数据库交互,除此之外,我们还需要定义一个类似JAVA Bean的实体类,来与数据库的每行记录进行对应,通常这个类要实现Writable和DBWritable接口,来重写里面的4个方法以对应获取每行记录里面的各个字段信息。

下面,我们先来看下如何使用MR来读取数据库的数据,并写入HDFS上,
数据表的截图如下所示,



实体类定义代码:

Java代码 复制代码  收藏代码
  1. package com.qin.operadb;  
  2.   
  3. import java.io.DataInput;  
  4. import java.io.DataOutput;  
  5. import java.io.IOException;  
  6. import java.sql.PreparedStatement;  
  7. import java.sql.ResultSet;  
  8. import java.sql.SQLException;  
  9.   
  10. import org.apache.hadoop.io.Text;  
  11. import org.apache.hadoop.io.Writable;  
  12. import org.apache.hadoop.mapreduce.lib.db.DBWritable;  
  13.    
  14. /*** 
  15.  * 封装数据库实体信息 
  16.  * 的记录 
  17.  *  
  18.  * 搜索大数据技术交流群:376932160 
  19.  *  
  20.  * **/  
  21. public class PersonRecoder implements Writable,DBWritable {  
  22.   
  23.     public int id;//对应数据库中id字段  
  24.     public String name;//对应数据库中的name字段  
  25.     public int age;//对应数据库中的age字段  
  26.       
  27.       
  28.       
  29.       
  30.     @Override  
  31.     public void readFields(ResultSet result) throws SQLException {  
  32.       
  33.           
  34.         this.id=result.getInt(1);  
  35.         this.name=result.getString(2);  
  36.         this.age=result.getInt(3);  
  37.           
  38.     }  
  39.   
  40.     @Override  
  41.     public void write(PreparedStatement stmt) throws SQLException {  
  42.           
  43.         stmt.setInt(1, id);  
  44.         stmt.setString(2, name);  
  45.         stmt.setInt(3, age);  
  46.           
  47.     }  
  48.   
  49.     @Override  
  50.     public void readFields(DataInput arg0) throws IOException {  
  51.         // TODO Auto-generated method stub  
  52.         this.id=arg0.readInt();  
  53.         this.name=Text.readString(arg0);  
  54.         this.age=arg0.readInt();  
  55.           
  56.     }  
  57.   
  58.     @Override  
  59.     public void write(DataOutput out) throws IOException {  
  60.         // TODO Auto-generated method stub  
  61.         out.writeInt(id);  
  62.         Text.writeString(out, this.name);  
  63.         out.writeInt(this.age);  
  64.     }  
  65.       
  66.       
  67.     @Override  
  68.     public String toString() {  
  69.         // TODO Auto-generated method stub  
  70.         return "id: "+id+"  年龄: "+age+"   名字:"+name;  
  71.     }  
  72.       
  73.   
  74. }  
package com.qin.operadb;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.mapreduce.lib.db.DBWritable;
 
/***
 * 封装数据库实体信息
 * 的记录
 * 
 * 搜索大数据技术交流群:376932160
 * 
 * **/
public class PersonRecoder implements Writable,DBWritable {

	public int id;//对应数据库中id字段
	public String name;//对应数据库中的name字段
	public int age;//对应数据库中的age字段
	
	
	
	
	@Override
	public void readFields(ResultSet result) throws SQLException {
	
		
		this.id=result.getInt(1);
		this.name=result.getString(2);
		this.age=result.getInt(3);
		
	}

	@Override
	public void write(PreparedStatement stmt) throws SQLException {
		
		stmt.setInt(1, id);
		stmt.setString(2, name);
		stmt.setInt(3, age);
		
	}

	@Override
	public void readFields(DataInput arg0) throws IOException {
		// TODO Auto-generated method stub
		this.id=arg0.readInt();
		this.name=Text.readString(arg0);
		this.age=arg0.readInt();
		
	}

	@Override
	public void write(DataOutput out) throws IOException {
		// TODO Auto-generated method stub
		out.writeInt(id);
		Text.writeString(out, this.name);
		out.writeInt(this.age);
	}
	
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "id: "+id+"  年龄: "+age+"   名字:"+name;
	}
	

}


MR类的定义代码,注意是一个Map Only作业:

Java代码 复制代码  收藏代码
  1. package com.qin.operadb;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import org.apache.hadoop.conf.Configuration;  
  6. import org.apache.hadoop.fs.FileSystem;  
  7. import org.apache.hadoop.fs.Path;  
  8. import org.apache.hadoop.io.LongWritable;  
  9. import org.apache.hadoop.io.Text;  
  10. import org.apache.hadoop.mapred.JobConf;  
  11. import org.apache.hadoop.mapred.lib.IdentityReducer;  
  12. import org.apache.hadoop.mapreduce.Job;  
  13. import org.apache.hadoop.mapreduce.Mapper;  
  14. import org.apache.hadoop.mapreduce.lib.db.DBConfiguration;  
  15. import org.apache.hadoop.mapreduce.lib.db.DBInputFormat;  
  16. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  17.   
  18. public class ReadMapDB {  
  19.       
  20.       
  21.       
  22.     /** 
  23.      * Map作业读取数据记录数 
  24.      *  
  25.      * **/  
  26.     private static class DBMap extends Mapper<LongWritable, PersonRecoder    , LongWritable, Text>{  
  27.         @Override  
  28.         protected void map(LongWritable key, PersonRecoder value,Context context)  
  29.                 throws IOException, InterruptedException {  
  30.            
  31.             context.write(new LongWritable(value.id), new Text(value.toString()));  
  32.            
  33.         }  
  34.     }  
  35.       
  36.     public static void main(String[] args)throws Exception {  
  37.           
  38.           
  39.          JobConf conf=new JobConf(ReadMapDB.class);  
  40.         //Configuration conf=new Configuration();  
  41.        //   conf.set("mapred.job.tracker","192.168.75.130:9001");  
  42.         //读取person中的数据字段  
  43.      // conf.setJar("tt.jar");  
  44.            
  45.         //注意这行代码放在最前面,进行初始化,否则会报  
  46.         DBConfiguration.configureDB(conf, "com.mysql.jdbc.Driver""jdbc:mysql://192.168.211.36:3306/test""root""qin");  
  47.           
  48.         /**要读取的字段信息**/  
  49.         String fileds[]=new String[]{ "id","name","age"};  
  50.         /**Job任务**/  
  51.         Job job=new Job(conf, "readDB");  
  52.         System.out.println("模式:  "+conf.get("mapred.job.tracker"));  
  53.           
  54.         /**设置数据库输入格式的一些信息**/  
  55.         DBInputFormat.setInput(job, PersonRecoder.class"person"null"id", fileds);  
  56.         /***设置输入格式*/  
  57.         job.setInputFormatClass(DBInputFormat.class);  
  58.         job.setOutputKeyClass(LongWritable.class);  
  59.         job.setOutputValueClass(Text.class);  
  60.         job.setMapperClass(DBMap.class);  
  61.         String path="hdfs://192.168.75.130:9000/root/outputdb";  
  62.         FileSystem fs=FileSystem.get(conf);  
  63.         Path p=new Path(path);  
  64.         if(fs.exists(p)){  
  65.             fs.delete(p, 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值