7.sqoop知识点

一、复习flume

1. flume的简介
	- flume是apache基金会旗下的一款项目
	- flume用于采集数据,通常采集的是行为数据(日志文件)
	(结构上分类:结构化数据,半结构化的数据,非结构化的数据
		采集数据的种类进行分类:行为数据(日志文件),业务数据,内容数据,第三方数据源)
	- flume具有的特点:分布式的,可靠性的,高可用的等				  
2. flume的体系结构
	- 运行单元是agent, agent至少包含一个source,一个channel,一个sink
	- source: 用于与数据源交互,将数据封装成event,传输给channel
	- channel:用于缓存event,提高传输效率,提高数据传输的安全性,并将数据传输给sink
			  常用的有memory: 内存   效率更高
			  	     file:  文件	 更安全
	- sink:  用于接收channel里的event, 将数据存储到文件系统上或者是下游的agent的source中	
    - event: 是采集的每一条记录,event的结构有两部分:
    		 (1)Map<String,String>的header,存储键值对
    		 (2)byte[]类型的body,存储的是采集的数据
    - interceptor:拦截器,拦截event,分析event和修改event
    			  作用位置:source和sink端
    			  常用拦截器:timestamp,host,static,regex,自定义
    - selector: 选择器,将event分发到不同的channel里
    			 位置:source端
    			 常用的选择器:
    			 	(1)replicating,复用选择器: 复制event到所有的channel里,
    			 	(2)multiplexing,多副路选择器:根据键值对的不同,将event分到不同的channel里
    - processor:处理器, 可以自动容灾或者是负载均衡
    				   failover
    				   load_balance: random,round_robin
    - flow: event在传输过程中的一个抽象概念				   
3. flume的数据流模型
	- 单agent
	- 多agent串联
	- 多agent汇聚并联
	- sinkgroups
4. flume的方案配置模板
5. flume的安装
6. flume的基本用法
	常用的source: spooldir,taildir,exec,syslogtcp,http,avro
	常用的channel: memory,file
	常用的sink:   logger,hdfs,avro, hbase,hive
7. flume的拦截器和选择器
8. flume的处理器(自动容灾和负载均衡)

二、sqoop的简介

2.1 产生背景

- 数据仓库的数据应该是集成的,也就是说不光只有行为数据,还要有业务数据,这样一起分析才更具有意义
- 基于上述需求,业务数据也应该导入到数据仓库。
- 但是以前将业务数据(在关系型数据库中)导入到hadoop中是非常困难的,所有市场需要一款可以方便导入和导出的工具
- 此时sqoop,datax,kettle等工具应运而生

2.2 sqoop是什么

1. sqoop是apache基金会旗下的一款工具
2. 功能是可以将数据在关系型数据库和hadoop生态体系之间进行传输。
3. 导入(import):指的数据从关系型数据库传输到hadoop生态体系
   导出(export):指的数据从hadoop生态体系到关系型数据库

2.3 sqoop的原理

1. sqoop底层使用的是mapreduce的N个MapTask来完成数据的导入导出
2. 由于使用MapTask,虽然能并行执行,加快速度,但是处理的数据依然是离线数据(静态数据),所以是一种批处理的方式,难以实现实时数据的导入导出。
3. 参考文档里的图片

2.4 sqoop的特点

优点:可以跨平台进行数据传输
缺点:不够灵活
目前只支持:
	mysql<---->hdfs
	mysql<---->hive
    mysql---->hbase

三、sqoop的安装

1、上传、解压、更名

[root@qianfeng01 ~]# tar -zxvf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C /usr/local/
[root@qianfeng01 local]# mv sqoop-1.4.7.bin__hadoop-2.6.0/ sqoop

2、配置环境变量

[root@qianfeng01 local]# vim /etc/profile
................
#sqoop environment
export SQOOP_HOME=/usr/local/sqoop
export PATH=$SQOOP_HOME/bin:$PATH

[root@qianfeng01 local]# source /etc/profile

3、配置sqoop的环境脚本文件

[root@qianfeng01 conf]# cp sqoop-env-template.sh sqoop-env.sh
#Set path to where bin/hadoop is available
export HADOOP_COMMON_HOME=/usr/local/hadoop

#Set path to where hadoop-*-core.jar is available
export HADOOP_MAPRED_HOME=/usr/local/hadoop

#set the path to where bin/hbase is available
export HBASE_HOME=/usr/local/hbase

#Set the path to where bin/hive is available
export HIVE_HOME=/usr/local/hive

#Set the path for where zookeper config dir is
export ZOOCFGDIR=/usr/local/zookeeper/conf

