Sqoop的基本操作

sqoop help

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

导入

1.全量导入mysql表数据到HDFS

bin/sqoop import \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--delete-target-dir \
--target-dir /sqoopresult \
--table emp --m 1

其中:
\:为linux系统中的换行符
bin/sqoop import:导入数据的固定写法
选项:
--connect:目标数据库地址
--username:访问数据库的用户名
--password:用户名密码
--delete-target-dir:当目标目录存在时删除
--target-dir:目标目录
--table:为mysql中的表
--m:maptask数量

2.全表导入mysql表数据到HIVE

方式1:先复制表结构到hive中再导入数据

将关系型数据库的表结构复制到hive中:

bin/sqoop create-hive-table \
--connect jdbc:mysql://node01:3306/test \
--table emp_add \
--username root \
--password 123456 \
--hive-table test.emp_add_sp
其中:
 --table:指定mysql中的表  
 --hive-table:指定在hive中新建的表名

从关系数据库导入文件到hive中

bin/sqoop import \
--connect jdbc:mysql://node02:3306/test \
--username root \
--password 123456 \
--table emp \
--hive-table myhive.hive_emp \
--hive-import \
--m 1

其中:
--hive-table:指定hive目标表
--hive-import:将表导入Hive中

方式2:直接复制表结构数据到hive中

导入机制:将数据导入到临时目录下并建表,再将数据移动到表对应的数据目录下

bin/sqoop import \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--table emp \
--hive-import \
--m 1 \
--hive-database myhive;
 
 其中:
 --hive-database:目标数据库

3.导入表数据子集

bin/sqoop import \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--where "city ='sec-bad'" \
--target-dir /wherequery \
--table emp_add --m 1

其中:
--where:可以指定从关系数据库导入数据时的查询条件,它执行在数据库服务器相应的SQL查询,并将结果存储在HDFS的目标目录。
city ='sec-bad':查询字段为city,字段值为sec—bad的数据

4.导入表数据子集(query查询)

bin/sqoop import \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--target-dir /wherequery2 \
--query 'select id,name,deg from emp WHERE  id>1203 and $CONDITIONS' \
--split-by id \
--fields-terminated-by '\t' \
--m 2

其中w:
1.使用query sql语句来进行查找不能加参数--table;
2.并且必须要添加where条件;
3.并且where条件后面要加and $CONDITIONS;
4.并且这个sql语句必须用单引号,不能用双引号;
5.sqoop命令中,--split-by id通常配合-m 10参数使用。用于指定根据哪个字段进行划分并启动多少个maptask。

5.增量导入

在实际工作当中,数据的导入,很多时候都是只需要导入增量数据即可,并不需要将表中的数据每次都全部导入到hive或者hdfs当中去,这样会造成数据重复的问题。因此一般都是选用一些字段进行增量的导入, sqoop支持增量的导入数据。

增量导入是仅导入新添加的表中的行的技术。

其中:
–check-column (col):
用来指定一些列,这些列在增量导入时用来检查这些数据是否作为增量数据进行导入,和关系型数据库中的自增字段及时间戳类似。
注:注意:这些被指定的列的类型不能使任意字符类型,如char、varchar等类型都是不可以的,同时-- check-column可以去指定多个列。

–incremental (mode):
append:追加,比如对大于last-value指定的值之后的记录进行追加导入。
lastmodified:最后的修改时间,追加last-value指定的日期之后的记录

–last-value (value):
指定自从上次导入后列的最大值(大于该指定的值),也可以自己设定某一值

a.Append模式增量导入

执行以下指令先将我们之前的数据导入:

bin/sqoop import \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--target-dir /appendresult \
--table emp --m 1

使用hadoop fs -cat查看生成的数据文件,发现数据已经导入到hdfs中。
然后在mysql的emp中插入2条增量数据:

insert into `emp` (`id`, `name`, `deg`, `salary`, `dept`) values ('1206', 'allen', 'admin', '30000', 'tp');
insert into `emp` (`id`, `name`, `deg`, `salary`, `dept`) values ('1207', 'woon', 'admin', '40000', 'tp');

执行如下的指令,实现增量的导入:

bin/sqoop import \
--connect jdbc:mysql://node01:3306/test \
--username root  --password 123456 \
--table emp --m 1 \
--target-dir /appendresult \
--incremental append \
--check-column id \
--last-value  1205

其中:
--incremental append \
--check-column id \
--last-value  1205
三者同时使用:指定id=1205为指标,将id大于1205的行数据导入到/appendresult目录中

在这里插入图片描述

b.Lastmodified模式增量导入

首先创建一个customer表,指定一个时间戳字段:

create table customertest(id int,name varchar(20),last_mod timestamp default current_timestamp on update current_timestamp);

注:此处的时间戳设置为在数据的产生和更新时都会发生改变

分别插入如下记录:

insert into customertest(id,name) values(1,'neil');
insert into customertest(id,name) values(2,'jack');
insert into customertest(id,name) values(3,'martin');
insert into customertest(id,name) values(4,'tony');
insert into customertest(id,name) values(5,'eric');

执行sqoop指令将数据全部导入hdfs:

bin/sqoop import \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--target-dir /lastmodifiedresult \
--table customertest --m 1
bin/sqoop import \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--table customertest \
--target-dir /lastmodifiedresult \
--check-column last_mod \
--incremental lastmodified \
--last-value "2019-05-28 18:42:06" \
--m 1 \
--append

注:lastmodified模式去处理增量时,会将大于等于last-value值的数据当做增量插入。

c.Lastmodified模式:append、merge-key

使用lastmodified模式进行增量处理要指定增量数据是以append模式(附加)还是merge-key(合并)模式添加

下面演示使用merge-by的模式进行增量更新,我们去更新 id为1的name字段:

update customertest set name = 'Neil' where id = 1;

更新之后,这条数据的时间戳会更新为更新数据时的系统时间.
执行如下指令,把id字段作为merge-key:

bin/sqoop import \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--table customertest \
--target-dir /lastmodifiedresult \
--check-column last_mod \
--incremental lastmodified \
--last-value "2019-05-28 18:42:06" \
--m 1 \
--merge-key id

由于merge-key模式是进行了一次完整的mapreduce操作,
因此最终我们在lastmodifiedresult文件夹下可以看到生成的为part-r-00000这样的文件,会发现id=1的name已经得到修改,同时新增了id=6的数据。

导出

1.默认模式导出HDFS数据到mysql

默认情况下,sqoop export将每行输入记录转换成一条INSERT语句,添加到目标数据库表中。如果数据库中的表具有约束条件(例如,其值必须唯一的主键列)并且已有数据存在,则必须注意避免插入违反这些约束条件的记录。如果INSERT语句失败,导出过程将失败。此模式主要用于将记录导出到可以接收这些结果的空表中。通常用于全表数据导出。

导出时可以是将Hive表中的全部记录或者HDFS数据(可以是全部字段也可以部分字段)导出到Mysql目标表。

a. 在HDFS文件系统中“/emp/”目录的下创建一个文件emp_data.txt:

1201,gopal,manager,50000,TP
1202,manisha,preader,50000,TP
1203,kalil,php dev,30000,AC
1204,prasanth,php dev,30000,AC
1205,kranthi,admin,20000,TP
1206,satishp,grpdes,20000,GR

b.手动创建mysql中的目标表

CREATE TABLE employee (
   id INT NOT NULL PRIMARY KEY,
   name VARCHAR(20), 
   deg VARCHAR(20),
   salary INT,
   dept VARCHAR(10));

c.执行导出命令

bin/sqoop export \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--table employee \
--export-dir /emp/emp_data

注:
--export-dir:导出文本数据的目录

2.更新导出(updateonly)

a.准备HDFS数据

在HDFS “/updateonly_1/”目录的下创建一个文件updateonly_1.txt:
1201,gopal,manager,50000
1202,manisha,preader,50000
1203,kalil,php dev,30000

b.手动创建mysql中的目标表

USE test;
CREATE TABLE updateonly ( 
   id INT NOT NULL PRIMARY KEY, 
   name VARCHAR(20), 
   deg VARCHAR(20),
   salary INT);

