Hadoop,MapReduce操作Mysql
前以前帖子介绍,怎样读取文本数据源和多个数据源的合并:http://www.cnblogs.com/liqizhou/archive/2012/05/15/2501835.html
这一个博客介绍一下MapReduce怎样读取关系数据库的数据,选择的关系数据库为MySql,因为它是开源的软件,所以大家用的比较多。以前上学的时候就没有用过开源的软件,直接用盗版,也相当与免费,且比开源好用,例如向oracle,windows7等等。现在工作了,由于公司考虑成本的问题,所以都用成开源的,ubuntu,mysql等,本人现在支持开源,特别像hadoop这样的东西,真的太好了,不但可以使用软件,也可以读到源代码。话不说多了。
hadoop技术推出一首曾遭到关系数据库研究者的挑衅和批评,认为MapReduce不具有关系数据库中的结构化数据存储和处理能力。为此,hadoop社区和研究人员做了多的努力,在hadoop0.19版支持MapReduce访问关系数据库,如:mysql,MySQL、PostgreSQL、Oracle 等几个数据库系统。
1. 从Mysql读出数据
Hadoop访问关系数据库主要通过一下接口实现的:DBInputFormat类,包所在位置:org.apache.hadoop.mapred.lib.db 中。DBInputFormat 在 Hadoop 应用程序中通过数据库供应商提供的 JDBC接口来与数据库进行交互,并且可以使用标准的 SQL 来读取数据库中的记录。学习DBInputFormat首先必须知道二个条件。
在使用 DBInputFormat 之前,必须将要使用的 JDBC 驱动拷贝到分布式系统各个节点的$HADOOP_HOME/lib/目录下。
- MapReduce访问关系数据库时,大量频繁的从MapReduce程序中查询和读取数据,这大大的增加了数据库的访问负载,因此,DBInputFormat接口仅仅适合读取小数据量的数据,而不适合处理数据仓库。要处理数据仓库的方法有:利用数据库的Dump工具将大量待分析的数据输出为文本,并上传的Hdfs中进行处理,处理的方法可参考:http://www.cnblogs.com/liqizhou/archive/2012/05/15/2501835.html
 
DBInputFormat 类中包含以下三个内置类
- protected class DBRecordReader implementsRecordReader<LongWritable, T>:用来从一张数据库表中读取一条条元组记录。
 - 2.public static class NullDBWritable implements DBWritable,Writable:主要用来实现 DBWritable 接口。DBWritable接口要实现二个函数,第一是write,第二是readFileds,这二个函数都不难理解,一个是写,一个是读出所有字段。原型如下:
public void write(PreparedStatement statement) throwsSQLException;
public void readFields(ResultSet resultSet) throws SQLException; - protected static class DBInputSplit implements InputSplit:主要用来描述输入元组集合的范围,包括 start 和 end 两个属性,start 用来表示第一条记录的索引号,end 表示最后一条记录的索引号.
 
下面对怎样使用 DBInputFormat 读取数据库记录进行详细的介绍,具体步骤如下:
DBConfiguration.configureDB (JobConf job, StringdriverClass, String dbUrl, String userName, String passwd)函数,配置JDBC 驱动,数据源,以及数据库访问的用户名和密码。MySQL 数据库的 JDBC 的驱动为“com.mysql.jdbc.Driver”,数据源为“jdbc:mysql://localhost/testDB”,其中testDB为访问的数据库。useName一般为“root”,passwd是你数据库的密码。
DBInputFormat.setInput(JobConf job, Class<?extends DBWritable> inputClass, String tableName, String conditions,String orderBy, String... fieldNames),这个方法的参数很容易看懂,inputClass实现DBWritable接口。,string tableName表名, conditions表示查询的条件,orderby表示排序的条件,fieldNames是字段,这相当与把sql语句拆分的结果。当然也可以用sql语句进行重载。etInput(JobConf job, Class<?extends DBWritable> inputClass, String inputQuery, StringinputCountQuery)。
- 编写MapReduce函数,包括Mapper 类、Reducer 类、输入输出文件格式等,然后调用JobClient.runJob(conf)。
 
