Sqoop使用笔记

[TOC]

最近在研究数据采集相关的知识,需要用到Sqoop把关系型数据库的数据导入到Hive里,这里记录下自己的使用心得,更多的是需要注意的地方。

环境准备

OS: MacOS
Hadoop: 2.7.2
Hive: 1.0.0
Sqoop: 1.4.6

根据Sqoop官网说法,Sqoop2 目前还未开发完,不建议在生产环境使用,所以这里选的是Sqoop的稳定版 1.4.6
Hadoop和Hive的安装与配置可以参考网上的资料,Sqoop环境配置注意修改 ${SQOOP_HOME}/conf/sqoop_env.sh ,如果使用MySQL,还要将MySQL的驱动jar包拷贝到 ${SQOOP_HOME}/lib 目录下

Sqoop简介

Sqoop是一个用于Hadoop和关系型数据库或主机之间的数据传输工具。它可以将数据从关系型数据库import到HDFS,也可以从HDFS export到关系型数据库,通过Hadoop的MapReduce实现。

Sqoop命令

执行 $sqoop help, 可以看到Sqoop支持的命令:

Sqoop命令

具体使用方法参见官方文档, 这里我们主要介绍下 import 命令的注意点

sqoop-import 注意点

import 可能会用到的参数:

Argument Described
--append Append data to an existing dataset in HDFS
--as-sequencefile import序列化的文件
--as-textfile import plain文件 ,默认
--columns <col,col,col…> 指定列import,逗号分隔,比如:--columns "id,name"
--delete-target-dir 删除存在的import目标目录
--direct 直连模式,速度更快(HBase不支持)
--fetch-size <n> 一次从数据库读取 n 个实例,即n条数据
-m,--num-mappers <n> 建立 n 个并发执行task import
-e,--query <statement> 构建表达式<statement>执行
--split-by <column-name> 根据column分隔实例
--autoreset-to-one-mappe 如果没有主键和split-by 用one mapper import (split-by 和此选项不共存)
--table <table-name> 指定表名import
--target-dir <d> HDFS destination dir
--warehouse-dir <d> HDFS parent for table destination
--where <where clause> 指定where从句,如果有双引号,注意转义 \$CONDITIONS,不能用or,子查询,join
-z,--compress 开启压缩
--null-string <null-string> string列为空指定为此值
--null-non-string <null-string> 非string列为空指定为此值,-null这两个参数are optional, 如果不设置,会指定为"null"
  1. 如果是分布式环境,--connect参数不要写成localhost,应该写TaskTracker节点的地址

  2. 数据库登录密码可以指定文件 --password-file ${user.home}/.password这个文件可以放到local或者hdfs上,注意:此文件不能有空格,echo -n "secret" > password.file

  3. 尽量别用 --password,不安全(ps命令可以获取到此参数), 可以用-P输入console方式, 注意:密码可以设置别名:--password-alias

  4. -m <n> 并发数默认是4 task, 并发数n不要超过可用的MapReduce集群数,也不要超过数据库支持限度。并发原理:假定split-column = id,数据库中 id = 0-1000,sqoop默认4个task,切成0-250,251-500 ... 不支持多列 split. (可以看到hdfs里有按并发数切了4个切片)

  5. 当使用Oozie启动Sqoop job时,添加 --skip-dist-cache 参数,Oozie会cache job需要的lib包

  6. --warehouse-dir 可以指定父级目录,与 --target-dir 不共存

  7. --map-column-java, --map-column-hive 指定某几列映射成Java或Hive的列属性

  8. 支持增量 --incremental <mode> mode指定为append或lastmodified,还要指定列增量的值,感觉不是很好用,万一数据是更新怎么办?

  9. 导出数据文件分两种 delimited 和 序列化文件,还可以-z压缩

  10. 如果列含有BLOB或CLOB等大型数据列,--inline-lob-limit 可以限制下,暂时先不研究

  11. 其他涉及到import export特殊字符转义的先不考虑,如果需要可以参见 Table6、7 Format

  12. 数据导入Hive


  • --hive-overwrite: 全表overwrite(需配合--hive-import使用,如果Hive里没有表会先创建之)

  • --create-hive-table: 自动推断表字段类型直接建表,overwrite功能可以完全替代掉了(但hive里此表不能exist,所以在import前要先drop下)

  • --hive-import - -hive-overwrite 这两个参数组合很不错 (直接overwrite也可以,但是考虑到如果表结构有变化,hive里是不会感知到的,所以还是先drop吧)

  • 如果含有特殊字符,需要转义可以用 -detlims 参数,这个参数只能用于hive默认分隔符

  • 默认用"null" 代替 NULL,而Hive \N 标识 NULL值,可以使用--null-string '\\N' --null-non-string '\\N' 解决这个问题, 没什么特殊要求就加上吧

  • Hive也可以使用 --compress 压缩,但是缺点是很多解码器不支持并行任务的split,貌似lzop解压可以,但是要求颇多,不建议使用

  • Hive里不支持 SQL 类型:bit(2),这样是不妥的,应该改成 bit(1)

  1. Sqoop支持import到 HBase,Accumulo 时间关系,暂不研究
  2. 支持额外的参数 conf/sqoop-site.xml 自己配置去(-…-)

sqoop-import-all-tables 注意点

  1. import-all-tables 可以整库的import,但有以为下限制条件:
  • 每个表都必须有一个单列主键,或者指定--autoreset-to-one-mapper参数
  • 每个表只能import全部列,即不可指定列import
  • 不能使用非默认的分隔符,不能指定 where 从句
  1. --exclude-tables <tables>此参数可以 exlude掉不需要import的表(多个表逗号分隔)
  2. 不可以使用 --table, --split-by, --columns, --where,--delete-target-dir 等等参数
  3. 不支持 --class-name,可以用 --package-name 指定package
  4. 一旦执行过程中有异常抛出,会立即停止

