您的位置:首页 > 大数据

大数据学习21:sqoop 语法和常用命令和小案例

2017-10-11 17:18 796 查看
1.1.0 sqoop 语法和常用命令

2.1.0 sqoop 典型用法

3.1.0 sqoop 的一个小案例

4.1.0 sqoop 的分区表导入导出

=======================================

1.1.0 sqoop 语法和常用命令

hive导入参数

  --hive-home   重写$HIVE_HOME
  --hive-import          插入数据到hive当中,使用hive的默认分隔符
  --hive-overwrite  重写插入
  --create-hive-table  建表,如果表已经存在,该操作会报错!
  --hive-table 设置到hive当中的表名
  --hive-drop-import-delims  导入到hive时删除 \n, \r, and \01
  --hive-delims-replacement  导入到hive时用自定义的字符替换掉 \n, \r, and \01
  --hive-partition-key          hive分区的key
  --hive-partition-value   hive分区的值
  --map-column-hive           类型匹配,sql类型对应到hive类型

1.1.1 前期准备:

如果sqoop要连接mysql 或者 oracle 需要下载 相应的jdbc

放到 $SQOOP_HOME/lib/ 下 ,如果是CDH 那么放在

/opt/cloudera/parcels/CDH-5.4.10-1.cdh5.4.10.p0.16/lib/sqoop/lib 下
mysql-connector-java-5.1.27-bin.jar
ojdbc6.jar


如果要采用压缩,那么需要在hdfs编译的时候加上native ,否则无法采用压缩。

例子:mvn clean package -Pdist,native -DskipTests -Dtar

1.1.2 list 功能

列出SQL中的所有库

sqoop list-databases --connect jdbc:mysql://192.168.100.100:3306/ -username root -password 123456


连接SQL 并列出库中的表

sqoop list-tables --connect jdbc:mysql://192.168.100.100:3306/oozie --username root --password 123456
sqoop list-tables --connect jdbc:mysql://192.168.100.100:3306/test --username root --password 123456
sqoop list-tables --connect jdbc:oracle:thin:@192.168.4.11:1521:dg1  --username wxk --password wxk


1.1.3 导入 mysql –> hdfs [表如果没有主键,这样会报错,需要特殊指定]

直接导入:

sqoop import \
--connect  jdbc:mysql://localhost:3306/sqoop \
--username root \
--password password \
--table emp


默认splits = 4 ,通过 -m 1 来指定maptask数量,也就是指定结果集分片的数量。

导入放在哪里了呢?默认放在 /user/用户名 下

[root@hadoop002 lib]# hadoop fs -ls /user/root
Found 1 items
drwxr-xr-x   - root supergroup          0 2017-09-23 10:05 /user/root/emp


一些参数解释:

–query 和 –table –where 不能同时使用,必须要加 $CONDITIONS,如果 query 后面是”” 那么要写 \$CONDITIONS 转义字符。

最好把要抽取的列直接写入sql中,这样能避免报错。

-m 指定分片,也是指定maptask数量

–delete-target-dir 覆盖,自动先删再导

–mapreduce-job-name 指定mr作业的名字

–columns “A,B” 导出指定的列

–target-dir EMP_COLUMN 导出到指定的路径 这里 EMP_COLUMN 其实也是表名的意思

–where “sal > 2000” 条件语句,按条件导出

例子1:

将 emp 的部分列 sal > 2000 的数据 从mysql的sqoop的库中 导入到 hdfs 上,存放在 /user/root/EMP_COLUMN 路径,

指定mapreduce的作业名为emp-all ,如果已经存在,那么先删除再导入。

sqoop import \
--connect  jdbc:mysql://localhost:3306/sqoop \
--username root \
--password password \
--table emp \
-m 1 \
--delete-target-dir \
--mapreduce-job-name emp-all \
--columns "empno,ename,job,mgr,sal,deptno" \
--target-dir EMP_COLUMN \
--where "sal > 2000"


例子2:

通过 sql 将数据从 mysql 的sqoop库中导入到hdfs上,存放在/user/root/EMP_COLUMN 路径,