c.先执行全部导出操作

bin/sqoop export \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--table updateonly \
--export-dir /updateonly_1/

d.查看此时mysql中的数据
在这里插入图片描述
e.新增一个文件

updateonly_2.txt。修改了前三条数据并且新增了一条记录。上传至/updateonly_2/目录下:
1201,gopal,manager,1212
1202,manisha,preader,1313
1203,kalil,php dev,1414
1204,allen,java,1515

f.执行更新导出

bin/sqoop export \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--table updateonly \
--export-dir /updateonly_2/ \
--update-key id \
--update-mode updateonly

注:
-- update-key:更新标识,即根据某个字段进行更新,例如id,可以指定多个更新标识的字段,多个字段之间用逗号分隔。
--update-mode:指定updateonly(默认模式),仅仅更新已存在的数据记录,不会插入新纪录。

g.查看最终结果
在这里插入图片描述

3.更新导出(allowinsert模式)

a.准备HDFS数据

在HDFS “/allowinsert_1/”目录的下创建一个文件allowinsert_1.txt:
1201,gopal,manager,50000
1202,manisha,preader,50000
1203,kalil,php dev,30000

b.手动创建mysql中的目标表

USE userdb;
 CREATE TABLE allowinsert ( 
   id INT NOT NULL PRIMARY KEY, 
   name VARCHAR(20), 
   deg VARCHAR(20),
   salary INT);

c.先执行全部导出操作

bin/sqoop export \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--table allowinsert \
--export-dir /allowinsert_1/

d.查看此时mysql中的数据
在这里插入图片描述
e.新增一个文件

allowinsert_2.txt。修改了前三条数据并且新增了一条记录。上传至/ allowinsert_2/目录下:
1201,gopal,manager,1212
1202,manisha,preader,1313
1203,kalil,php dev,1414
1204,allen,java,1515

f.执行更新导出

bin/sqoop export \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password 123456 \
--table allowinsert \
--export-dir /allowinsert_2/ \
--update-key id \
--update-mode allowinsert

-- update-key:更新标识,即根据某个字段进行更新,例如id,可以指定多个更新标识的字段,多个字段之间用逗号分隔。

-- updatemod:指定allowinsert,更新已存在的数据记录,同时插入新纪录。实质上是一个insert & update的操作。

g.查看最终结果
在这里插入图片描述

Sqoop job作业

1.创建job

创建一个名为czxyjob的作业,该作业可以从RDBMS表的数据导入到HDFS:

bin/sqoop job \
--create czxyjob \
-- import \
--connect jdbc:mysql://node02:3306/test \
--username root \
--password 123456 \
--target-dir /sqoopresult333 \
--table emp \
--m 1

2.验证job

–list 参数是用来验证保存的作业。
下面的命令用来验证保存Sqoop作业的列表:

bin/sqoop job --list

3.检查job

–show 参数用于检查或验证特定的工作,及其详细信息。
以下命令和样本输出用来验证一个名为czxyjob的作业:

bin/sqoop job --show czxyjob

4.执行job

–exec 参数选项用于执行保存的作业。
下面的命令用于执行保存的作业称为czxyjob:

bin/sqoop job --exec czxyjob

5.免密执行job

sqoop在创建job时,使用–password-file参数,可以避免输入mysql密码,如果使用–password将出现警告,并且每次都要手动输入密码才能执行job,sqoop规定密码文件必须存放在HDFS上,并且权限必须是400。
并且检查sqoop的sqoop-site.xml是否存在如下配置:

<property>
    <name>sqoop.metastore.client.record.password</name>
    <value>true</value>
    <description>If true, allow saved passwords in the metastore.
    </description>
</property>

1.将密码保存在绝对路径为/input/sqoop/pwd/czxymysql.pwd目录中并上传到HDFS中:

内容:
123456

2.创建job实现免密执行job

bin/sqoop job \
--create czxyjob1 \
-- import \
--connect jdbc:mysql://node01:3306/test \
--username root \
--password-file /input/sqoop/pwd/czxymysql.pwd \
--target-dir /sqoopresult333 \
--table emp \
--m 1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据老人家i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值