转自:
http://blog.csdn.net/u012842205/article/details/52344196
http://blog.csdn.net/u012842205/article/details/52346595
最近被Sqoop2彻底搞蒙了,各种各样的奇怪问题,层出不穷,而且网上资料都没有针对这些问题的,官方文档也有各种各样的不完整描述。一些注意事项也不说。弄了快一个星期,这么个小小工具,才算基本会使了。网上sqoop1.99.7的资料很少,或者我没找到吧!希望这篇文章能给同行们很好的帮助。主要是记录从MySQL数据表中将数据导出到HDFS上的过程,我也记录下各种奇奇怪怪的问题。
一、环境描述
Apache Hadoop2.6.4
Sqoop1.99.7
Kali2 Linux 系统,基于Debian,Ubuntu也差不多。
MySQL server 5.5.49-0+deb8u1(Debian)
再提一下MySQL的JDBC驱动:直接上官网下的connection/J:mysql-connector-Java-5.1.39-bin.jar,也就是5.1.39的版本
二、Sqoop2基本介绍
用于结构化数据系统(比如关系型数据库系统RDBMS)和Hadoop系统间的大量数据传输的一个工具,特别是Hadoop所使用的HDFS分布式文件系统。作为ASF下的一个开源项目,其一开始也只是一个小工具,当然现在也是,还附带一些库供客户端调用。Sqoop版本又分Sqoop1和Sqoop2,其中Sqoop1目前最高释出版本为1.4.6,Sqoop2最高释出版本为1.99.7,Sqoop1与Sqoop2相互间不兼容,而且Sqoop2目的并不是作为产品,主要是致力于开发。再者,其对Hadoop的支持版本有些特别要求,比如Hadoop1和Hadoop0.x还有Hadoop2.x的兼容性等。在下载时一般要注意其兼容的Hadoop版本(Sqoop官网上我没有看到相关具体的描述,只是通过下载的文件名辨别与Hadoop的兼容性)。
Sqoop进行数据转移时必须依赖于Hadoop的MapReduce作业,所以Hadoop必须在环境中存在,且能被Sqoop访问。
三、Sqoop2下载安装
选择sqoop2的1.99.7版本即可。我直接下的bin版本,这个版本已经编译好了,直接用。当然你也可以下源代码到本地编译安装,确保有Java环境,因为Sqoop用Java编写的。本文直接用的bin版本:sqoop-1.99.7-bin-hadoop200.tar.gz
2、解压安装包
tar -xzvf sqoop-1.99.7-bin-hadoop200.tar.gz
mv sqoop-1.99.7-bin-hadoop200 sqoop1.99.7
3、目录简单说明
bin:可执行脚本,一般使用sqoop都是通过这个目录中的工具调用,是一些shell或batch脚本。
conf:存放配置文件
docs:目前不清楚具体是什么,可能是帮助文档,不过一般使用sqoop不会用到。
server:里面只有一个lib目录,存了很多jar文件,是sqoop2 的server包。
shell:同理,sqoop2的shell包。
tools:同理,sqoop2的工具包。
4、安装
因为已经编译好了,所以安装过程是很简单的,只需要把整个目录放在一个自己喜欢的地方即可。
5、配置
这里说说环境需要什么:
(1)Java环境,也就是需要Java JDK,我使用的Java为Oracle的1.8版本,注意建议不使用OpenJDK,以防一些兼容性问题。本例根目录为/usr/lib/jvm/jdk1.8.0_101。
(2)Hadoop环境,我使用的Apache Hadoop2.6版本,根目录为/home/hadoop/hadoop2.6。
配置过程中多参考官网的文档,但就我亲试而言,还是有很多没有说清楚的地方。文档一定选择对应版本的。
(1)配置Hadoop根目录路径
添加一个系统环境变量,HADOOP_HOME,本例中设置为/home/hadoop/hadoop2.6。
无论添加到/etc/profile还是在/etc/profile.d中创建一个脚本导入变量,亦或是在~/.bashrc文件中写,都可以:
注意:配置这个变量主要是让Sqoop能找到以下目录的jar文件和Hadoop配置文件:
$HADOOP_HOME/share/hadoop/common
$HADOOP_HOME/share/hadoop/hdfs
$HADOOP_HOME/share/hadoop/mapreduce
$HADOOP_HOME/share/hadoop/yarn
官网上说名了可以单独对各个组建进行配置,使用以下变量:
$HADOOP_COMMON_HOME, $HADOOP_HDFS_HOME, $HADOOP_MAPRED_HOME, $HADOOP_YARN_HOME
若$HADOOP_HOME已经配置了,最好不要再配置下面的变量,可能会有些莫名错误。
(2)配置Hadoop代理访问
因为sqoop访问Hadoop的MapReduce使用的是代理的方式,必须在Hadoop中配置所接受的proxy用户和组。找到Hadoop的core-site.xml配置文件(本例是$HADOOP_HOME/etc/hadoop/core-site.xml):
<property> <name>hadoop.proxyuser.$SERVER_USER.hosts</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.$SERVER_USER.groups</name> <value>*</value> </property>$SERVER_USER是运行Sqoop2 Server的系统用户,本例我使用了hadoop用户运行server,所以将之代替为hadoop。
注意:保证你的用户id大于1000(可用id命令查看),否则作为系统变量运行时,可能需要其他配置,参照官网。
(3)配置Sqoop根目录
这个官方文档没有说明,不过貌似sqoop1文档有这个描述,我也胡乱配置了一个:
(4)配置第三方jar引用路径
一般我们使用的数据库驱动包都没有随着Sqoop一起释出,多半是因版权问题,所以将这些包放置在这个第三方组件下。再在配置一个SQOOP_SERVER_EXTRA_LIB系统变量即可,本例指定路径为$SQOOP_HOME/extra
最后把mysql的驱动jar文件复制到这个目录下。
(5)Sqoop服务器配置
主要是配置conf目录下的sqoop.properties和sqoop_bootstrap.properties两个文件
sqoop_bootstrap.properties文件配置config支持类,这里一般使用默认值即可:
sqoop.properties文件配置比较多,这里按需要配置,我写下我配置的项,其他都使用默认值:
注意 :官方文档上只说了配置上面第一项,mapreduce的配置文件路径,但后来运行出现authentication异常,找到sqoop文档描述security部分,发现sqoop2支持hadoop的simple和kerberos两种验证机制。所以配置了一个simple验证,这个异常才消除。
(6)验证配置是否有效
使用bin中的sqoop2-tool工具进行验证:
这个工具也可用于软件升级。若没有什么问题,则可以往下走了。
(7)开启服务器
sqoop2的运行模式不再是sqoop1的一个小工具,而加入了服务器,这样只要能访问到mapreduce配置文件及其开发包,sqoop服务器部署在哪里都无所谓,而客户端shell是不需要任何配置的。直接用即可。
开启服务器:
这时可以通过JDK中的jps工具查看是否已经正确启动起来,正常情况下会有个SqoopJettyServer的进程,这也可以想象,Sqoop server是基于jetty实现的。
至此,sqoop1.99.7的配置和启动已经完成,下一篇文章将接着讲使用和一些注意事项,并总结。
本文将接上文,记录Sqoop1.99.7基本使用。这里我们使用sqoop2将MySQL中的一个数据表导出到HDFS,都是最简单的使用。
请确保Sqoop2服务器已经启动,并确保Hadoop启动。其中Hadoop不仅要启动hdfs(NameNode、DataNode),还要启动yarn(NodeManager、ResourceManager),当然,一般还会有一个SecondaryNameNode,用于原始NameNode的备援进程。Sqoop具体配置请看上一篇博客。
一、sqoop客户端
sqoop2客户端提供各种命令行交互接口,供用户使用。sqoop2客户端先连接Sqoop Server,将参数传递过去,再调用mapreduce进行数据导入到出作业。以下是sqoop2中比较重要的几个对象。
(1)connector:sqoop2中预定一了各种里链接,这些链接是一些配置模板,比如最基本的generic-jdbc-connector,还有hdfs-connector,通过这些模板,可以创建出对应数据源的link,比如我们链接mysql,就是使用JDBC的方式进行链接,这时候就从这个generic-jdbc-connector模板继承出一个link,可以这么理解。
(2)link:从connector继承出的对象,用于指定的对数据源的链接。
(3)job:指定一个导入导出作业,必须指定数据源和数据目的地,并配置各项job参数,用于提交给mapreduce。
二、客户端使用
由于sqoop是一个交互式命令行工具,使用如下命令打开sqoop的shell:
若成功会开启sqoop的shell命令行提示符:sqoop:000>
(1)配置sqoop server参数
port和host就不用说了,port是默认值;最后一个--webapp官方文档说是指定的sqoop jetty服务器名称,大概是一个自己能识别的用于标示这个服务器的名字吧。
完成后可以验证服务器是否能正确链接上:
这个命令能显示shell和server的版本信息,若server版本信息能正确显示,则没问题!能正确链接上。
注意:我在运行这条命令时出现一个警告,说hadoop native library无法加载什么的,这个目前也没有查到相关说法,但验证下来,hadoop2.6中的lib/native只有一些提供给C/C++调用的二进制文件。若没有影响直接忽略吧。望哪位知道的能告诉我。
(2)配置链接到MySQL的链接(link)
MySQL链接使用的是JDBC,这样想来不难理解,必须有对应的驱动文件jar,还得有对应的访问权限,请确保能在server端访问MySQL。参照上一篇博客。
可以先看看connector模板都有哪些:
这时候会显示各个conector信息,在1.99.7版本以前,每个connector会有一个id,当创建link时,用这个id指定所继承的connector,但在这个版本中没有这个id了,创建link时直接使用connector名称创建,这里我们使用的是generic-jdbc-connector:
这时候就会出现交互会话,提示你输入各项参数:
Name:标示这个link的字符串,可以是一个自己喜欢的名称。
Driver Class:指定jdbc启动时所需要加载的driver类,这个类实现了Java.sql.Driver接口。对本文来说,这个值是com.mysql.jdbc.Driver。
Connection String:广为人知的数据库链接字符串,本例为jdbc:mysql://localhost/db_ez,db_ez是本例的数据库名称。
Username:链接数据库的用户名,也就是mysql客户端传入的-u参数。本例是ez。
Password:链接数据库的用户密码。
FetchSize:这个属性并没有在官方文档上描述,我也不知道说的是什么,直接回车了,使用的默认值。
填写完上面几项,将提供一个可以输入JDBC属性的hash,提示符是entry#,这时候可以手动指定很多JDBC属性的值。本例只覆盖了一个protocol值为tcp:
protocol=tcp
再按回车,之后会再定义一下SQL方言。也就是说,各个数据库系统提供商们对SQL语言标准的理解和实现各有不同,于是各有各的一些细微差别。以下属性就是用于指定这些区别的。当然,很坑的是,官方文档上并没有说明这些属性如何填写,连提都没提。
Identifier enclose:指定SQL中标识符的定界符,也就是说,有的SQL标示符是一个引号:select * from "table_name",这种定界符在MySQL中是会报错的。这个属性默认值就是双引号,所以不能使用回车,必须将之覆盖,我使用空格覆盖了这个值。吐槽一下,这个错误我整了一整天才搞明白,官方文档也是坑啊!
至此,就可以完成这个link的创建。命令行提示符也会还原为sqoop:000>。使用以下命令查看是否创建成功:
(3)配置链接到HDFS的link:
同理,使用以下命令,connector指定为HDFS:
hdfs的参数只有一个Name和一个HDFS URI,Name同上的MySQL,自己指定一个喜欢的标示符即可。这个url是hadoop中配置hdfs-site.xml中的属性fs.defaultFS的值。本例为hdfs://localhost:9000
回车后没有什么错误就会显示successful信息。
(4)配置传输事务job:
链接都指定了,接下来就要指定Job,用于提交给mapreduce:
-f指定from,即是数据源位置,-t指定to,即是目的地位置。本例是从MySQL传递数据到HDFS,所以就是from mysql to HDFS。参数值就是在创建链接(link)时指定的Name。
以下是各个属性
Name:一个标示符,自己指定即可。
Schema Name:指定Database或Schema的名字,在MySQL中,Schema同Database类似,具体什么区别没有深究过,但官网描述在创建时差不多。这里指定数据库名字为db_ez即可,本例的数据库。
Table Name:本例使用的数据库表为tb_forhadoop,自己指定导出的表。多表的情况请自行查看官方文档。
SQL Statement:就是sql查询语句,文档上说需要指定一个$condition,但我一直没有创建成功,貌似是一个条件子句。
配置完以上几项,又回出现element#提示符,提示输入一些hash值,这里我没有再指定什么。直接回车过。而以下几个配置我也是直接回车,使用默认值,大概是一些与数据库相关的参数。
Partition column:
Partition column nullable:
Boundary query
Last value
后面需要配置数据目的地各项值:
Null alue:大概说的是如果有空值用什么覆盖
File format:指定在HDFS中的数据文件是什么文件格式,这里使用TEXT_FILE,即最简单的文本文件。
Compression codec:用于指定使用什么压缩算法进行导出数据文件压缩,我指定NONE,这个也可以使用自定义的压缩算法CUSTOM,用Java实现相应的接口。
Custom codec:这个就是指定的custom压缩算法,本例选择NONE,所以直接回车过去。
Output directory:指定存储在HDFS文件系统中的路径,这里最好指定一个存在的路径,或者存在但路劲下是空的,貌似这样才能成功。
Append mode:用于指定是否是在已存在导出文件的情况下将新数据追加到数据文件中。
Extractors:不清楚是什么,我取了一个1
Loaders:同上
最后再次出现element#提示符,用于输入extra mapper jars的属性,可以什么都不写。直接回车。
至此若出现successful则证明已经成功创建。
三、开启事务
使用如下命令
name就是创建job时指定的Name属性,不出意外将正确执行,之后使用如下命令就能查看其进度了:
四、写在最后
未完成。。。