指定mapreduce的作业名为emp-all ,如果已经存在,那么先删除再导入,

将输出文件设置为 parquet 或者 sequencefile 格式。

sqoop import \
--connect  jdbc:mysql://localhost:3306/sqoop \
--username root \
--password password \
-m 1  \
--delete-target-dir \
--mapreduce-job-name emp-all \
--columns "empno,ename,job,mgr,sal,deptno" \
--target-dir EMP_COLUMN \
--query 'select empno,ename,job,mgr,sal,deptno from emp where sal>2000 and $CONDITIONS'
--as-parquetfile 或者 --as-sequencefile

[root@hadoop002 ~]# hadoop fs -ls  /user/root/EMP_COLUMN/
Found 3 items
drwxr-xr-x   - root supergroup          0 2017-09-24 04:24 /user/root/EMP_COLUMN/.metadata
drwxr-xr-x   - root supergroup          0 2017-09-24 04:24 /user/root/EMP_COLUMN/.signals
-rw-r--r--   1 root supergroup       1714 2017-09-24 04:24 /user/root/EMP_COLUMN/d2ce0a72-51e2-4125-accc-deb449c2ac3a.parquet
[root@hadoop002 ~]# hadoop fs -ls    /user/root/EMP_COLUMN/
Found 2 items
-rw-r--r--   1 root supergroup          0 2017-09-24 04:26 /user/root/EMP_COLUMN/_SUCCESS
-rw-r--r--   1 root supergroup        587 2017-09-24 04:26 /user/root/EMP_COLUMN/part-m-00000


例子3:

将导入文件进行压缩 –compression-codec codec为hadoop的压缩模式,-z 为默认gzip

sqoop import \
--connect  jdbc:mysql://localhost:3306/sqoop \
--username root \
--password password \
-m 1  \
--delete-target-dir \
--mapreduce-job-name emp-all \
--columns "empno,ename,job,mgr,sal,deptno" \
--target-dir EMP_COLUMN \
--query 'select empno,ename,job,mgr,sal,deptno from emp where sal>2000 and $CONDITIONS' \
-z


如果用其他格式的压缩,需要配合hdfs上压缩格式使用。

--compression-codec snappy 163k
不用压缩 210k


如何查看能用的压缩格式?

[root@hadoop002 native]# hadoop checknative -a
17/09/26 04:04:31 INFO bzip2.Bzip2Factory: Successfully loaded & initialized native-bzip2 library system-native
17/09/26 04:04:31 INFO zlib.ZlibFactory: Successfully loaded & initialized native-zlib library
Native library checking:
hadoop:  true /opt/software/hadoop-2.6.0-cdh5.7.0/lib/native/libhadoop.so
zlib:    true /lib64/libz.so.1
snappy:  true /opt/software/hadoop-2.6.0-cdh5.7.0/lib/native/libsnappy.so.1
lz4:     true revision:99
bzip2:   true /lib64/libbz2.so.1
openssl: true /usr/lib64/libcrypto.so


例子4:

将多个表的统计结果导出到hdfs 这里好像不好指定具体哪些表,只能一次全导入了。需要进一步研究。

sqoop import-all-tables \
--connect jdbc:mysql://localhost:3306/sqoop  \
--username root \
--password password \
-m 1 \
--delete-target-dir \
--warehouse-dir /output/


多表导入,且每个表都要有主键

[root@hadoop002 ~]# hadoop fs -ls /output
Found 4 items
drwxr-xr-x   - root supergroup          0 2017-09-24 02:00 /output/dept
drwxr-xr-x   - root supergroup          0 2017-09-24 02:00 /output/emp
drwxr-xr-x   - root supergroup          0 2017-09-24 02:01 /output/emp2
drwxr-xr-x   - root supergroup          0 2017-09-24 02:01 /output/salgrade


例子5:

导出没有主键的表,并且使用多个mapper 要指定一下主键列,否则多 map 会报错。–split-by empno。

如果使用单个 map 是不会报错的

