sqoop学习总结

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

相关文章
相关标签/搜索