参考博客为下标题
1.Sqoop全量数据导入、增量数据导入、并发导入 (Sqoop进阶)
Sqoop支持两种方式的全量数据导入和增量数据导入,同时可以指定数据是否以并发形式导入。
可以进去看一下简介
1.全量数据导入就是一次性将所有需要导入的数据,从关系型数据库一次性地导入到Hadoop中(可以是HDFS、Hive等)。全量导入形式使用场景为一次性离线分析场景。
2.事实上,在生产环境中,系统可能会定期从与业务相关的关系型数据库向Hadoop导入数据,导入数仓后进行后续离线分析。故我们此时不可能再将所有数据重新导一遍,此时我们就需要增量数据导入这一模式了。
增量数据导入分两种,一是基于递增列的增量数据导入(Append方式)。二是基于时间列的增量数据导入(LastModified方式)。
先提炼一下下面的内容 具体的看下面的步骤
1.mysql建表 id name lastmodify(类型为datatime) 存入两条数据
2.使用sqoop的create-hive-table语句,在hive创建mysql表结构的表。
3.创建job 实现根据lastmodified增量导入 从mysql导入到hive
4.查看job信息 主要是 incremental.last.value = 2019/09/20 14:39:00.0 还没执行job 是我们指定的值
5.执行job
6.查询hive表结果
7.查看job信息 主要是 incremental.last.value = 2019-09-20 16:37:24.0
执行job后 incremental.last.value是执行完job的时间 不是数据中的表的数据的时间
8.手动增加mysql表数据 再次执行job
9.查看hive表结果
10.查看job信息 主要是 incremental.last.value = 2019-09-20 16:42:27.0 更新数据后第二次执行job 是执行完job的时间
11.考虑使用定时器contab执行job
下面我写一下Sqoop实现简单的增量导入数据之LastModified方式具体步骤。
核心参数
- –check-column
用来指定一些列,这些列在增量导入时用来检查这些数据是否作为增量数据进行导入,和关系型数据库中的自增字段及时间戳类似.
注意:这些被指定的列的类型不能使任意字符类型,如char、varchar等类型都是不可以的,同时–check-column可以去指定多个列 - –incremental
用来指定增量导入的模式,两种模式分别为Append和Lastmodified - –last-value
指定上一次导入中检查列指定字段最大值
1.mysql中准备数据
增量导入在企业当中,一般都是需要经常执行的,如隔一个星期就执行一次增量导入,故增量导入的方式需要多次执行,而每次执行时,又去写相应的执行命令的话,比较麻烦。而sqoop提供了一个很好的工具save job的方式。
测试的方式是通过–incremental来执行 lastmodified 模式, --check-column来设置 LASTMODIFIED检查的字段,意思就是当该字段发生更新或者添加操作,则才会执行导入。–last-value来设置初始值 ‘2019/09/20 14:39:00’,该值是用来作为第一次导入的下界,从第二次开始,sqoop会自动更新该值为上一次导入的上界。
(感觉第一次设置的值只要比数据库中的数据小就可以 第一次实现全部导入)
测试开始:sqoop创建一个job的方式来实现日常的增量导入,首先在关系型的数据库中mysql创建一个测试表testlast,添加两条数据:
id name lastmodified
1 shi 2019-09-20 14:43:27
2 shuai 2019-09-20 14:44:17
(1)创建sqoop job
sqoop job --create myfirstjob \
--import \
--connect jdbc:mysql://hadoop01:3306/test \
--username root --password root \
--driver com.mysql.jdbc.Driver \
--table testlast \
--hive-import \
--hive-table testlast \
--incremental lastmodified \
--check-column lastmodify \
--last-value '2019/09/20 14:39:00'
说明:
1)在上面的job当中,不能指定-m ,因为指定了-m的话,对应的导入会在hdfs上差生相应的中间结果,当你下一次再次执行job时,则会因为output directory is exist 报错。
或者可以知道 -m 1 再加上 --delete-target-dir \ 删除存在的目标目录 也行
2)上面的hive的表testlast必须是已存在的。在第一次导入的时候,为了使得表存在,可以通过将mysql中的testlast的表结构导入到hive中,执行的命令如下:
使用sqoop在hive创建mysql表结构语句
生成与关系数据库表结构对应的hive表结构 Sqoop 命令&参数:create-hive-table
sqoop create-hive-table \
--connect jdbc:mysql://hadoop01:3306/test \
--username root --password root \
--table testlast \
--hive-database guli \
--hive-table testlast
执行完后,会在hive中创建一个具有相同名字和相同表结构的表。
若出现 sqoop-导入数据出现java.sql.SQLException: Streaming result set com.mysql.jdbc.
可以加一句话 指定驱动 --driver com.mysql.jdbc.Driver \ 即可
即
sqoop create-hive-table \
--connect jdbc:mysql://hadoop01:3306/test \
--username root --password root \
--driver com.mysql.jdbc.Driver \
--table testlast \
--hive-database guli \
--hive-table testlast
执行建表完成之后再执行最上面的创建job的语句
(2)查看并执行job
上面已经创建了job后,可以通过下面的命令来查看是否已经创建job成功:
sqoop job --list 列出所有的job
sqoop job --show jobname 显示jobname的信息
sqoop job --delete jobname 删除jobname
sqoop job --exec jobname 执行jobname
1. sqoop job --list 列出所有的job
2.sqoop job --show jobname 显示jobname的信息
这个要输入密码??? 我这个测试机密码都是一个 所以不知道到底要输入什么密码 猜想是创建job的用户的密码
网搜可以配置配置文件不输入密码
然后执行!
中间的结果信息 会自动给你更新lastmotify
19/09/20 16:37:24 INFO manager.SqlManager: Executing SQL statement: SELECT t.* FROM testlast AS t WHERE 1=0
19/09/20 16:37:24 INFO tool.ImportTool: Incremental import based on column lastmodify
19/09/20 16:37:24 INFO tool.ImportTool: Lower bound value: '2019/09/20 14:39:00'
19/09/20 16:37:24 INFO tool.ImportTool: Upper bound value: '2019-09-20 16:37:24.0'
19/09/20 16:37:29 INFO db.DataDrivenDBInputFormat:
BoundingValsQuery: SELECT MIN(id), MAX(id) FROM testlast WHERE
( lastmodify >= '2019/09/20 14:39:00' AND lastmodify < '2019-09-20 16:37:24.0' )
再次查看job的信息 看到它自动更新了 incremental.last.value 信息
说明:从上面的部分我们很清楚的知道,sqoop在导入的时候是怎么导入。我们可以知道设置的–last-value的值就是对应的下界。
(3)执行完job后,查看hive中的表是否有数据。当然不出意外肯定是有数据的
并且在 执行的过程中,我们可以看到对应的执行日志如下:
(4)在关系数据库oracle中对testlast添加一个字段
id name lastmodified
1 shi 2019-09-20 14:43:27
2 shuai 2019-09-20 14:44:17
3 sun 2019-09-20 16:40:31
4 qing 2019-09-20 16:41:14
(5)此时进行增量导入
即再一次执行job:sqoop job --exec jobname
再次查看日志的内容如下:
说明:我们可以从执行的日志中看出,–last-value的值会自动更新为上一次的上界的值,注意看一下上次的上界即可。
19/09/20 16:42:27 INFO manager.SqlManager: Executing SQL statement: SELECT t.* FROM testlast AS t WHERE 1=0
19/09/20 16:42:27 INFO tool.ImportTool: Incremental import based on column lastmodify
19/09/20 16:42:27 INFO tool.ImportTool: Lower bound value: '2019-09-20 16:37:24.0'
19/09/20 16:42:27 INFO tool.ImportTool: Upper bound value: '2019-09-20 16:42:27.0'
19/09/20 16:42:32 INFO db.DataDrivenDBInputFormat: BoundingValsQuery:
SELECT MIN(id), MAX(id) FROM testlast WHERE
( lastmodify >= '2019-09-20 16:37:24.0' AND lastmodify < '2019-09-20 16:42:27.0' )
没有问题 ,在不考虑之前的数据更新的问题情况下, 只实现纯粹的增量导入(根据lastmodified即时间) 更新数据, 可以考虑使用linux的 contab 定时器定时执行
以上参考博客
sqoop的增量导入(increment import)
再试一次
在mysql再插一条数据
上界是上次的incremental.last.value
19/09/20 17:02:00 INFO tool.ImportTool: Lower bound value: '2019-09-20 16:42:27.0'
19/09/20 17:02:00 INFO tool.ImportTool: Upper bound value: '2019-09-20 17:02:00.0'
19/09/20 17:02:05 INFO db.DataDrivenDBInputFormat:
BoundingValsQuery: SELECT MIN(id), MAX(id) FROM testlast WHERE
( lastmodify >= '2019-09-20 16:42:27.0' AND lastmodify < '2019-09-20 17:02:00.0' )
确认incremental.last.value = 2019-09-20 17:02:00.0是执行完job的时间 不是数据的时间
另外 还有一点