Hadoop主要用来对非结构化或半结构化(HBase)数据进行存储和分析,而结构化的数据则一般使用数据库来进行存储和访问。本文的主要内容则是讲述如何将Hadoop与现有的数据库结合起来,在Hadoop应用程序中访问数据库中的文件。
1.DBInputFormat
DBInputFormat是Hadoop从0.19.0开始支持的一种输入格式,包含在包org.apache.hadoop.mapred.lib.db中,主要用来与现有的数据库系统进行交互,包括MySQL、PostgreSQL、Oracle等几个数据库系统。DBInputFormat在Hadoop应用程序中通过数据库供应商提供的JDBC接口来与数据库进行交互,并且可以使用标准的SQL来读取数据库中的记录。在使用DBInputFormat之前,必须将要使用的JDBC驱动拷贝到分布式系统各个节点的$HADOOP_HOME/lib/目录下。
在DBInputFormat类中包含以下三个内置类:
1.protected class DBRecordReader
implements RecordReader<LongWritable, T>:用来从一张数据库表中读取一条条元组记录。
2.public static
class NullDBWritable implements DBWritable, Writable:主要用来实现DBWritable接口。
3.protected static
class DBInputSplit implements InputSplit:主要用来描述输入元组集合的范围,包括start和end两个属性,start用来表示第一条记录的索引号,end表示最后一条记录的索引号。
其中DBWritable接口与Writable接口比较类似,也包含write和readFields两个函数,只是函数的参数有所不同。DBWritable中的两个函数分别为:
public void
write(PreparedStatement statement) throws SQLException;
public void
readFields(ResultSet resultSet) throws SQLException;
这两个函数分别用来给java.sql.PreparedStatement设置参数,以及从java.sql.ResultSet中读取一条记录,熟悉Java JDBC用法的应该对这两个类的用法比较了解。
2.使用DBInputFormat读取数据库表中的记录
上文已经对DBInputFormat以及其中的相关内置类作了简单介绍,下面对怎样使用DBInputFormat读取数据库记录进行详细的介绍,具体步骤如下:
1.使用DBConfiguration.configureDB (JobConf
job, String driverClass, String dbUrl, String userName, String passwd)函数配置JDBC驱动,数据源,以及数据库访问的用户名和密码。例如MySQL数据库的JDBC的驱动为“com.mysql.jdbc.Driver”,数据源可以设置为“jdbc:mysql://localhost/mydb”,其中mydb可以设置为所需要访问的数据库。
2.使用DBInputFormat.setInput(JobConf
job, Class<? extends DBWritable> inputClass, String tableName, String
conditions, String orderBy, String... fieldNames)函数对要输入的数据进行一些初始化设置,包括输入记录的类名(必须实现了DBWritable接口)、数据表名、输入数据满足的条件、输入顺序、输入的属性列。也可以使用重载的函数setInput(JobConf
job, Class<? extends DBWritable> inputClass, String inputQuery, String
inputCountQuery)进行初始化,区别在于后者可以直接使用标准SQL进行初始化,具体可以参考Hadoop API中的讲解。
3.按照普通Hadoop应用程序的格式进行配置,包括Mapper类、Reducer类、输入输出文件格式等,然后调用JobClient.runJob(conf)。
3.使用示例
假设MySQL数据库中有数据库school,其中的teacher数据表定义如下:
DROP TABLE IF
EXISTS `school`.`teacher`;
CREATE TABLE `school`.`teacher` (
`id` int(11) default NULL,
`name` char(20) default NULL,
`age` int(11) default NULL,
`departmentID` int(11) default NULL
) ENGINE=InnoDB
DEFAULT CHARSET=latin1;
首先给出实现了DBWritable接口的TeacherRecord类:
public class TeacherRecord implements
Writable, DBWritable{
int id;
String name;
int age;
int departmentID;
@Override
public void
readFields(DataInput in) throws IOException {
// TODO Auto-generated
method stub
this.id = in.readInt();
this.name = Text.readString(in);
this.age = in.readInt();
this.departmentID =
in.readInt();
}
@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.age);
out.writeInt(this.departmentID);
}
@Override
public void
readFields(ResultSet result) throws SQLException {
// TODO Auto-generated
method stub
this.id = result.getInt(1);
this.name =
result.getString(2);
this.age = result.getInt(3);
this.departmentID =
result.getInt(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.setInt(3, this.age);
stmt.setInt(4, this.departmentID);
}
@Override
public String toString() {
// TODO Auto-generated
method stub
return new String(this.name
+ " " + this.age + " " + this.departmentID);
}
}
利用DBAccessMapper读取一条条记录:
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
collector.collect(new
LongWritable(value.id),
new Text(value.toString()));
}
}
Main函数如下:
public class DBAccess {
public static void
main(String[] args) throws IOException {
JobConf conf = new
JobConf(DBAccess.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", "age", "departmentID"};
DBInputFormat.setInput(conf,
TeacherRecord.class, "teacher",
null, "id", fields);
conf.setMapperClass(DBAccessMapper.class);
conf.setReducerClass(IdentityReducer.class);
JobClient.runJob(conf);
}
}
该示例从teacher表中读取所有记录,并以TextOutputFormat的格式输出到dboutput目录下,输出格式为<”id”, “name
age departmentID”>。
4.使用DBOutputFormat向数据库中写记录
DBOutputFormat将计算结果写回到一个数据库,同样先调用DBConfiguration.configureDB()函数进行数据库配置,然后调用函数DBOutputFormat.setOutput (JobConf job, String tableName, String... fieldNames)进行初始化设置,包括数据库表名和属性列名。同样,在将记录写回数据库之前,要先实现DBWritable接口。每个DBWritable的实例在传递给Reducer中的OutputCollector时都将调用其中的write(PreparedStatement
stmt)方法。在Reduce过程结束时,PreparedStatement中的对象将会被转化成SQL语句中的INSERT语句,从而插入到数据库中。
5.总结
DBInputFormat和DBOutputFormat提供了一个访问数据库的简单接口,虽然接口简单,但应用广泛。例如,可以将现有数据库中的数据转储到Hadoop中,由Hadoop进行分布式计算,通过Hadoop对海量数据进行分析,然后将分析后的结果转储到数据库中。在搜索引擎的实现中,可以通过Hadoop将爬行下来的网页进行链接分析,评分计算,建立倒排索引,然后存储到数据库中,通过数据库进行快速搜索。虽然上述的数据库访问接口已经能满足一般的数据转储功能,但是仍然存在一些限制不足,例如并发访问、数据表中的键必须要满足排序要求等,还需Hadoop社区的人员进行改进和优化。
分享到:
相关推荐
1. **配置JDBC驱动和数据源**:使用`DBConfiguration.configureDB(JobConf job, String driverClass, String dbUrl, String userName, String passwd)`函数配置JDBC驱动、数据源以及数据库访问的用户名和密码。...
hadoop连接数据库查询数据,并添加到hdfs;从hdfs进行mapreduce数据导入到数据库 hadoop连接数据库查询数据,并添加到hdfs;从hdfs进行mapreduce数据导入到数据库 hadoop连接数据库查询数据,并添加到hdfs;从hdfs...
Oracle Hadoop装载器是Oracle提供的一种用于将Hadoop中的数据加载到Oracle数据库中的工具。它利用MapReduce框架来高效地处理大规模数据集,并支持在线和离线两种加载模式。 - **在线模式**:在这种模式下,数据直接...
综上所述,这些jar包组合在一起,为Java应用程序提供了连接到Hadoop Hive数据库的能力,通过编写Java代码,可以执行SQL查询,操作Hive中的数据。记得在部署时,将这些库复制到项目的lib目录或配置到类路径中,以便...
在进行Hadoop与Oracle之间的数据迁移时,需要定义数据库信息类DBInfo,这个类用于配置数据库访问对象。DBInfo类中包含了一系列的私有属性,包括数据库的IP地址、端口、服务名、用户名、密码、表名、查询条件、排序...
分布式数据库Hive是大数据处理领域中的重要工具,它与Hadoop生态系统紧密相连,主要用于实现对大规模数据集的存储和查询。Hive构建在Hadoop的HDFS(分布式文件系统)之上,利用MapReduce进行分布式计算,同时引入了...
HBase 是基于 Apache Hadoop 的面向列的 NoSQL 数据库,是 Google 的 BigTable 的开源实现。HBase 是一个针对半结构化数据的开源的、多版本的、可伸缩的、高可靠的、高性能的、分布式的和面向列的动态模式数据库。 ...
#### 二、Hadoop框架及其在数据库中的应用 ##### 2.1 Hadoop框架概述 Hadoop是一个由Apache基金会维护的开源项目,其核心组件包括HDFS(Hadoop Distributed File System)和MapReduce。HDFS提供了一个分布式的文件...
Hbase是Apache的NoSQL分布式可扩展Hadoop数据库,可以很好地横向扩展。Hbase中的数据是面向列的数据库,其中结构化数据存储在键值对中。Hbase用Java编写。Hbase的灵感来自Google Paper-“大表:结构化数据的分布式...
10. **安全性**:在Hadoop 2.7.1中,安全性也是一个重要的主题,包括Kerberos认证、访问控制列表(ACLs)和安全模式,确保了在大规模集群中的数据安全。 通过阅读这份Hadoop 2.7.1的中文文档,无论是初学者还是经验...
这篇博客文章(虽然链接无法直接访问,但我们可以根据常规知识来解释这个概念)可能探讨了如何实现Hadoop MapReduce任务中的二次排序,并将其结果插入到数据库中。 **一、Hadoop二次排序** 在Hadoop MapReduce的...
针对如何从数据库中获取有效信息的问题,即云计算成功应用的关键,本文分析了现有云计算技术的关键,并选择了开源的Hadoop分布式计算平台作为解决方案。通过使用HBase存储数据,Hive作为数据仓库工具用于查询和分析...
在深入分析Hadoop云计算框架中的分布式数据库HBase研究之前,我们先了解一下Hadoop的背景和其核心组件。Hadoop是一个开源框架,它允许使用简单的编程模型在计算机集群上进行海量数据的存储和处理。由于其用Java语言...
描述中提到的“数据库访问驱动”和“数据库开发驱动”可能是指与Hadoop集成的数据库连接器,例如JDBC(Java Database Connectivity)驱动,这些驱动允许Hadoop与各种关系型数据库(如MySQL、Oracle等)进行交互,...
书中会讨论Hadoop中的权限控制、加密和审计机制,以保护数据不被未经授权的访问。 7. **Hadoop的扩展和优化**:包括YARN的资源调度策略、HDFS的性能调优,以及如何通过Hadoop与其他技术(如NoSQL、云存储)集成来...
HBase是一个分布式、面向列的NoSQL数据库,它提供了实时读写和强一致性的能力,适用于需要实时访问大量结构化和半结构化数据的场景。 此外,书中还可能涉及Hadoop的扩展和优化,如YARN(Yet Another Resource ...
在Hadoop环境中,Kerberos可以应用于HDFS、YARN、HBase等组件,保护数据的读写操作、资源调度以及数据库访问。安装Hadoop-3.3.4时,需确保配置Kerberos以实现安全运行。首先,需要设置Kerberos的KDC服务器,并为每个...
在Hadoop环境中,可以利用MapReduce对这些日志进行高效处理,提取出有价值的信息,如最受欢迎的页面、访问模式等。 4. **Zookeeper**:Zookeeper是Apache的一个分布式协调服务,它在Hadoop生态系统中起着至关重要的...
除了核心组件,书中还会涉及其他Hadoop生态系统的组件,例如HBase(一个分布式的、面向列的数据库)、Hive(一个数据仓库工具,用于查询和分析存储在HDFS中的大数据集)、Pig(一个用于大数据分析的平台),以及 ...