【Sqoop】Sqoop job实现增量导入的原理

本文详细介绍了使用Sqoop进行数据库增量导入的两种方法,重点讲解了通过创建job自动记录和更新last-value,实现自动化批量导入的过程。通过实例演示了如何在MySQL中创建表并插入数据,随后使用Sqoop job进行增量导入,最后观察last-value的更新,验证了自动抽取增量数据的有效性。

我们在使用Sqoop的增量导入时,需要配置三个参数:
在这里插入图片描述
假设有这样的场景:

使用Sqoop每天定时导出emp表的增量数据,其中emp的id列为自增列。

那么此时有两种方式实现:

(1) 每天手工配置last-value,手工调度;

(2) 使用job,给定初始last-value,定时任务每天自动跑批;

相信大多数人会选择第(2)种方式。

为什么job可以给定一次last-value就可以自动抽取增量呢?

这是因为批量每次跑完后,job会把当前check-column的最大值记录到meta中,下次再调起时自动把此值赋给last-value。

meta信息存在哪里呢?

在sqoop-site.xml中有这样的配置:

sqoop.metastore.server.location /tmp/sqoop-metastore/shared.db Path to the shared metastore database files. If this is not set, it will be placed in ~/.sqoop/.

可以发现,sqoop.metastore.server.location就是与元数据相关的保存路径。

如果没有设置,默认路径是:~/.sqoop/

[hadoop@node03 conf]$ cd ~/.sqoop/
[hadoop@node03 .sqoop]$ ll
total 12
-rw-rw-r-- 1 hadoop hadoop  419 Feb 21 19:31 metastore.db.properties
-rw-rw-r-- 1 hadoop hadoop 6198 Feb 21 19:31 metastore.db.script

其中,metastore.db.script文件记录了对last-value的更新操作:

[hadoop@node03 .sqoop]$ cat metastore.db.script |grep incremental.last.value
INSERT INTO SQOOP_SESSIONS VALUES('myjob1','incremental.last.value','1205','SqoopOptions')

上面的例子显示,更新SQOOP_SESSIONS的incremental.last.value为1205

也就是我的实验中最后一次增量的最大值。

下面是完整实验过程,想验证的小伙伴可以参考:

1.mysql中建库,建表并插入测试数据:

create database userdb;
use userdb;

create table emp(
id int(11) default null,
name varchar(100) default null,
deg varchar(100) default null,
salary int(11) default null,
dept varchar(10) default null,
create_time timestamp not null default current_timestamp,
update_time timestamp not null default current_timestamp on update current_timestamp,
is_delete bigint(20) default '1'
)
engine = innodb default charset=latin1;


insert into emp(id,name,deg,salary,dept) values (1201,'gopal','manager',50000,'TP'),
(1202,'manisha','Proof reader',50000,'TP'),
(1203,'khalil','php dev',30000,'AC'),
(1204,'prasanth','php dev',30000,'AC'),
(1205,'kranthi','admin',20000,'TP');

2.新建sqoop job

bin/sqoop job --create myjob1 -- import \
--connect jdbc:mysql://node03:3306/userdb \
--username root --password 123456 \
--table emp \
--incremental append \
--check-column id \
--last-value 1202 \
--target-dir /sqoop/increment/emp \
-m 1

3.执行job

bin/sqoop job --exec myjob1

4.观察last-value的更新值,发现已经更新为最大值

[hadoop@node03 conf]$ cd ~/.sqoop/
[hadoop@node03 .sqoop]$ cat metastore.db.script |grep incremental.last.value
INSERT INTO SQOOP_SESSIONS VALUES('myjob1','incremental.last.value','1205','SqoopOptions')
### 三、Sqoop 实现数据的增量更新方法 Sqoop 支持多种方式实现数据的增量更新,主要通过 `--incremental` 参数控制增量导入的类型,结合 `--check-column` 和 `--last-value` 来实现数据的自动同步与更新。 #### 1. 增量导入类型 Sqoop 提供了两种主要的增量导入模式: - **append**:适用于基于自增列(如 ID)的增量导入。这种方式仅导入大于 `--last-value` 的记录。 - **lastmodified**:适用于基于时间戳字段的增量导入。这种方式导入在指定时间之后更新或插入的记录。 例如,使用 `append` 模式进行增量导入的命令如下: ```bash sqoop import \ --connect jdbc:mysql://xxx:3306/xxx \ --username root \ --password root \ --table category \ --target-dir /user/survey/sqoop1 \ --incremental append \ --check-column id \ --last-value 1000 \ --m 1 \ --fields-terminated-by "\001" ``` 该命令会导入 `id` 大于 1000 的新记录,适用于自增主键的情况[^1]。 #### 2. 自动记录上次同步值(Last Value) Sqoop 支持通过 `sqoop job` 的方式创建增量同步任务,它会在元数据中自动记录上一次导入的 `last-value`,无需手动指定。例如: ```bash sqoop job \ --create myjob1 \ -- import \ --connect jdbc:mysql://xxx:3306/xxx \ --username root \ --password root \ --table category \ --target-dir /user/survey/sqoop1 \ --incremental append \ --check-column id \ --last-value 1000 \ --m 1 \ --fields-terminated-by "\001" ``` 在首次执行后,后续只需运行: ```bash sqoop job --exec myjob1 ``` 即可自动使用上次的 `last-value`,实现增量更新。 #### 3. 基于时间戳字段的增量导入 当数据更新依赖时间戳字段时,可使用 `lastmodified` 模式。例如: ```bash sqoop import \ --connect jdbc:mysql://xxx:3306/xxx \ --username root \ --password root \ --table category \ --target-dir /user/survey/sqoop1 \ --incremental lastmodified \ --check-column updated_at \ --last-value "2019-06-12 12:39:43" \ --m 1 \ --fields-terminated-by "\001" ``` 该命令会导入 `updated_at` 时间戳大于 `2019-06-12 12:39:43` 的记录,适用于基于时间更新的场景[^2]。 #### 4. 使用 SQL 查询实现更灵活的增量控制 除了使用 `--incremental` 参数,还可以通过自定义 SQL 查询实现更复杂的增量逻辑。例如: ```bash sqoop import \ --connect jdbc:mysql://xxx:3306/xxx \ --username root \ --password root \ --target-dir /user/survey/sqoop1 \ --query 'SELECT * FROM category WHERE create_time >= "2023-01-01" AND $CONDITIONS' \ --split-by id \ --m 4 ``` 该方式允许使用任意 SQL 条件进行数据过滤,适用于复杂业务场景下的增量导入[^4]。 #### 5. 增量导出与更新 Sqoop 同样支持增量导出到关系型数据库,结合 `--update-mode` 和 `--update-key` 可以实现数据的更新操作。例如: ```bash sqoop export \ --connect jdbc:mysql://xxx:3306/xxx \ --username root \ --password root \ --table category \ --export-dir /user/survey/sqoop1 \ --update-mode updateonly \ --update-key id ``` 该命令会根据 `id` 字段匹配数据库记录并执行更新操作。若需要同时支持更新与插入,可使用 `allowinsert` 模式[^5]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值