4、导入mysql驱动到lib目录

mysql-connector-java-5.1.xxx.jar

四、常用指令介绍

1)常用指令的查看

sqoop help

usage: sqoop COMMAND [ARGS]

Available commands:
  codegen            Generate code to interact with database records
  create-hive-table  Import a table definition into Hive
  eval               Evaluate a SQL statement and display the results
  export             Export an HDFS directory to a database table
  help               List available commands
  import             Import a table from a database to HDFS
  import-all-tables  Import tables from a database to HDFS
  import-mainframe   Import datasets from a mainframe server to HDFS
  job                Work with saved jobs
  list-databases     List available databases on a server
  list-tables        List available tables in a database
  merge              Merge results of incremental imports
  metastore          Run a standalone Sqoop metastore
  version            Display version information

2)查看指定命令的帮助信息

sqoop help COMMAND

1)比如查看ist-databases的帮助信息
sqoop help ist-databases

usage: sqoop list-databases [GENERIC-ARGS] [TOOL-ARGS]
Common arguments:
   --connect <jdbc-uri>                                       Specify JDBC
                                                              connect
                                                              string
   --connection-manager <class-name>                          Specify
                                                              connection
                                                              manager
                                                              class name
   --connection-param-file <properties-file>                  Specify
                                                              connection
                                                              parameters
                                                              file
   --driver <class-name>                                      Manually
                                                              specify JDBC
                                                              driver class
                                                              to use
   --hadoop-home <hdir>                                       Override
                                                              $HADOOP_MAPR
                                                              ED_HOME_ARG
   --hadoop-mapred-home <dir>                                 Override
                                                              $HADOOP_MAPR
                                                              ED_HOME_ARG
   --help                                                     Print usage
                                                              instructions
   --metadata-transaction-isolation-level <isolationlevel>    Defines the
                                                              transaction
                                                              isolation
                                                              level for
                                                              metadata
                                                              queries. For
                                                              more details
                                                              check
                                                              java.sql.Con
                                                              nection
                                                              javadoc or
                                                              the JDBC
                                                              specificaito
                                                              n
   --oracle-escaping-disabled <boolean>                       Disable the
                                                              escaping
                                                              mechanism of
                                                              the
                                                              Oracle/OraOo
                                                              p connection
                                                              managers
-P                                                            Read
                                                              password
                                                              from console
   --password <password>                                      Set
                                                              authenticati
                                                              on password
   --password-alias <password-alias>                          Credential
                                                              provider
                                                              password
                                                              alias
   --password-file <password-file>                            Set
                                                              authenticati
                                                              on password
                                                              file path
   --relaxed-isolation                                        Use
                                                              read-uncommi
                                                              tted
                                                              isolation
                                                              for imports
   --skip-dist-cache                                          Skip copying
                                                              jars to
                                                              distributed
                                                              cache
   --temporary-rootdir <rootdir>                              Defines the
                                                              temporary
                                                              root
                                                              directory
                                                              for the
                                                              import
   --throw-on-error                                           Rethrow a
                                                              RuntimeExcep
                                                              tion on
                                                              error
                                                              occurred
                                                              during the
                                                              job
   --username <username>                                      Set
                                                              authenticati
                                                              on username
   --verbose                                                  Print more
                                                              information
                                                              while
                                                              working

3)去官网上查询

http://sqoop.apache.org/docs/1.4.7/SqoopUserGuide.html#_literal_sqoop_list_databases_literal

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HNFhsmxA-1615385990983)(ClassNotes.assets/image-20201028104049913.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cWzCoLBz-1615385990987)(ClassNotes.assets/image-20201028104132124.png)]

五、sqoop的基本用法

5.1 查询数据库和表

1)查看数据库
sqoop list-databases --connect jdbc:mysql://10.36.149.27:3306 --username root --password 123456
sqoop list-databases --connect jdbc:mysql://qianfeng03:3306 --username root --password @Mm123123

2)查看指定数据库hive下的表
sqoop list-tables \
--connect jdbc:mysql://qianfeng03:3306/hive \
--username root \
--password @Mm123123 

5.2 mysql<==>hdfs

5.2.0 准备数据