sqoop-import-mainframe

直接import主机!这个命令过于暴力,和import-all-tables差别不大,等有需要在研究研究吧。

sqoop-job 注意点

Sqoop可以将import任务保存为job,可以理解为起了个别名,这样方便的Sqoop任务的管理。

参数列表:
Argument Described
--create <job-id> 创建一个job,job-id是job名称,
--delete <job-id> 删除这个job
--exec <job-id> 执行这个job
--show <job-id> Show the parameters for a saved job.
--list List all saved jobs
--meta-connect <jdbc-uri> Specifies the JDBC connect string used to connect to the metastore
job存储方案

job的是有两种存储方案的,通过配置--meta-connect或者在conf/sqoop-site.xml 里配置 sqoop.metastore.client.autoconnect.url 参数来指定是否使用metastore-client

方案A(推荐):不使用metastore-client

如果job信息放到 ${HOME}/.sqoop 目录下,此目录下有两个文件:
metastore.db.properties:metastore的配置信息
metastore.db.script:job的详细信息,通过sql语句存储

方案B: 不使用metastore-client

此时,job的信息会存储到配置的 autoconnect.url 的 SQOOP_SESSION 表里,但是此方案会有个bug,我本地在执行创建job的时候报错:

ERROR tool.JobTool: I/O error performing job operation: java.io.IOException: Invalid metadata version

上网查了下解决方案,发现 SQOOP_ROOT 表需要插入条数据:

INSERT INTO SQOOP_ROOT VALUES(NULL,'sqoop.hsqldb.job.storage.version','0');

所以,还是使用方案A吧,这样也不会对数据库造成入侵

注意: 如果使用Oozie执行sqoop-job的话,务必将sqoop-site.xml 中的 sqoop.metastore.client.record.password参数设置为true

其他命令

  1. sqoop-export:HDFS export 到关系型数据库,目标table必须存在,可分为insert和update模式
  2. sqoop-metastore:指定metadata仓库,可在配置文件中设置
  3. sqoop-merge:合并两个数据集,一个数据集的记录应该重新旧数据集的条目
  4. sqoop-codegen:将数据集封装成Java类
  5. sqoop-create-hive-table:Sqoop单独提供了针对Hive的命令,可以代替 sqoop import --hive-import, 其他参数一样
  6. sqoop-eval:执行sql语句,结果会打印在控制台,可以用来校验下import的查询条件是否正确
  7. sqoop-list-databases,sqoop-list-tables:列出数据库,列出表

以上命令暂时没用到或很简单,等以后需要的时候再去研究吧

HCatalog

HCatalog提供表和存储管理服务,使不同的Hadoop数据处理工具如:Pig,MapReduce,Hive更容易读取和写入数据网格

看文档比较复杂,暂时用不到,等以后需要的时候再去研究吧o(╯□╰)o

需要注意的地方

  1. MySQL
  • MySQL允许Date类型字段出现'0000-00-00',Sqoop有三种方式处理这种情况:1. 转成NULL(默认),2. 抛出异常 3. 置成'0001-01-01', 配置zeroDateTimeBehavior参数设置,跟在connect string后面
  • UNSIGNED 列, MySQL 范围:0 ~ 2^32 ,Sqoop范围:-2^31~ +2^31-1, 注意不要越界
  1. Hive
  • DATE, TIME, TIMESTAMP 类型转换到Hive里会被处理为 String
  • NUMERIC, DECIMAL 类型转换到Hive里会被处理为 DOUBLE
  • Sqoop会打印warn日志警告可能会丢失精度
  1. --direct 参数目前只有MySQL和PostgreSQL(import) 支持,不支持BLOB, CLOB, LONGVARBINARY 列
  2. --direct不支持视图

最佳实践

根据我的个人需求,配置了适合我的最佳Sqoop参数(∩_∩)

单表import到Hive:

sqoop import  \
  --connect jdbc:mysql://127.0.0.1:3306/database_name \
  --username root \
  --password 123456 \
  --table table_name \
  --outdir \${HOME}/.sqoop/java  \
  --delete-target-dir \
  --hive-import \
  --hive-overwrite \
  --null-string '\\N' \ 
  --null-non-string '\\N' \
  -m 8 \
  --direct

整库import到Hive:

sqoop import-all-tables \
  --connect jdbc:mysql://127.0.0.1:3306/database_name \
  --username root \
  --password 123456 \
  --outdir \${HOME}/.sqoop/java  \
  --hive-import \
  --hive-overwrite \
  --null-string '\\N' \ 
  --null-non-string '\\N'  \
  -m 8 \
  --direct

说明:
--out-dir:指定Java文件的路径
--delete-target-dir:删除HDFS目录
--hive-import:直接导入的Hive
--hive-overwrite:全表覆盖(如果表不存在会直接创建表)
--null-string:指定String列如果为NULL转换到Hive里也为NULL
--null-non-string:指定String列如果为NULL转换到Hive里也为NULL
-m 8:8个并发
--direct:直连模式,使用mysqldump加快速度(本地测试13W条数据,74M, 快了10%左右)

最后

通过几天对Sqoop的研究,掌握了Sqoop import的基本用法,更高级的用法还有待探索,最近在写个Sqoop的Java工具类,希望能通过API的形式执行Sqoop命令,以后也会加入Oozie对Sqoop job的管理。

PS:Sqoop2 有很多新特性, 支持命令行、Web UI、REST API,支持server模式同时也更安全易用,所以很期待Sqoop的 2.0 版!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容