Apache Sqoop正确使用方式
Summary(提炼):
在玩Sqoop时候最重要的是搞清楚到底是数据导入还是导出,抓不住这点你就是迷迷糊糊的(不是我)
import == 是mysql导入数据到Hive,HDFS,HBase
export == 刚好相反
对于Sqoop我的建议是记住一两个常用的数据导入方式(通过HCatlog将数据从mysql导入到Hive)
Linux中手动进入Hive二代客户端的命令:
beeline
!connect jdbc:hive2://hadoop01:10000 (注意!和connect中间可以没有空格)
Tips:Swoop是在Linux中直接执行的
数据导入
数据导入-MySQL到HDFS
指定分隔符
将数据从MySQL的userdb数据库的表tmp导出数据到HDFS上,
并指定存储位置为/sqoop/result2以及分割符为\t
1 | sqoop import \ |
–target-dir 表示目标目录的路径, 即: 导入到的HDFS的路径(子目录必须不存在, 会自动创建).
–table 表示数据源表, 即: MySQL的表名
–m MapReduce的任务数, 1表示1个分区, 即: 最终结果在1个文件中.
指定任务并行度(maptask个数)
注意:指定任务并行度时,指定几个MapTask则最终会得到几个文件,且需要有主键,如果没有主键需要手动指定分割列。
1 | sqoop import \ |
上述的命令最后是 –m 2, 即两个MapReduce, 最终结果会到2个文件中, 但是因为上述表 没有主键(特点: 唯一, 非空),
且如果我们没有自己手动指定 分割列, 则上述的代码会报错. 加入 –split-by 切割字段即可, 具体如下:建议切割字段最好是id列, 或者是数字列.
数据导入-Mysql 到Hive
这也是以后会用的比较多的点
先在hive中创建test数据库。
用Sqoop在hive中建表
1 | sqoop create-hive-table \ |
注意这种方式建表,只是创建表的结构,具体数据并没有在hive中插入。
往数据表中导入数据
1 | sqoop import \ |
上述两种方法可以合并为一句话:(哈哈有点坑爹,都这时候了早点说不行吗?)
1 | sqoop import \ |
全量导入
Mysql到Hive之全量导入
※
在hive中建表(存储格式为ORC),注意中间不要有换行,一整行敲完。
1 | createtable test.emp_hive( |
将数据导入到Hive中
※
这种方式导入不会成功,(因为Hive表示orc存储格式,使用原生的API虽然成功但是hive中没有数据)
1 | sqoop import \ |
使用HCatlogAPI导入到HIVE中※
1 | sqoop import \ |
Sqoop条件导入数据※
where方式
主要过滤的是行
1 | sqoop import \ |
query方式, 主要过滤的是行和列方式比较灵活
要注意以下几点:
因为有SQL语句了, 所以不能写 —table
query后边的SQL语句要用单引号包裹, 不能是双引号.
query后边的SQL语句必须跟 where 查询条件.
哪怕是写个where 1=1 也行,这是相当于不过滤query后边的SQL语句的最后必须跟上 $CONDITIONS 表示SQL语句结束.
1 | sqoop import \ |
Sqoop原生API 和HCatalog之间的区别是什么?
1.数据格式支持
//这是实际中使用HCatalog的主要原因,否则还是原生的灵活一些.
Sqoop方式支持的数据格式较少;
HCatalog支持的数据格式多,包括RCFile, ORCFile, CSV, JSON和SequenceFile等格式。
2.数据覆盖
Sqoop方式允许数据覆盖,HCatalog不允许数据覆盖,每次都只是追加。
3.字段名匹配
Sqoop方式比较随意,不要求源表和目标表字段相同(字段名称和个数都可以不相同),它抽取的方式是将字段按顺序插入,
比如: 目标表有3个字段,源表有一个字段,它会将数据插入到Hive表的第一个字段,其余字段为NULL。
但是HCatalog不同,源表和目标表字段名需要相同,字段个数可以不相等,如果字段名不同,抽取数据的时候会报
NullPointerException错误。HCatalog抽取数据时,会将字段对应到相同字段名的字段上,哪怕字段个数不相等。
总结:
HCatalog方式较之于Hive原生API, 优点是: 支持的数据格式更多一些, 例如: CSV, Orc, Json, SequenceFile等.
缺点是: 没有Hive原生API灵活, 例如: 它支持追加, 不支持覆盖, 且导入时要求 目标表字段名 和 原表字段名要一致.
增量导入
可以是导入到Hive数据表中,也可以导入到HDFS文件系统中。
关于增量导入的3个核心参数:
–check-column: //以哪一列的值作为增量的基准
–last-value: //指定上一次这一列的值是什么
–incremental: //指定增量的方式
Append模式
Append模式:
要求:必须有一列自增的值,按照 自增的int值 进行判断
特点:只能导入增加的数据,无法导入更新的数据
先全量导入表的数据
1 | sqoop import \ |
向MySQL数据表中添加数据
1 | insert into `userdb`.`emp` (`id`, `name`, `deg`, `salary`, `dept`) values ('1206', 'allen', 'admin', '30000', 'tp'); |
修改MySQL数据表中的数据
1 | update emp set name='liuyifei', salary=80000 where id = 1201; |
增量导入, 看是否会导入新增数据, 更新数据
1 | sqoop import \ |
结论:Append模式只会导入增量数据,并不会导入更新数据
Lastmodified模式
不仅会导入新增数据, 还会导入修改数据,该模式要求,必须有一个动态修改的时间戳.
时间戳是createtime和updatetime,这也是后端程序员设计数据库时要考虑的两个字段。
要求:
必须包含动态时间变化这一列,按照数据变化的时间进行判断.
特点:既导入新增的数据, 也导入更新的数据
创建数据表
在MySQL的userdb数据库中,创建数据表,该表有动态时间戳这一列, 用于记录该列值 添加或者修改的时间
1 | create table customertest( |
添加数据
具体的添加数据的动作, 建议:不要批量执行,而是逐条执行, 因为MySQL的效率很高, 你要是批量执行了, 可能他们修改时间都一样
1 | insert into customertest(id,name) values(1,'neil'); |
全量导入表的数据
1 | sqoop import \ |
往MySQL中插入数据
在MySQL中, 往 userdb数据库的 customertest 表中 新增1条数据.
1 | insert into customertest(id,name) values(6,'james'); |
在MySQL中修改数据
在MySQL中, 往 userdb数据库的 customertest 表中 修改1条数据.
1 | update customertest set name = 'LiuYiFei' where id = 1; |
增量导入
采用lastmodified模式, 增量导入, 看是否会导入 新增数据, 更新数据.
1 | sqoop import \ |
- merge-key这种模式是进行了一次完整的mapreduce操作,即: id一样的数据, 是同一条数据. 重复会覆盖,不重复会新增.
- 因此最终我们在lastmodifiedresult文件夹下可以发现id=1的name已经得到修改,同时新增了id=6的数据
结论:Append模式会导入增量数据,而且会导入更新数据
全量导出
将数据从Hadoop生态体系导出到RDBMS数据库导出前,目标表必须存在于目标数据库中。
导出数据-HDFS到MySQL
Sqoop导出数据的最大的特点是, (MySQL的)表需要我们手动创建
在mysql中创建数据库
1 | create table employee ( |
导出数据
从 HDFS的 /sqoop/result1 中 导出数据到 MySQL的 employee表中
1 | sqoop export \ |
导出数据-Hive到MySQL
清空MySQL的 userdb数据库的 employee表的数据
1 | truncate table employee; |
数据全量导出
1 | sqoop export \ |
注意,如果Hive中的表底层是使用ORC格式存储的,那么必须使用hcatalog API进行操作。
UpdateOnly增量导出
增量导出两种模式解释:
updateonly: //只增量导出更新(修改)的数据
allowinsert: //既导出更新的数据,也导出新增的数据
– update-key,更新标识,即根据某个字段进行更新,例如id,可以指定多个更新标识的字段,多个字段之间用逗号分隔。
– updatemod,指定updateonly(默认模式),仅仅更新已存在的数据记录,不会插入新纪录。
在HDFS中创建文件准备导出
在HDFS文件系统中/sqoop/updateonly/目录的下创建一个文件updateonly_1.txt
1 | hadoop fs -mkdir -p /sqoop/updateonly/ |
通过Hue修改txt文件
1 | 1201,gopal,manager,50000 |
创建MySQL数据库
1 | CREATE TABLE updateonly ( |
全量导出
1 | sqoop export \ |
将updateonly_1.txt删除新建文件updateonly_2.txt
1 | 1201,gopal,manager,1212 |
增量导出
1 | sqoop export \ |
– update-key,更新标识,即根据某个字段进行更新,例如id,可以指定多个更新标识的字段,多个字段之间用逗号分隔。
– updatemod,指定updateonly(默认模式),仅仅更新已存在的数据记录,不会插入新纪录。
AllowInsert增量导出
– update-key,更新标识,即根据某个字段进行更新,例如id,可以指定多个更新标识的字段,多个字段之间用逗号分隔。
– updatemod,指定allowinsert,更新已存在的数据记录,同时插入新纪录。实质上是一个insert & update的操作。
- 在MySQL中创建表, 用于存储 导出的数据.
1 | CREATE TABLE allowinsert ( |
- 先全量导入上述的数据, 即: /sqoop/updateonly/updateonly_1.txt
1 | sqoop export \ |
- 增量导出 HDFS的 /sqoop/updateonly/updateonly_2.txt文件数据到 MySQL的 updateonly表中.
1 | sqoop export \ |