create database sz2003 default character set utf8;
use sz2003;
## emp
表 有主键
DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp` (
`EMPNO` int(4) NOT NULL,
`ENAME` varchar(10),
`JOB` varchar(9),
`MGR` int(4),
`HIREDATE` date,
`SAL` int(7),
`COMM` int(7),
`DEPTNO` int(2),
PRIMARY KEY (`EMPNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `emp` VALUES ('7369', 'SMITH', 'CLERK', '7902', '1980-12-17', '800', null, '20');
INSERT INTO `emp` VALUES ('7499', 'ALLEN', 'SALESMAN', '7698', '1981-02-20', '1600', '300', '30');
INSERT INTO `emp` VALUES ('7521', 'WARD', 'SALESMAN', '7698', '1981-02-22', '1250', '500', '30');
INSERT INTO `emp` VALUES ('7566', 'JONES', 'MANAGER', '7839', '1981-04-02', '2975', null, '20');
INSERT INTO `emp` VALUES ('7654', 'MARTIN', 'SALESMAN', '7698', '1981-09-28', '1250', '1400', '30');
INSERT INTO `emp` VALUES ('7698', 'BLAKE', 'MANAGER', '7839', '1981-05-01', '2850', null, '30');
INSERT INTO `emp` VALUES ('7782', 'CLARK', 'MANAGER', '7839', '1981-06-09', '2450', null, '10');
INSERT INTO `emp` VALUES ('7788', 'SCOTT', 'ANALYST', '7566', '1987-04-19', '3000', null, '20');
INSERT INTO `emp` VALUES ('7839', 'KING', 'PRESIDENT', null, '1981-11-17', '5000', null, '10');
INSERT INTO `emp` VALUES ('7844', 'TURNER', 'SALESMAN','7698', '1981-09-08', '1500', '0', '30');
INSERT INTO `emp` VALUES ('7876', 'ADAMS', 'CLERK', '7788', '1987-05-23', '1100', null, '20');
INSERT INTO `emp` VALUES ('7900', 'JAMES', 'CLERK', '7698', '1981-12-03', '950', null, '30');
INSERT INTO `emp` VALUES ('7902', 'FORD', 'ANALYST', '7566', '1981-12-03', '3000', null, '20');
INSERT INTO `emp` VALUES ('7934', 'MILLER', 'CLERK', '7782', '1982-01-23', '1300', null, '10');

## 学生表  没有主键
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `s_id` varchar(20) NOT NULL,
  `s_name` varchar(20) NOT NULL DEFAULT '',
  `s_birth` varchar(20) NOT NULL DEFAULT '',
  `s_sex` varchar(10) NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `student` VALUES 
('01','赵雷','1990-01-01','男'),
('02','钱电','1990-12-21','男'),
('03','孙风','1990-05-20','男'),
('04','李云','1990-08-06','男'),
('05','周梅','1991-12-01','女'),
('06','吴兰','1992-03-01','女'),
('07','郑竹','1989-07-01','女'),
('08','王菊','1990-01-20','女'),
('09','张飞','1990-9-25','男'),
('10','刘备','1990-01-25','男'),
('11','关羽','1990-01-25','男');

5.2.1 mysql—>hdfs

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FDjyWEI7-1615385990990)(ClassNotes.assets/image-20201028111041760.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BBBPVHcc-1615385990994)(ClassNotes.assets/image-20201028114137248.png)]

案例1)导入有主键表到hdfs
sqoop import \
--connect jdbc:mysql://qianfeng03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp \
--target-dir /sqoop/mysql-hdfs/emp 


注意:数据的split 个数由maptask的数量控制,数据范围由切分字段最大值和最小值确定范围,然后均分
7934-7368 = 566 /4    141.25

7369~ 7368+141= 7509
7510 ~7509+141 = 7650
7651 ~7650+141 = 7791
7792~ 7791+141 = 7934
案例2)导入无主键表到hdfs
sqoop import \
--connect jdbc:mysql://qianfeng03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table student \
--target-dir /sqoop/mysql-hdfs/student

结论:无主键的表需要指定--split-by参数或者是将maptask的数量设置为1

修改如下:

第一种方式:
sqoop import \
--connect jdbc:mysql://qianfeng03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table student \
--target-dir /sqoop/mysql-hdfs/student \
--delete-target-dir \
-m 1

第二种方式:注意可能报错
sqoop import -Dorg.apache.sqoop.splitter.allow_text_splitter=true \
--connect jdbc:mysql://qianfeng03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table student \
--target-dir /sqoop/mysql-hdfs/student \
--split-by s_id

注意: 如果报以下错误,需要将提示中的属性和值添加到导入语句中