上面讲了理论,下面举个例子:假设 MySQL 数据库中有数据库student,假设数据库中的字段有“id”,“name”,“gender","number"。
第一步要实现DBwrite和write数据接口。代码如下:

        public class StudentRecord implements Writable, DBWritable{
            int id;
            String name;
            String gender;
            String number;
            @Override
        public void readFields(DataInput in) throws IOException {
            // TODO Auto-generated method stub
            this.id = in.readInt();
            this.gender = Text.readString(in);
            this.name = in.readString();
            this.number = in.readString();
        }
            @Override
        public void write(DataOutput out) throws IOException {
            // TODO Auto-generated method stub
            out.writeInt(this.id);
            Text.writeString(out,this.name);
            out.writeInt(this.gender);
            out.writeInt(this.number);
        }
            @Override
        public void readFields(ResultSet result) throws SQLException {
            // TODO Auto-generated method stub
            this.id = result.getInt(1);
            this.name = result.getString(2);
            this.gender = result.getString(3);
            this.number = result.getString(4);
        }
            @Override
        public void write(PreparedStatement stmt) throws SQLException{
            // TODO Auto-generated method stub
            stmt.setInt(1, this.id);
            stmt.setString(2, this.name);
            stmt.setString(3, this.gender);
            stmt.setString(4, this.number);
        }
            @Override
        public String toString() {
            // TODO Auto-generated method stub
            return new String(this.name + " " + this.gender + " " +this.number);
        }

第二步,实现Map和Reduce类

public class DBAccessMapper extends MapReduceBase implements
Mapper<LongWritable, TeacherRecord, LongWritable, Text> {
@Override
public void map(LongWritable key, TeacherRecord value,
OutputCollector<LongWritable, Text> collector, Reporter reporter)
throws IOException {
// TODO Auto-generated method stub
new collector.collect(new LongWritable(value.id), new Text(value
.toString()));
}
}

第三步:主函数的实现,函数

public class DBAccessReader {
    public static void main(String[] args) throws IOException {
        JobConf conf = new JobConf(DBAccessReader.class);
        conf.setOutputKeyClass(LongWritable.class);
        conf.setOutputValueClass(Text.class);
        conf.setInputFormat(DBInputFormat.class);
        FileOutputFormat.setOutputPath(conf, new Path("dboutput"));
        DBConfiguration.configureDB(conf,"com.mysql.jdbc.Driver",
        "jdbc:mysql://localhost/school","root","123456");
        String [] fields = {"id", "name", "gender", "number"};
        DBInputFormat.setInput(conf, StudentRecord.class,"Student",null "id", fields);
        conf.setMapperClass(DBAccessMapper.class);
        conf.setReducerClass(IdentityReducer.class);
        JobClient.runJob(conf);
        }
}

2.写数据
往往对于数据处理的结果的数据量一般不会太大,可能适合hadoop直接写入数据库中。hadoop提供了相应的数据库直接输出的计算发结果。
- DBOutFormat: 提供数据库写入接口。
 - DBRecordWriter:提供向数据库中写入的数据记录的接口。
 - DBConfiguration:提供数据库配置和创建链接的接口。
 
DBOutFormat提供一个静态方法setOutput(job,String table,String ...filedNames);该方法的参数很容易看懂。假设要插入一个Student的数据,其代码为

    public static void main(String[] args) throws IOException {
        Configuration conf = new Configuration();
        JobConf conf = new JobConf();
        conf.setOutputFormat(DBOutputFormat.class);
        DBConfiguration.configureDB(conf,"com.mysql.jdbc.Driver",
                "jdbc:mysql://localhost/school","root","123456");
        DBOutputFormat.setOutput(conf,"Student", 456, "liqizhou", "man", "20004154578");
        JobClient.runJob(conf); 

Hadoop,MapReduce操作Mysql的更多相关文章
- Hadoop MapReduce 操作 统计词频
		
1.准备文件并设置编码格式为UTF-8并上传Linux 2.新建一个Java Project 3.导入jar 4.编写Map()和Reduce() 5.将代码输出成jar 6.在linux中启动hdf ...
 - 本地通过Eclipse链接Hadoop操作Mysql数据库问题小结
		
前一段时间,在上一篇博文中描述了自己抽时间在构建的完全分布式Hadoop环境过程中遇到的一些问题以及构建成功后,通过Eclipse操作HDFS的时候遇到的一些问题,最近又想进一步学习学习Hadoop操 ...
 - Hadoop 中利用 mapreduce 读写 mysql 数据
		
Hadoop 中利用 mapreduce 读写 mysql 数据 有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...
 - Hbase理论&&hbase shell&&python操作hbase&&python通过mapreduce操作hbase
		
一.Hbase搭建: 二.理论知识介绍: 1Hbase介绍: Hbase是分布式.面向列的开源数据库(其实准确的说是面向列族).HDFS为Hbase提供可靠的底层数据存储服务,MapReduce为Hb ...
 - 通过mapreduce把mysql的数据读取到hdfs
		
前面讲过了怎么通过mapreduce把mysql的一张表的数据放到另外一张表中,这次讲的是把mysql的数据读取到hdfs里面去 具体怎么搭建环境我这里就不多说了.参考 通过mapreduce把mys ...
 - Hadoop MapReduce 一文详解MapReduce及工作机制
		
@ 目录 前言-MR概述 1.Hadoop MapReduce设计思想及优缺点 设计思想 优点: 缺点: 2. Hadoop MapReduce核心思想 3.MapReduce工作机制 剖析MapRe ...
 - Hadoop MapReduce执行过程详解(带hadoop例子)
		
https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 Map ...
 - hadoop  MapReduce Yarn运行机制
		
原 Hadoop MapReduce 框架的问题 原hadoop的MapReduce框架图 从上图中可以清楚的看出原 MapReduce 程序的流程及设计思路: 首先用户程序 (JobClient) ...
 - Hadoop MapReduce例子-新版API多表连接Join之模仿订单配货
		
文章为作者原创,未经许可,禁止转载. -Sun Yat-sen University 冯兴伟 一. 项目简介: 电子商务的发展以及电商平台的多样化,类似于京东和天猫这种拥有过亿用户的在线购 ...
 
随机推荐
- CentOS7 使用chrony搭建集群中的时间同步服务
			
一.集群环境: 系统:CentOS7-minimal 集群中的两台主机ip:10.132.226.103/24 10.132.226.104/24 二.CentOS7中时间相关命令timedatec ...
 - jquery优化
			
选择器优化执行的速度 选择器 优先:id>元素>类 使用对象缓存:即使用变量来保存对象名,var $myDiv = $("#myDiv"):$myDiv.show(); ...
 - Spring异常重试框架Spring Retry
			
Spring Retry支持集成到Spring或者Spring Boot项目中,而它支持AOP的切面注入写法,所以在引入时必须引入aspectjweaver.jar包. 快速集成的代码样例: @Con ...
 - MongoDB如何释放空闲空间?
			
当我们从MongoDB中删除文档或集合时,MongoDB并不会将已经占用了的磁盘空间释放,它会一直维护已经占用了磁盘空间的数据文件,尽管数据文件中可能存在大大小小的空记录列表(empty record ...
 - Java学习笔记二十二:Java的方法重写
			
Java的方法重写 一:什么是方法的重写: 如果子类对继承父类的方法不满意,是可以重写父类继承的方法的,当调用方法时会优先调用子类的方法. 语法规则 返回值类型.方法名.参数类型及个数都要与父类继承的 ...
 - 主存和cache的地址映射
			
cache是一种高速缓冲寄存器,是为解决CPU和主存之间速度不匹配而采用的一项重要技术. 主存与cache的地址映射方式有全相联方式.直接方式和组相联方式三种. 直接映射(directmapping) ...
 - 北京Uber优步司机奖励政策(2月23日)
			
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
 - android stadio  编译报错:download fastutil-7.2.0.jar
			
在Ubuntu上面,新安装的stadio,第一次编译项目的时候, 一直开在下载 fastutil-7.2.0.jar 原因是需要FQ.那么改一下你的buil.gradle buildscript { ...
 - springBoot -webSocket 基于STOMP协议交互
			
浅谈WebSocket WebSocket是在HTML5基础上单个TCP连接上进行全双工通讯的协议,只要浏览器和服务器进行一次握手,就可以建立一条快速通道,两者就可以实现数据互传了.说白了,就是打破了 ...
 - Wireshark对HTTPS数据的解密
			
本文来自网易云社区 之前有介绍<wireshark抓包分析--TCP/IP协议>,然后某天有人问我,示例里是HTTP的,如果是HTTPS,你可以抓包分析吗?基于好奇,我查阅了下相关资料,把 ...