整套大数据学习资料(视频+笔记)百度网盘无门槛下载:http://www.edu360.cn/news/content?id=3377

15.5深入了解数据库导入

如前所述,Sqoop是通过一个MapReduce作业从数据库中导入一个表,这 个作业从表中抽取一行行记录,然后将记录写入HDFSMaPReduce是如何 读取记录的呢?本节将解释Sqoop的底层工作机理。

图〗5-1粗略演示了 Sqoop是如何与源数据库及Hadoop进行交互的。像 Hadoop —样,Sqoop是用Java语言编写的。Java提供了一个称为 JDBC(Java Database Connectivity)的API,应用程序可以使用这个API来访 问存储在RDBMS中的数据,同时可以检査数据类型。大多数数据库厂商 都提供了 JDBC驱动程序,其中实现了 JDBC API并包含用于连接其数据库 服务器的必要代码。

image.png

                                                                                   

15-1. Sqoop的导入过程


根据用于访问数据库的连接字符串中的URL, Sqoop尝试预测应该 加载哪个驱动程序,而你要事先下载所需的JDBC驱动并且将其安 装在Sqoop客户端。在Sqoop无法判定使用哪个JDBC驱动程序 时,用户可以明确指定如何将JDBC驱动程序加载到Sqoop,这样 Sqoop就能够支持大多数的数据库平台。

在导入开始之前,Sqoop使用JDBC来检查将要导入的表。它检索出表中所 有的列以及列的SQL数据类型。这些SQL类型(VARCHARINTEGER等)被 映射到Java数据类型(StringInteger等),在MapReduce应用中将使用 这些对应的Java类型来保存字段的值。Sqoop的代码生成器使用这些信息 来创建对应表的类,用于保存从表中抽取的记录。

例如,之前提到的Widget类包含下列方法,这些方法用于从抽取的记录中 检索所有的列:

public Integer get_id();

public String get_widget_name();

public java.math.BigDecimal get_price();

public java.sql.Date get_design_date();

public Integer get_version();

public String get_design_comment();

不过,对于导入来说,更关键的是DBWritable接口的序列化方法,这些 方法能使Widget类和JDBC进行交互:

public void readFields(ResultSet —dbResults) throws SQLException; public void write(PreparedStatement __dbStmt) throws SQLException;

JDBCResultSet接口提供了一个用于从査询结果中检索记录的游标, 这里的readFields()方法将用ResultSet中一行数据的列来填充Widget 对象的字段。这里的write()方法允许Sqoop将新的Widget行插入表, 这个过程称为“导出”(exporting)。15.8节将对此进行讨论。

Sqoop启动的MapReduce作业用到一个InputFormat,它可以通过JDBC 从一个数据库表中读取部分内容。Hadoop提供的DataDrivenDBInputFormat

能够为几个map任务对査询结果进行划分。

使用一个简单的査询通常就可以读取一张表的内容,例如:

SELECT coiltcoi2fcoL3,,.. FROM tabLeName

但是,为了获得更好的导入性能,人们经常将这样的查询划分到多个节点 上执行。査询是根据一个“划分列splitting column)来进行划分的。根据


表的元数据,Sqoop会选择一个合适的列作为划分列(通常是表的主键)。主 键列中的最小值和最大值会被读出,与目标任务数一起用来确定每个map 任务要执行的查询。

例如,假设widgets表中有100,000条记录,其id列的值为0~99,999。 在导入这张表时,Sqoop会判断出id是表的主键列。启动MapReduce作业 时,用来执行导入的DataDrivenDBInputFormat便会发出一条类似于 SELECT MIN(id), MAX(id) FROM widgets的査询语句。检索出的数据 将用于对整个数据集进行划分。假设我们指定并行运行5个map任务(使 用-m 5),这样便可以确定每个map任务要执行的査询分別为:SELECT id, widgetname, … FROM widgets WHERE id >= 0. AND id < 20000,SELECT id, widget_name, … FROM widgets WHERE id >= 20000 AND id < 40000,

以此类推。

划分列的选择是影响并行执行效率的重要因素。如果id列的值不是均匀分 布的(也许在id值50,000到75,000的范围内没有记录),那么有一部分map 任务可能只有很少或没有工作要做,而其他任务则有很多工作要做。在运 行一个导入作业时,用户可以指定一个列作为划分列,从而调整作业的划 分使其符合数据的真实分布。如果使用1参数来让一个任务执行导入作 业,就不再需要这个划分过程。

在生成反序列化代码和配置InPutF〇rmat之后,sq〇〇p将作业发送到 MapReduce集群。map任务执行查询并且将ResultSet中的数据反序列化 到生成类的实例,这些数据要么被直接保存在SequenceFile文件中,要么 在写到HDFS之前被转换成分隔的文本。 

转载请注明:全栈大数据 » 15.5深入了解数据库导入

喜欢 (0)or分享 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址