sqoop import \
--connect  jdbc:mysql://localhost:3306/sqoop \
--username root \
--password password \
-m 2  \
--delete-target-dir \
--mapreduce-job-name emp-all \
--target-dir EMP3 \
--table emp3 \
--split-by empno


如果不采用–split-by 并且采用多 maptask 会出现报错:

Error during import: No primary key could be found for table emp2. Please specify one with --split-by or perform a sequential import with '-m 1'.


例子6:oracle 的导入 ,oracle –> hdfs

将 t2 表从 oracle 中导入hdfs ,存放在/user/root/T2 路径,

指定mapreduce的作业名为T2-all ,如果已经存在,那么先删除再导入,

将输出文件设置为 parquet 或者 sequencefile 格式。

sqoop import \
--connect jdbc:oracle:thin:@192.168.4.11:1521:dg1 \
--username wxk --password wxk \
--table T2 \
-m 1 \
--delete-target-dir \
--mapreduce-job-name T2-all \
--target-dir T2 \
--compression-codec snappy


例子7:分隔符

将mysql 的 emp2 导入到 hdfs ,放在 /user/root/EMP2_COLUMN 下,覆盖, 分隔符为 \t ,并采用direct

sqoop import \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root \
--password password \
--table emp2 \
-m 1 \
--split-by empno \
--delete-target-dir \
--target-dir EMP2_COLUMN \
--fields-terminated-by '\t'  \           [在注释中介绍为char,说明只能一个字符 $$$ = $]
--null-non-string '0' --null-string '' \ [对于非string 的 null 设为0,对于string 的 null 设为空字符串]
--direct                                 [可以加快传输速度 但是需要底层数据库支持【mysqlimport,比jdbc高效;oracle 支持】,可能会报错]


结果:

[root@hadoop002 ~]# hadoop fs -text /user/root/EMP2_COLUMN/part-m-00000
7369    SMITH   CLERK   7902    1980-12-17 00:00:00.0   800.00  0       20   [\t  分隔符]
7369$SMITH$CLERK$7902$1980-12-17 00:00:00.0$800.00$0$20						 [$$$ 分隔符]


会报这个错误,可能是由于mysql配置原因。

17/09/24 20:39:02 INFO mapreduce.Job: Task Id : attempt_1506081636263_0047_m_000000_0, Status : FAILED
Error: java.io.IOException: Cannot run program "mysqldump": error=2, No such file or directory


例子8: 增量导入

增量导入,增量要设置3个参数

--delete-target-dir 和 append 不能一起用


将mysql 的 emp2 表中数据,以empno列为准,数值为7900以后的数值,以增量方式导入hdfs ,

设置分隔符为 \t ,null字符型为空,null非字符型为 0 。

sqoop import \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
--table emp2 \
-m 1 \
--split-by empno --target-dir EMP2_COLUMN \
--fields-terminated-by '\t' \
--null-non-string '0' --null-string '' \
--check-column empno \
--incremental append \
--last-value 7900


结果:会产生新的文件,按照之前命令,last-value 值之后的为增量输入,产生新文件。

如果为新目录,则会生成一个part-m-00000,如果为老目录,会产生新的part-m-00001,不会删除之前的。

[root@hadoop002 ~]# hadoop fs -ls /user/root/EMP2_COLUMN/
Found 3 items
-rw-r--r--   1 root supergroup          0 2017-09-24 20:40 /user/root/EMP2_COLUMN/_SUCCESS
-rw-r--r--   1 root supergroup        838 2017-09-24 20:40 /user/root/EMP2_COLUMN/part-m-00000
-rw-r--r--   1 root supergroup        116 2017-09-24 20:49 /user/root/EMP2_COLUMN/part-m-00001
[root@hadoop002 ~]# hadoop fs -text /user/root/EMP2_COLUMN/part-m-00001
7902    FORD    ANALYST 7566    1981-12-03 00:00:00.0   3000.00 0       20
7934    MILLER  CLERK   7782    1982-01-23 00:00:00.0   1300.00 0       10