ERROR tool.ImportTool: Import failed: java.io.IOException: Generating splits for a textual index column allowed only in case of "-Dorg.apache.sqoop.splitter.allow_text_splitter=true" property passed as a parameter
案例3)指定列分隔符
sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp \
--target-dir /sqoop/mysql-hdfs/emp \
--delete-target-dir \
--fields-terminated-by '\t' \
-m 1
案例4)测试columns
sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--columns "empno,ename,deptno" \
--table emp \
--target-dir /sqoop/mysql-hdfs/emp \
--delete-target-dir \
--fields-terminated-by '\t' \
-m 1
案例5)测试where
sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--columns "empno,ename,deptno" \
--table emp \
--where "deptno=10 or deptno=30" \
--target-dir /sqoop/mysql-hdfs/emp \
--delete-target-dir \
--fields-terminated-by '\t' \
-m 1
案例6)测试-e|–query
sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--query 'select empno, ename,deptno from emp where $CONDITIONS and deptno=10' \
--target-dir /sqoop/mysql-hdfs/emp \
--delete-target-dir \
--fields-terminated-by '\t' \
--split-by 'empno' 

注意事项:

--1. 如果使用--query 不能使用--table
--2. 如果使用--query, select语句中必须要有where子句,子句中必须要有$CONDITIONS 
--3. select语句可以使用单引号,也可以使用双引号,如果使用双引号,那么$必须加转义字符
--4. 如果使用--query,需要指定切分字段,也就是参数--split-by
--5. 可以使用--where参数,但是不生效。
案例7)测试字符串类型的null处理和非字符串类型的null处理
mysql> update emp set job=null where empno = 7934;


sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp \
--target-dir /sqoop/mysql-hdfs/emp \
--delete-target-dir \
--fields-terminated-by '\t' \
--null-string '\\N' \
--null-non-string '-1' \
-m 1

5.2.2 hdfs–>mysql

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wn0gbwp7-1615385990997)(ClassNotes.assets/image-20201028142336072.png)]

注意:导出时,mysql中的表必须提前创建。

