sqoop是Apache的一个开源项目,属于Hadoop家族成员,核心功能是关系型数据库和Hadoop之间的数据转换与传输,从名字大概可以看出来:sql+hadoop=sqoop。sqoop目前发展处两个主版本,分别是sqoop1和sqoop2,sqoop1的版本号是1.4.x,sqoop2的版本号是1.99.x,这个编号有点儿意思,尚不清楚为何这么遍。sqoop2和sqoop1是彻底不兼容的,从软件构架到使用方法都是彻底不一样的。html
sqoop1没有server的概念,其自己做为hadoop集群的client调用mapreduce完成工做,sqoop2则多了一层server的构架,其中集成了tomcat。用户经过client登陆到sqoop2 shell,在这个shell中能够建立link,link是基于connector的,connector不须要建立,是sqoop2自己提供的,经常使用的connector包括hdfs-connector和jdbc-connector,分别对应HDFS和关系型数据库的连接,目前最新的1.99.6版本记得也支持kafka等connector。建立link的过程至关因而connector的实例化,将指定连接的地址、用户名密码等信息。有了link以后就能够建立job,job对应两个link,一个链接数据源一个链接数据目的地。job建立完成后并无实际执行数据的传输,能够在任意时间启动建立成功的job。sqoop2的简单操做能够参考官方的这个小Demo:Sqoop5MinutesDemojava
个人理解是:sqoop2 server的做用主要是保存和管理数据源链接信息、数据传输任务等,固然也提供了经过REST接口操做任务这样的高级功能。与sqoop1相比,sqoop2因为多了一个server层,在配置上要麻烦一些,启动server时常常会遇到一些奇怪的报错,即便成功启动server,后面的操做也可能遇到问题。目前我遇到一个问题是:成功建立link,成功建立job,启动job后卡死,不提示任何错误信息,日志文件中也看不到报错信息。这个问题最终也没有解决,因此我转向了sqoop1。mysql
sqoop1要简单不少,减压到指定目录,/etc/profile中配置好HADOOP_COMMON_HOME和HADOOP_MAPRED_HOME环境变量就能够了,若是使用Hbase和Hive,也须要配置相应的环境变量。sqoop1使用上也很简单,就是shell命令的通常用法:命令行里敲sqoop+一些参数。个人使用场景是:把一台Postgresql数据库里的全部数据导入HDFS,下面是shell脚本:sql
#!/bin/bash # transport data from PG to HDFS # parse database names psql -h 10.192.33.55 -p 5432 -U postgres -c '\l' > ./database_info cut -f 1 -d '|' ./database_info | grep '^\s[a-zA-Z]' | sed s/[[:space:]]//g > database_names rm -f ./database_info # get one database name every time and conduct the transformation by sqoop cat ./database_names | while read DBNAME do if [[ $DBNAME != "postgres" && $DBNAME != "template0" && $DBNAME != "template1" ]] then # make dir on HDFS for each database hadoop fs -mkdir /pgdata/$DBNAME # make code dir for each database mkdir ./gencode/$DBNAME SCHEMA=`echo $DBNAME | tr a-z A-Z` echo "start working on the database $DBNAME ********************************** " sqoop-import-all-tables --connect jdbc:postgresql://10.192.33.55:5432/$DBNAME \ --direct --username postgres --password postgres --fields-terminated-by '|' \ --enclosed-by "'" --escaped-by '\' --warehouse-dir /pgdata/$DBNAME -m 1 \ --outdir ./gencode/$DBNAME -- --schema $SCHEMA echo "finished working on database $DBNAME ===================================" fi done
我这里用的是sqoop-import-all-tables,用于导入(入是相对Hadoop来讲的)一个库的全部表,若是须要导入单个表,能够用sqoop-import,而后用--table tablename指定要导入的表。除了导入整个表,sqoop也支持按照必定条件过滤导入数据,经过--where选项实现。下面解释下用脚本中用到的几个参数:shell
--connect: JDBC连接字符串 --username: 数据库用户名 --password: 数据库登陆密码,这是显式指定密码的方式,也能够用-P实现交互式指定密码,还能够经过--password-file经过指定存有密码的文件加载密码。 --direct: 若是能够,绕过普通的jdbc方式连接,使用数据库各自特有的直接连接方式导数据,好比mysql的mysqldump,PG的psql。不是全部数据库产品都支持这种方式。 --fields-terminated-by: 字段之间的分隔符,默认为逗号。 --enclosed-by: 用来将各个字段包起来的字符,模式为空。 --escaped-by: 转义符,好比我这里指定了分隔符'|'转义符'\',若字段内部出现'|'这个字符,就须要将其转义写成'\|'。 --warehouse-dir: 导入HDFS的文件存储目录 -m: map任务数,一些表因为没有主键或者其余缘由不能拆分用于多个map任务,我这里为了方便就所有指定了1个map任务。 --outdir: 导入过程当中生成的java类保存目录 --schema: PG数据库模式,注意这类参数是传递给特定数据库链接工具的(不是sqoop),好比这里的是psql,因此须要出如今一个单独的“--”后面。
须要了解更多参数,请参考官方文档:SqoopUserGuide
导入的结果像下面这样,数据库里的每条记录对应文件里的一行:数据库
'3663684'|'2016-05-12 08:06:00'|'2016-05-13 11:00:00'|'3'|'669'|'62.24'|'2016051200'|'187' '3663685'|'2016-05-12 08:06:00'|'2016-05-13 17:00:00'|'3'|'669'|'9.71'|'2016051200'|'187' '3663686'|'2016-05-12 08:06:00'|'2016-05-13 10:00:00'|'3'|'669'|'72.50'|'2016051200'|'187' '3663687'|'2016-05-12 08:06:00'|'2016-05-13 04:00:00'|'3'|'669'|'1.00'|'2016051200'|'187' '3663688'|'2016-05-12 08:06:00'|'2016-05-13 00:00:00'|'3'|'669'|'1.00'|'2016051200'|'187' '3663689'|'2016-05-12 08:06:00'|'2016-05-13 09:00:00'|'3'|'669'|'110.57'|'2016051200'|'187' '3663690'|'2016-05-12 08:06:00'|'2016-05-13 22:00:00'|'3'|'669'|'13.86'|'2016051200'|'187' '3663691'|'2016-05-12 08:06:00'|'2016-05-13 08:00:00'|'3'|'669'|'109.19'|'2016051200'|'187' '3663692'|'2016-05-12 08:06:00'|'2016-05-13 07:00:00'|'3'|'669'|'104.67'|'2016051200'|'187'
本篇就到此,后续再写一写导入Hbase以及Hive的方法,以及从Hadoop到sql的导出过程。apache