1、Sqoop简介
Apache sqoop是一个专门为高效在Apache hadoop和结构化数据库之间传输大规模数据的工具,可以用来在MySQL,postgresql,Oracle和HDFS之间传输数据。Sqoop开始于2012年3月份,现在是Apache的顶级项目。目前最稳定的sqoop1版本也是sqoop1的最后一个版本是1.4.6,最新的sqoop2版本是1.99.7。Sqoop1和sqoop2之间不兼容。
文档地址:http://sqoop.apache.org/docs/...
2、Sqoop安装
(1)、编辑sqoop/conf/sqoop-env.sh
若是不用hbase和hive的话就不用配置,需要使用zookeeper的话自己配置zookeeper的home,这里仅仅只配置了hive,其他类似。
export HIVE_HOME=XXXX
(2)、编辑sqoop/bin/configure-sqoop
根据需要注释掉自己不用的东西:
根据自己的需要注释掉了 HCAT_HOME 、ACCUMULO_HOME、ZOOKEEPER_HOME
(3)、测试
命令行输入:sqoop version
显示如下:
06/09/19 15:28:49 INFO sqoop.Sqoop: Running Sqoop version: 1.4.5
Sqoop 1.4.5
git commit id 5b34accaca7de251fc91161733f906af2eddbe83
Compiled by abe on Fri Aug 1 11:19:26 PDT 2014
3、sqoop命令行简介
(1)、sqoop list-databases命令
列出pg数据库下的所有数据库:
例子:
sqoop list-databases --connect jdbc:postgresql://host:port --username user --password pass
(2)、sqoop list-tables 命令
列出pg数据库下某数据库下所有表:
例子:
sqoop list-tables --connect jdbc:postgresql://host:port/database --username user --password pass
(3)、sqoop create-hive-table 命令
在hive上创建一个和关系型数据库一样的表:
sqoop create-hive-table --connect jdbc:postgresql://host:port/database --username user --password pass --table table_name --hive-database hive_database --hive-table hive_table_name
其中:
--table 标识关系数据库中的表
--hive-database 标识hive中的目标库
--hive-table 标识hive中的目标表
(4)、 sqoop import 命令
sqoop的核心功能,将数据从关系型数据库导入到hive或者hdfs中
导入数据到hive例子:
sqoop import --connect jdbc:postgresql://$HOST:$PORT/$DATABASES --username $USER --password $PASS --direct --hive-import --hive-database $hive_db --hive-table $hive_tb --map-column-java $arg --map-column-hive $arg --table $pg_tb --where "$wh" -- --schema public --input-null-string '\\N' --input-null-non-string '\\N'
其中:
--connect: 数据库的地址,里面包含有用到的数据库名和端口号等信息
--username: 连接关系型数据库的用户名
--password: 相应的应户名密码
--direct:sqoop的快速传输模式,去掉此命令则会在传输中用MapReduce的方式传输数据
--hive-import:标识传输数据到hive,类似的有--hbase-import等
--hive-database:数据传输到hive的目标数据库
--hive-table:数据传输到hive的目标表
--map-column-java:数据库字段在生成的java文件中会映射为各种属性,且默认的数据类 型与数据库类型保持对应,比如数据库中某字段的类型为bigint,则在Java文件中的数据类型为long型,通过这个属性,可以改变数据库字段在java中映射的数据类型,格式如: –map-column-java DB_ID=String,id=Integer
--map-column-hive:生成hive表时,可以更改生成字段的数据类型,格式如:–map-column-hive TBL_ID=String,LAST_ACCESS_TIME=string
--table:关系型数据库中的表名字
--where:关系型数据库中的限制条件,可以选择同步的数据集合
-- --schema:pg中用到的schema名字
--input-null-string:string类型的字段值为null时的填充值
--input-null-non-string: 非string类型的字段值为null时的填充值
导入数据到hdfs例子:
sqoop import --connect jdbc:postgresql://$HOST:$PORT/$DATABASES --username user --password pass --append --target-dir /user/ticketdev --direct --table ttd_first_order_info -- --schema transformation
其中:
--append:增量同步,每次同步时候先把数据发到临时目录,然后copy到目标目录
--target-dir:目标目录
更新
在用sqoop导入表的时候,发现同一张表从pg到hive会多出来很多几乎全部为null的行,原因是在字段中有n导致的,查资料发现用 --hive-drop-import-delims 可以解决这个问题,用法是直接加上--hive-drop-import-delims就可以了后面不用指定字符,会默认的去掉n,r,01等字符。
例:
sqoop import --connect jdbc:postgresql://$HOST:$PORT/$DATABASES --username $USER --password $PASS --hive-drop-import-delims --hive-import --hive-database $hive_db --hive-table $hive_tb --table $pg_tb -- --schema $pg_db
需要注意的地方是 --hive-drop-import-delims 和 --direct 不兼容!
还会有集群机器访问数据库权限问题。
这样的话就需要走MapReduce的方式同步,问题又出现了:如果表里面没有主键,就需要加上 -m 1,-m 表示启动几个map任务来读取数据 , 如果数据库中的表没有主键这个参数是必须设置的而且只能设定为1 否则会提示错误;
例:
sqoop import -m 1 --connect jdbc:postgresql://$HOST:$PORT/$DATABASES --username $USER --password $PASS --hive-drop-import-delims --hive-import --hive-database $hive_db --hive-table $hive_tb --table $pg_tb -- --schema $pg_db
这时候又会出现提示: hdfs://qunarcluster/user/ticketdev/table_name 这个目录已经存在的问题,现在需要在前面先删除这个目录,然后执行sqoop命令;
更新
pg中数据有乱码的时候,同步到hive会导致hive表大面积乱码。
同步的时候可以限制字符编码:
sqoop import --connect "jdbc:postgresql://HOST:PORT/database?useUnicode=true&characterEncoding=utf-8" --username USER --password PASS --direct --hive-import --hive-database hive_db --hive-table hive_tb --table pg_tb -- --schema pg_schema