1)创建一个带有主键约束的表emp_1,字段数与hdfs上的一致
DROP TABLE IF EXISTS `emp_1`;
CREATE TABLE `emp_1` (
`EMPNO` int(4) NOT NULL,
`ENAME` varchar(10),
`JOB` varchar(9),
`MGR` int(4),
`HIREDATE` date,
`SAL` int(7),
`COMM` int(7),
`DEPTNO` int(2),
PRIMARY KEY (`EMPNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2)创建一个带有主键约束的表emp_2,字段数少于hdfs上的列数
DROP TABLE IF EXISTS `emp_2`;
CREATE TABLE `emp_2` (
`EMPNO` int(4) NOT NULL,
`ENAME` varchar(10),
`JOB` varchar(9),
`MGR` int(4),
`HIREDATE` date,
`SAL` int(7),
PRIMARY KEY (`EMPNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3)创建一个带有主键约束的表emp_3,字段数多于hdfs上的列数
DROP TABLE IF EXISTS `emp_3`;
CREATE TABLE `emp_3` (
`EMPNO` int(4) NOT NULL,
`ENAME` varchar(10),
`JOB` varchar(9),
`MGR` int(4),
`HIREDATE` date,
`SAL` int(7),
`COMM` int(7),
`DEPTNO` int(2),
`age` int,
PRIMARY KEY (`EMPNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4)创建一个无主键的表
DROP TABLE IF EXISTS `emp_4`;
CREATE TABLE `emp_4` (
`EMPNO` int(4) NOT NULL,
`ENAME` varchar(10),
`JOB` varchar(9),
`MGR` int(4),
`HIREDATE` date,
`SAL` int(7),
`COMM` int(7),
`DEPTNO` int(2)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
案例1)代有主键字段的表,字段数相同
sqoop export \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp_1 \
--export-dir /sqoop/mysql-hdfs/emp \
-m 1

注意事项:导出时,字段之间的切分符号默认是逗号。如果hdfs上的文件不是逗号分隔符,需要使用--fields-terminated-by或--input-fields-terminated-by参数指定分隔符,参考下面的例子


sqoop export \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp_1 \
--export-dir /sqoop/mysql-hdfs/emp \
--input-fields-terminated-by '\t' \
-m 1
案例2)代有主键字段的表,字段数少于hdfs上列数
sqoop export \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp_2 \
--export-dir /sqoop/mysql-hdfs/emp \
--input-fields-terminated-by '\t' \
-m 1
案例3)代有主键字段的表,字段数多于hdfs上列数
sqoop export \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp_3 \
--export-dir /sqoop/mysql-hdfs/emp \
--input-fields-terminated-by '\t' \
-m 1
案例4)导出到无主键约束的表中
sqoop export \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp_4 \
--export-dir /sqoop/mysql-hdfs/emp \
--input-fields-terminated-by '\t' \
-m 1
案例5)测试类型没有对应上
DROP TABLE IF EXISTS `emp_5`;
CREATE TABLE `emp_5` (
`EMPNO` int(4) NOT NULL,
`ENAME` varchar(10),
`JOB` varchar(9),
`MGR` int(4),
`SAL` int(7),
`COMM` int(7),
`DEPTNO` int(2)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

sqoop export \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp_5 \
--export-dir /sqoop/mysql-hdfs/emp \
--input-fields-terminated-by '\t' \
-m 1

结论:

1. 导出时,mysql中的表必须提前创建。
2. 导出时,字段之间的切分符号默认是逗号。如果hdfs上的文件不是逗号分隔符,需要使用--fields-terminated-by或--input-fields-terminated-by参数指定分隔符
3. 导出时,是按照hdfs上文件从左到右的顺序给mysql表的字段赋值
4. 导出时,mysql的表的字段数与hdfs上的列数可以不相同
5. 导出时,字段类型要一致
6. 带有主键约束的mysql表,要注意导出的数据的主键约束的情况,不能重复 
7. 使用--columns给mysql中的某些字段赋值时,没有包含在参数中的字段要么有默认值,要么不能设置not null
8. 在sqoop1.4.7中,hdfs上的字符串'null'是可以转成mysql中字符串类型字段的null值,
			      也可以转成mysql中非字符串类型字段的null值。
案例6)使用参数–columns
DROP TABLE IF EXISTS `emp_6`;
CREATE TABLE `emp_6` (
empno int(4),
ename varchar(10),
job varchar(9),
mgr int(4),
hiredate VARCHAR(20),
sal int(7),
comm int(7),
deptno int(2)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

sqoop export \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--columns "ename,job,hiredate" \
--table emp_6 \
--export-dir /sqoop/mysql-hdfs/emp \
--input-fields-terminated-by '\t' \
-m 1
案例7)测试hdfs上的字符串’null’是可以转成mysql中字符串类型字段的null值,或者是非字符串类型的null值
sqoop export \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp_6 \
--export-dir /sqoop/mysql-hdfs/emp \
--input-fields-terminated-by '\t' \
-m 1
案例8)input-null-string和input-null-non-string参数的用法
上述参数的功能:将hdfs上的值在mysql中设置为null。

sqoop export \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp_6 \
--export-dir /sqoop/mysql-hdfs/emp \
--input-fields-terminated-by '\t' \
--input-null-string '\\N' \
--input-null-non-string '-1' \
-m 1


sqoop export \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp_6 \
--export-dir /sqoop/mysql-hdfs/emp \
--input-fields-terminated-by '\t' \
--input-null-string 'KING' \
--input-null-non-string '10' \    
-m 1

5.3 mysql<==>hive

5.3.1 mysql–>hive

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0cnYqlUM-1615385990999)(ClassNotes.assets/image-20201028154521677.png)]

案例1)导入hive中
sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp \
--hive-import \
--hive-table 'emp1'

注意:如果报以下错误,说明sqoop的lib下缺少hive的common包

Import failed: java.io.IOException: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf
案例2)测试–hive-overwrite
sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp \
--hive-import \
--hive-overwrite \
--hive-table 'emp1' \
-m 1

结论:

1. 添加--hive-overwrite会覆盖原有的hive的表数据,反之没有此参数,表示追加数据。
2. 必须要有--hive-import选项。
3. 从mysql中导入到hive中时,如果不指定分隔符,默认使用的是^A,可以使用fields-terminated-by指定分隔符
案例3):指定分隔符
sqoop import \
--connect jdbc:mysql://mei01:3306/sz2003 \
--username root \
--password 123456 \
--table emp \
--hive-overwrite \
--hive-table 'emp11' \
--fields-terminated-by '\001' \
-m 1
案例4)使用分区字段参数导入到hive中
sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password 123456 \
--table emp \
--hive-import \
--hive-overwrite \
--hive-table 'emp2' \
--fields-terminated-by ',' \
--hive-partition-key 'dt' \
--hive-partition-value "2020-10-28" \
-m 1

5.3.2 hive–>mysql

hive到mysql的本质其实就是hdfs到mysql
-- 先在mysql中创建表结构
DROP TABLE IF EXISTS `emp_7`;
CREATE TABLE `emp_7` (
empno int(4),
ename varchar(10),
job varchar(9),
mgr int(4),
hiredate VARCHAR(20),
sal int(7),
comm int(7),
deptno int(2)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 将hive表emp2对应的目录下的数据导出到mysql的表中

sqoop export \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp_7 \
--export-dir /user/hive/warehouse/emp2/dt=2020-10-28 \
--fields-terminated-by ',' \
-m 1
sqoop import \
--connect jdbc:mysql://localhost:3306/my2003 \
--username mei \
--password 123456 \
--table user \
--hive-import \
--hive-overwrite \
--hive-table 't1.emp' \
--fields-terminated-by '\t' \
--hive-partition-key 'dt' \
--hive-partition-value '2020-12-12' \
-m 1

sqoop export \
--connect jdbc:mysql://localhost:3306/my2003 \
--username mei \
--password 123456 \
--table user \
--export-dir /user/emp/dt=2020-12-12 \
--fields-terminated-by '\t' \
-m 1

5.4 mysql==>hbase

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BltKdrij-1615385991000)(ClassNotes.assets/image-20201028164454118.png)]

案例1)

sqoop import \
--connect jdbc:mysql://mei01:3306/sz2003 \
--username root \
--password 123456 \
--table emp \
--column-family 'f1' \
--hbase-create-table \
--hbase-table 'myemp' \
--hbase-row-key 'EMPNO' \
-m 1


sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--query 'select ename,job from emp where $CONDITIONS and deptno=10' \
--column-family 'f1' \
--hbase-create-table \
--hbase-table 'myemp' \
--hbase-row-key 'empno' \
-m 1


sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table 'emp' \
--column-family 'f1' \
--hbase-create-table \
--hbase-table 'myemp' \
-m 1

结论:

注意:在导入到hbase中时:
--1. rowkey大小写问题
	如果是--table [--where]  那么hbase-row-key的字段名必须大写
	如果是--query并且指定了主键字段, hbase-row-key的字段名必须和query中的大小写一致,否则也要是大写的
--2. rowkey的指定问题
    --hbase-row-key,参数可以忽略,忽略情况下,主动将mysql中的主键作为rowkey,不指定时,必须使用--table,也可以指定出来
    -- 如果mysql中的主键是复合键,那么此属性必须指定,并且使用逗号分隔
    -- 如果mysql中没有主键约束,那么应该指定--hbase-row-key

六 sqoop的高阶用法

6.1 增量导入

6.1.1 应用场景

在实际生产环境中,业务数据在导入到数仓里时,通常使用增量导入的方式。这样可以避免有些数据重复导入的操作。
1. 经常需要导入的RDBMS表,建议使用增量导入
2. RDBMS表数据量特别大,但是变化小,建议使用增量导入

6.1.2 增量导入的方式

1. 可以使用--query参数,在select语句中进行条件限制来导入数据,缺点是条件需要人为的设置
2. 可以使用--incremental,进行增量导入,通常这个参数要配合--check-column和--last-value一起使用

6.1.3 案例演示

1)演示query的增量导入

昨天导入的数据如下:
sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--driver 'com.mysql.jdbc.Driver' \
--username root \
--password @Mm123123 \
--query 'select * from emp where deptno in(10,20) and $CONDITIONS' \
--target-dir /tmp111 \
--hive-import \
--hive-table 'sz2003.emp101' \
--fields-terminated-by '\t' \
--null-string '\\N' \
--null-non-string '0' \
-m 1


注意事项: 向hive中导入数据时,使用--table时,会临时存储到/user/root/mysql-tableName目录下,然后再load到hive的表中
如果使用的是--query,必须使用--target-dir指定临时目录

今天导入新增加的30号部门的数据
sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--driver 'com.mysql.jdbc.Driver' \
--username root \
--password @Mm123123 \
--query 'select * from emp where deptno =30 and $CONDITIONS' \
--target-dir /tmp111 \
--hive-import \
--hive-table 'sz2003.emp101' \
--fields-terminated-by '\t' \
--null-string '\\N' \
--null-non-string '0' \
-m 1

2)测试–append参数

sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--driver 'com.mysql.jdbc.Driver' \
--username root \
--password @Mm123123 \
--append \
--query 'select * from emp where deptno =30 and $CONDITIONS' \
--target-dir /sqoop/hdfs-emp/ \
--fields-terminated-by '\t' \
--null-string '\\N' \
--null-non-string '0' \
-m 1

注意:可以使用--append参数向hdfs上追加数据,如果不指定此参数,会报目录已经存在。

3)测试incremental

1)提前准备一些数据
sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--driver 'com.mysql.jdbc.Driver' \
--username root \
--password @Mm123123 \
--query 'select * from emp where empno<7400 and $CONDITIONS' \
--target-dir /sqoop/hdfs-emp/ \
--delete-target-dir \
--fields-terminated-by '\t' \
--null-string '\\N' \
--null-non-string '0' \
-m 1

2) 增量导入

sqoop import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--driver 'com.mysql.jdbc.Driver' \
--username root \
--password @Mm123123 \
--incremental append \
--check-column 'empno' \
--last-value '7800' \
--query 'select * from emp where $CONDITIONS' \
--target-dir /sqoop/hdfs-emp/ \
--fields-terminated-by '\t' \
--null-string '\\N' \
--null-non-string '0' \
-m 1

注意:增量导入时,不要由--delete-target-dir参数

--last-value: 从指定的值开始检查,如果有大于此值的数据,就认为是新数据,才会增量导入。导入后,会记录这次导入的最大值,为下一次增量导入做提示。
--check-column: 检查指定列,是否有新值,那么从意义上来说,指定的列应该具有唯一,非空,自增的特点。

注意:如果last-value的值由人来维护,那么很可能出现重复数据,人指定的值可能会出错,所以应该使用一种机制来自动维护last-value的值。

6.2 job的应用

6.2.1 job应用的优点

1. 可以将导入导出语句创建到job里,然后可以重复的执行job。避免重写一堆参数,也可以使用定时器来定时执行job
2. 如果job里封装了增量导入语句,因为job里自动维护了一堆参数,包括--last-value,因此执行job后,job会记录last-value的最新的值,以便下次导入新的行数据。

6.2.2 job的指令

[root@qianfeng01 ~]# sqoop job --help

usage: sqoop job [GENERIC-ARGS] [JOB-ARGS] [-- [<tool-name>] [TOOL-ARGS]]
Job management arguments:
   --create <job-id>            Create a new saved job
   --delete <job-id>            Delete a saved job
   --exec <job-id>              Run a saved job
   --help                       Print usage instructions
   --list                       List saved jobs
   --meta-connect <jdbc-uri>    Specify JDBC connect string for the
                                metastore
   --show <job-id>              Show the parameters for a saved job
   --verbose                    Print more information while working

6.2.3 案例演示1

1)创建一个job,相当于将导入语句封装到job里。想要执行导入功能,必须执行job

sqoop job --create job1 \
-- import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp \
--target-dir "/0911/job" \
--delete-target-dir \
-m 1


注意:创建job时,一定要添加import参数,要与前面的--之间有一个空格
如果报以下
ERROR sqoop.Sqoop: Got exception running Sqoop: java.lang.NullPointerException
java.lang.NullPointerException
        at org.json.JSONObject.<init>(JSONObject.java:144)
需要将java-json.jar包导入到sqoop的lib目录下

2)查询所有的job

[root@qianfeng01 ~]# sqoop job --list

3)执行job

[root@qianfeng01 ~]# sqoop job --exec job1

4)写一个定时脚本执行,规定中午12点整和半夜12整执行

[root@qianfeng01 ~]# crontab -e
0 12,0 * * * /usr/local/sqoop/bin/sqoop job --exec job1

6.2.4 案例演示2

1)创建一个带有增量导入的job

sqoop job --create job2 \
-- import \
--connect jdbc:mysql://mei03:3306/sz2003 \
--username root \
--password @Mm123123 \
--table emp \
--incremental append \
--check-column 'empno' \
--last-value '0' \
--target-dir "/incremental/job" \
--fields-terminated-by ',' \
-m 1
  1. 查看指定job
[root@qianfeng01 ~]# sqoop job --show job2

可以看到job的元数据,包括各种参数,如last-value的值

3)执行job

[root@qianfeng01 ~]# sqoop job --exec job2

执行完后,会看到last-value变成了7934.

4)在mysql的emp表中插入以下三条记录

insert into emp (empno,ename,job,deptno) values (7933,'zhangsan','clerk',10);
insert into emp (empno,ename,job,deptno) values (7935,'lisi','clerk',10);
insert into emp (empno,ename,job,deptno) values (7936,'wangwu','clerk',10);

5)再次执行job2

[root@qianfeng01 ~]# sqoop job --exec job2

执行后,会看到之导入了大于7934的两条记录。last-value变成了7936

6.3 metastore的应用

6.3.1 metastore的介绍

1. metastore服务是sqoop的元数据服务,用于存储sqoop的job相关信息
2. 默认会使用内嵌的元数据库,存储位置位于~/.sqoop/下
3. 由于安全性问题,将job信息保存于关系型数据库中是最合适的,关系型数据库可以选择mysql

6.3.2 配置metastore服务项

步骤1)修改用户自定义配置文件

[root@qianfeng01 conf]# vim sqoop-site.xml
<configuration>
    <property>
        <name>sqoop.metastore.client.enable.autoconnect</name>
        <value>true</value>
    </property>
    <property>
        <name>sqoop.metastore.client.autoconnect.url</name>
        <value>jdbc:mysql://mei03:3306/sqoop</value>
    </property>
    <property>
        <name>sqoop.metastore.client.autoconnect.username</name>
        <value>root</value>
    </property>
    <property>
        <name>sqoop.metastore.client.autoconnect.password</name>
        <value>@Mm123123</value>
    </property>
    <property>
        <name>sqoop.metastore.client.record.password</name>
        <value>true</value>
    </property>
    <property>
        <name>sqoop.metastore.server.location</name>
        <value>/usr/local/sqoop/sqoop-metastore/shared.db</value>
    </property>
    <property>
        <name>sqoop.metastore.server.port</name>
        <value>16000</value>
    </property>
</configuration>    

步骤2)在mysql中创建sqoop数据库

mysql> create database sqoop

步骤3)启动sqoop的服务项

[root@qianfeng01 ~]# sqoop metastore
或者后台启动
[root@qianfeng01 ~]# sqoop metastore &

步骤4)在sqoop库中要维护一张表SQOOP_ROOT

##方式1:可以使用sqoop的某一个语句进行连接,这样就可以创建此表

执行如下语句即可
sqoop job --list --meta-connect 'jdbc:mysql://mei03:3306/sqoop?user=root&password=@Mm123123'

执行后,SQOOP_ROOT表创建成功



##方式2)手动维护此表
CREATE TABLE `SQOOP_ROOT` (
  `version` int(11) DEFAULT NULL,
  `propname` varchar(128) NOT NULL,
  `propval` varchar(256) DEFAULT NULL,
  UNIQUE KEY `SQOOP_ROOT_unq` (`version`,`propname`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

步骤5)需要向SQOOP_ROOT中添加一条记录

insert into SQOOP_ROOT values (NULL, 'sqoop.hsqldb.job.storage.version', '0');

步骤6)修改两张表的存储引擎为myisam(innoDB引擎会引起事务锁超时情况)

alter table SQOOP_ROOT engine=myisam;
alter table SQOOP_SESSIONS engine=myisam;

6.3.3 案例演示1

1)创建一个job

sqoop job --create job1 \
--meta-connect 'jdbc:mysql://mei01:3306/sqoop?user=root&password=123456' \
-- import \
--connect "jdbc:mysql://mei01:3306/sz2003" \
--username root \
--password @Mm123123 \
--table emp \
--target-dir /1029/emp \
--append \
--fields-terminated-by ',' \
-m 1

2)查询metastore里保存的job

sqoop job --list \
--meta-connect 'jdbc:mysql://mei03:3306/sqoop?user=root&password=@Mm123123' 

注意:由于sqoop-site.xml里的自动连接属性为true,所以可以不添加--meta-connect参数

3)执行metastore里保存的job

sqoop job --exec job3

6.3.4 案例演示2

1)创建增量导入的job

sqoop job --create job2 \
--meta-connect 'jdbc:mysql://mei01:3306/sqoop?user=root&password=123456' \
-- import \
--connect "jdbc:mysql://mei01:3306/sz2003" \
--username root \
--password @Mm123123 \
--table emp \
--incremental append \
--check-column empno \
--target-dir /1029/incremental/ \
--fields-terminated-by ',' \
-m 1


注意:第一次创建增量job时,last-value参数可以不指定,默认导入全表的数据,然后会自动维护last-value的值

2)执行

sqoop job --exec job4


注意:想要使用metastore保存增量导入的job,那么SQOOP_SESSIONS的存储引擎必须是myisam。否则在执行job,想要保存last-value时,会失败

3)在mysql的emp表中插入两条新数据

insert into emp (empno,ename,job,deptno) values (7937,'lisi','clerk',10);
insert into emp (empno,ename,job,deptno) values (7938,'wangwu','clerk',10);

4)再次执行job4

sqoop job --exec job4

6.4 sqoop的优化

-1. mapTask的数量不能超过yarn的Vcore的数目,默认情况下yarn的VCORE的数量是8
-2. 如果数据量比较小,在200M以内,建议使用一个MapTask
-3. split-by指定的字段最好是均分分布的数字类型或者是时间类型。
-4. --fetch-size的数目的数据总大小最好在128M以内。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值