例子9:sqoop eval 用法

用sqoop 去直接查询 mysql中的表,并显示

sqoop eval \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
--query "select * from emp where deptno=10"


例子10:sqoop 的脚本应用,–options-file 传递参数 工作中推荐使用。

[root@hadoop002 data]# cat emp.opt
import
--connect
jdbc:mysql://hadoop002:3306/sqoop
--username
root
--password
password
--table
emp2
-m
1
--split-by
empno
--delete-target-dir
--target-dir
EMP_OPTION
--fields-terminated-by
'\t'
--null-non-string
'0'
--null-string
''


注意:一行只能写一个参数,或者一个值!!!

sqoop --options-file /user/root/emp.opt


运行结果成功

例子11:sqoop job 的使用

工作中建议封装为 sqoop job + crontab

sqoop job –help

注意,import 前面要加 空格

sqoop job --create myjob \
-- import \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
--table emp \
--fields-terminated-by '\t' \
-m 1 \
--delete-target-dir


查看 sqoop job

[root@hadoop002 data]# sqoop job --list


删除 sqoop job

[root@hadoop002 conf]# sqoop job --delete myjob


查看某个sqoop job

[root@hadoop002 data]# sqoop job --show myjob  要输入密码 password


执行某个 sqoop job

[root@hadoop002 data]# sqoop job --exec myjob  要输入密码 password


!!!!如何才能不输入密码,直接执行呢?

[root@hadoop002 conf]# vi sqoop-site.xml  添加
<property>
<name>sqoop.metastore.client.record.password</name>
<value>true</value>
<description>no use the password</description>
</property>


然后重启hive 创建 sqoop job 这样就可以了。

注意:如果是在改参数之前创建的job ,则没有用, 需要重建。

1.1.4 导出 hdfs -> mysql

首先要在mysql上创建表结构

mysql> create table emp_demo as select * from emp where 1=2;


然后用sqoop 导出到mysql

[注意大小写!!!!]

[每操作一次,数据会重复插入。如何解决?配合shell先删除,再插入]

[疑问:分隔符是怎么判断的?]

sqoop export \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
--table emp_demo \
-m 1 \
--export-dir /user/root/EMP2/part-m-00000


1.1.5 导入 RDBMS -> hive

例子1:

将mysql 的 emp 表直接导入到 hive 中,并直接创建hive表。

sqoop import \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
--table emp \
-m 1 \
--delete-target-dir \
--hive-import \
--create-hive-table \   #真实场景不要用 只能执行一次,而且生成的字段类型,用 desc 看可能不一样,一般要自己先创建hive的table
--hive-table emp_import


这里可能会报错:

17/09/25 03:16:04 WARN hive.TableDefWriter: Column empno had to be cast to a less precise type in Hive

如何解决呢?如下:

[root@hadoop002 lib]# cp hive-common-1.1.0-cdh5.7.0.jar /opt/software/sqoop-1.4.6-cdh5.7.0/lib/
[root@hadoop002 lib]# cp hive-shims-* /opt/software/sqoop-1.4.6-cdh5.7.0/lib/


如何指定库? 而且desc 去看的话,字段类型会变。

例子2:

将mysql中的 emp 表导入 hive 中。会自动创建hive表!!!

sqoop import \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
--table emp \
-m 1 \
--delete-target-dir \
--hive-import \
--hive-table emp_import     ##指定hive中具体的某个表


会发现插入了重复数据,如何解决这个问题?

一般是删除原表的数据,再次插入,truncate。

注意:truncate 不能删除外部表!因为外部表里的数据并不是存放在Hive Meta store中

例子3:分隔符问题!!!

注意:sqoop 从 mysql –> hive 只有在第一次创建的时候能指定分隔符,如果创建后,再使用fields-terminated-by 没法更改。

sqoop import \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
--table emp \
-m 1 \
--delete-target-dir \
--hive-import \
--hive-table emp_import2 \
--hive-overwrite \
--fields-terminated-by "\t"


1.1.6 导出 hive –> RDBMS

例子1:

首先要在mysql上创建表结构

mysql> create table emp_demo as select * from emp where 1=2;


然后导出

sqoop export \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
--table emp_demo \
-m 1 \
--export-dir /user/hive/warehouse/emp_import \
--fields-terminated-by '\t'


这里从hive导入到rdbms的时候,hive 表的分隔符是 \u0001 那么这里到 mysql的时候是用 \t 还是 \u001 ?

emp_import  表分隔符为 \u0001 导入到 mysql 时 分隔符用 \t 没有报错,而且mysql正常
emp_import2 表分隔符为 \t 导入到 mysql 时 分隔符用 \t 没有报错,而且mysql正常
而且两种方式混合导入 mysql 表均正常


2.1.0 sqoop 典型用法

2.1.1 sqoop定时增量导入,导入前一天数据到hdfs

(1)增量数据导入

select strace,SDATETIME,NKIND,LNKID,STEMID from OTDRTEST1
where to_date(sdatetime,'yyyy-mm-dd,hh24:mi:ss') >= trunc(sysdate)-1 and
to_date(sdatetime,'yyyy-mm-dd,hh24:mi:ss') < trunc(sysdate);


sudo sqoop import \
--connect jdbc:oracle:thin:@192.168.100.200:1521:orcl \
--username ALEX --password 123456 \
--query "select strace,SDATETIME,NKIND,LNKID,STEMID from OTDRTEST1
where to_date(sdatetime,'yyyy-mm-dd,hh24:mi:ss') >= trunc(sysdate)-1 and
to_date(sdatetime,'yyyy-mm-dd,hh24:mi:ss') < trunc(sysdate) and lnkid=1 and \$CONDITIONS" -m 1 \
--target-dir  /user/hive/warehouse/ecmk/otdrtest11 --fields-terminated-by ","


(2)加载数据到hive表

sudo hive -e "load data inpath '/user/hive/warehouse/ecmk/otdrtest11/part-m-00000' into table otdrtest11"


(3)删除数据存放目录

sudo hadoop dfs -rmr /user/hive/warehouse/ecmk/otdrtest11


(4)清空回收站删除目录

sudo hadoop dfs -rmr /user/root/.Trash/Current/user/hive/warehouse/ecmk/otdrtest11


(5)定时任务

0 */2 * * *  /home/hadoop/sh/otdrtest2.sh
10 22 * * *  /home/hadoop/sh/otdrtest1.sh
*/5 * * * *  /home/hadoop/sh/lnkid.sh


2.2.1 集群hive数据迁移

(1)导出hive表数据到本地文件

导出hive表数据到本地文件(注意:加中间逗号分隔符)

hive (default)> insert overwrite local directory '/home/hadoop/exporthive' ROW FORMAT DELIMITED FIELDS TERMINATED BY','
select strace,sdatetime,nkind,lnkid,stemid from otdrtest1;


(2)本地文件压缩并远程发送

(3)创建hive表

hive (default)> CREATE TABLE OTDRTEST1100(STRACEFULL string,SDATETIME string,NKIND string,LNKID string,STEMID string )
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';


(4)加载本地文件到hive表

load data local inpath '/home/hadoop/exporthive/000000_0' into table otdrtest1100;


3.1.0 sqoop 的一个小案例

需求:mysql 中有 emp 表中有数据,不直接使用mysql统计,而是先将mysql的emp表数据通过sqoop抽取到hive中

然后使用hive,进行统计分析,统计的结果通过sqoop 导出到mysql 中

这是一个典型的ETL(extraction tranformation load)

分析:

1)在hive中创建emp对应的表

2)使用sqoop将mysql中的emp表导入到hive表中

3)在hive中统计分析(每个部门多少人),结果写入到hive结果表中

4)将hive结果表通过sqoop导出到mysql表中

要求:

1)所有步骤,手工执行,单任务执行。

2)shell 脚本

关键点:

我们在测试hdfs导入到关系型表的时候,数据是重复的

思路:在shell中直接访问mysql 表,先将数据清除。

1)truncate 可能适合这个作业

2)如果表是分区表,mysql 必然有一个字段对应分区字段,用shell去删分区的数据。

通过java jdbc 去读 ==> 表 ==> opt 文件,去执行即可

①手动

查看emp表

mysql> select * from emp;


创建hive 导入表

hive (default)>
create table emp_m_to_h
(
empno      int ,
ename      string ,
job        string  ,
mgr        int    ,
hiredate   string  ,
sal        double  ,
comm       double  ,
deptno     int
)
row format delimited fields terminated by '\t';


导入到hive 表

sqoop import \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
--table emp \
-m 1 \
--hive-import \
--hive-table emp_m_to_h \
--hive-overwrite \
--delete-target-dir \
--fields-terminated-by '\t'


查看

[root@hadoop002 ~]# hadoop fs -ls  /user/hive/warehouse/emp_m_to_h
Found 1 items
-rwxr-xr-x   1 root supergroup        871 2017-09-25 06:59 /user/hive/warehouse/emp_m_to_h/part-m-00000


hive (default)> select deptno , count(1) from emp_m_to_h group by deptno ;


生成结果表

注意!!#hive (default)> create table result_h_to_m as select deptno , count(1) as sum_person from emp_m_to_h group by deptno ;


上面这样不行,因为生成的表格式不对,没有分隔符等,导出到mysql会报错。

create table result_h_to_m (deptno int,sum_person int) row format delimited fields terminated by '\t';
insert overwrite table result_h_to_m select deptno , count(1) as sum_person from emp_m_to_h group by deptno ;


创建mysql上结果表

mysql> create table result_a (deptno int,sum_person int);


导出到mysql

sqoop export \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
--table result_a \
-m 1 \
--export-dir /user/hive/warehouse/result_h_to_m \
--fields-terminated-by '\t'


②shell脚本

[root@hadoop002 ETL]# cat ETL.sh
#!/bin/bash
#mysql emp - > hive emp_m_to_h - > calculate - > hive result_h_to_m - > mysql result_a
########改进版
export MYSQL_BASE=/usr/local/mysql
export PATH=$PATH:$MYSQL_BASE/bin
ETL_LOG=/root/data/ETL/etl.log
TODAY=`date`

RUN_STR="
export MYSQL_BASE=/usr/local/mysql
export PATH=$PATH:$MYSQL_BASE/bin
ETL_LOG=/root/data/ETL/etl.log
TODAY=`date`
mysql -uroot -ppassword sqoop -e \"select * from emp\"
hive -e \"create table if not exists emp_m_to_h (
empno int ,
ename string ,
job string ,
mgr int ,
hiredate string ,
sal double ,
comm double ,
deptno int) row format delimited fields terminated by '\t';\"

sqoop import \ --connect jdbc:mysql://hadoop002:3306/sqoop \ --username root --password password \ --table emp \ -m 1 \ --hive-import \ --hive-table emp_m_to_h \ --hive-overwrite \ --delete-target-dir \ --fields-terminated-by '\t'

hive -e \"create table if not exists result_h_to_m (deptno int,sum_person int) row format delimited fields terminated by '\t';\"
hive -e \"insert overwrite table result_h_to_m select deptno , count(1) as sum_person from emp_m_to_h group by deptno ;\"

mysql -uroot -ppassword sqoop -e \"drop table result_a;\"
mysql -uroot -ppassword sqoop -e \"create table result_a (deptno int,sum_person int);\"

sqoop export \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
--table result_a \
-m 1 \
--export-dir /user/hive/warehouse/result_h_to_m \
--fields-terminated-by '\t'

mysql -uroot -ppassword sqoop -e \"select * from result_a;\" > /root/data/ETL/result_a

"

echo $TODAY >> $ETL_LOG
/bin/sh -c "$RUN_STR" >> $ETL_LOG

echo `date +%Y/%m/%d-%H:%M:%H` === "success" >> $ETL_LOG


4.1.0 sqoop 的分区表导入导出

PS:

创建分区表

hive> create table order_partition(
order_number string,
event_time string
)
partitioned by (event_month string)
row format delimited fields terminated by '\t';

#本地
load data local inpath '/root/data/order_created.txt' overwrite into table order_partition partition(event_month = '201405')
或者 创建动态分区表
hive> create table emp_dynamic_partition(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double
)partitioned by (deptno int)
row format delimited fields terminated by '\t';
hive> insert into table emp_dynamic_partition partition(deptno)
select empno ,ename ,job ,mgr ,hiredate,sal ,comm ,deptno from emp;


4.1.1 导入 mysql(RDBMS) -> hive

–hive-partition-key hive分区的key

–hive-partition-value hive分区的值

例子1:对于只有单分区字段的导入

将emp表全部导入,成为某个分区表,分区表名为 emp_pardept10 ,分区为字段为 deptnumber ,值为 10

sqoop import \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
--table emp \
-m 1 \
--delete-target-dir \
--hive-import \
--hive-table emp_pardept10 \
--hive-overwrite \
--fields-terminated-by "\t" \
--hive-partition-key deptnumber \
--hive-partition-value "10"
[root@hadoop002 ETL]# hadoop fs -ls /user/hive/warehouse/emp_pardept10
Found 1 items
drwxr-xr-x   - root supergroup          0 2017-09-26 08:38 /user/hive/warehouse/emp_pardept10/deptnumber=10


注意:分区字段必须不是表的字段,否则会报错!

例子2:将某个rdbms的表 用 分区表形式 导入 到 hive

sqoop import \
--connect jdbc:mysql://hadoop002:3306/sqoop \
--username root --password password \
-m 1 \
--delete-target-dir \
--hive-import \
--query 'select empno,ename,job,mgr,sal,deptno from emp where sal>2000 and $CONDITIONS' \
--target-dir /user/hive/warehouse/emp_pardept10/ \
--hive-table emp_pardept10 \
--hive-overwrite \
--fields-terminated-by "\t" \
--hive-partition-key deptnumber \
--hive-partition-value "10"


注意:这里–query 和 –target-dir 必须连用

例子3:对于多分区字段的导入

不能再用–hive-table, –hive-partition-key, –hive-partition-value这三个参数。因为这样只能向单个分区导入数据,无法指定多个分区;其次,–where条件中没有用and。

所以可以分两步解决这个问题:

hive上创建track_log 为分区表 ;

mysql> create table track_log (
id                         string ,
url                        string ,
cityId                     string )
PARTITIONED BY (ds string,hour string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';


track_log18 为mysql(rdbms) 上的一个表;

1) 首先确保目标分区中没有数据,即/user/hive/warehouse/track_log/ds=20150827/hour=18目录是空的;

2) 将数据直接上传到指定的数据仓库目录中

sqoop import --connect  jdbc:mysql://localhost:3306/track_log \
--username root --password Nokia123  \
--table track_log18 \
-m 1  \
--target-dir /user/hive/warehouse/track_log/ds=20150827/hour=18 \
--fields-terminated-by '\t'  //这个也很重要,否则查询一列时会返回多列


###上面这个命令可以看做mysql 导入到 hdfs


结果:

开始没结果

hive> select id from track_log  limit 2;
OK
Time taken: 0.584 seconds


加入分区就好了

hive> alter table track_log add partition(ds='20150828' ,hour='18') location '/user/hive/warehouse/track_log/ds=20150828/hour=18';
OK
Time taken: 0.759 seconds
hive> select id from track_log limit 2;
OK
121508281810000000
121508281810000001


4.1.2 导出 hive -> mysql(RDBMS)

sqoop export --connect jdbc:mysql://localhost:3306/test \
--username root --password 123456 --table tablename \
--export-dir /user/hive/warehouse/database/tablename1/part_date=2015-06-16 \
--input-fields-terminated-by ','


非分区表:/user/hive/warehouse/database1/tablename
分区表:/user/hive/warehouse/database1/tablename/part_date=2015-06-16


这是目前我对SQOOP的理解,如果有不准确的地方,欢迎指正哈!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: