kettlespoon判断增量更新_使⽤Kettle实现数据实时增量同步时
间戳增量回滚同步
0. 前⾔
本⽂介绍了使⽤Kettle对⼀张业务表数据(500万条数据以上)进⾏实时(10秒)同步,采⽤了时间戳增量回滚同步的⽅法。关于ETL和Kettle的⼊门知识⼤家可以阅读相关的blog和⽂档学习。
1. 时间戳增量回滚同步
假定在源数据表中有⼀个字段会记录数据的新增或修改时间,可以通过它对数据在时间维度上进⾏排序。通过中间表记录每次更新的时间戳,在下⼀个同步周期时,通过这个时间戳同步该时间戳以后的增量数据。这是时间戳增量同步。
但是时间戳增量同步不能对源数据库中历史数据的删除操作进⾏同步,我们可以通过在每次同步时,把时间戳往前回滚⼀段时间,从⽽同步⼀定时间段内的删除操作。这就是时间戳增量回滚同步,这个名字是我⾃⼰给取得,意会即可,就是在时间戳增量同步的同时回滚⼀定的时间段。
说明:
源数据表 需要被同步的数据表
⽬标数据表 同步⾄的数据表
中间表 存储时间戳的表
2. 前期准备
在两个数据库中分别创建数据表,并通过脚本在源数据表中插⼊500万条数据,完成后再以每秒⼀条的速度插⼊新数据,模拟⽣产环境。
源数据表结构如下:
CREATE TABLE `im_message` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sender` varchar(45) COLLATE utf8_bin NOT NULL COMMENT '消息发送者:SYSTEM',
`send_time` datetime(6) NOT NULL,
`receiver` varchar(45) COLLATE utf8_bin NOT NULL COMMENT '消息接受者',
`content` varchar(255) COLLATE utf8_bin NOT NULL COMMENT '消息内容',
`is_read` tinyint(4) NOT NULL COMMENT '消息是否被读取:0-未读;⾮0-已读',
`read_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),阳澄湖在哪里哪个省的
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='消息表'
3. 作业流程
1. 开始组件
2. 建时间戳中间表
3. 获取中间表的时间戳,并设置为全局变量
4. 删除⽬标表中时间戳及时间戳以后的数据
5. 抽取两个数据表的时间戳及时间戳以后的数据进⾏⽐对,并根据⽐对结果进⾏删除、新增或修改操作
6. 更新时间戳
4. 创建作业
作业的最终截图如下:
作业截图
4.1 创建作业和DB连接
打开Spoon⼯具,新建作业,然后在左侧主对象树DB连接中新建DB连接。创建连接并测试通过后可
以在左侧DB连接下右键共享出来。因为在单个作业或者转换中新建的DB连接都是局域数据源,在其他转换和作业中是不能使⽤的,即使属于同⼀个作业下的不同转换,所以需要把他们共享,这样DB连接就会成为全局数据源,不⽤多次编辑。
4.2 建时间戳中间表
这⼀步是为了在⽬标数据库建中间表etl_temp,并插⼊初始的时间戳字段。因为该作业在⽣产环境是循环调⽤的,该步骤在每⼀个同步周期中都会调⽤,所以在建表时需要判断该表是否已经存在,如果不存在才建表。
SQL代码和组件配置截图如下:
CREATE TABLE IF NOT EXISTS etl_temp(id int primary key,time_stamp timestamp);
INSERT IGNORE INTO etl_temp (id,time_stamp) VALUES (1,'2018-05-22 00:00:00');
中间配置截图
我把该作业时间戳的ID设为1,在接下来的步骤中也是通过这个ID查询我们想要的时间戳
4.2 获取时间戳并设为变量
新建⼀个转换,在转换中使⽤表输⼊和设置变量两个组件
表输⼊
SQL代码和组件配置截图如下
在Kettle中设置的变量都是字符串类型,为了便于⽐较。我在SQL语句把查出的时间戳进⾏了格式转换
select date_format(time_stamp , '%Y-%m-%d %H:%i:%s') time_stamp from etl_temp where id='1'
这⾥写图⽚描述
设置变量
变量活动类型可以为该变量设置四种有效活动范围,分别是JVM、该Job、⽗Job和祖⽗Job
这⾥写图⽚描述
4.3 删除⽬标表中时间戳及时间戳以后的数据
这样做有两个好处:
1. 避免在同步中重复或者遗漏数据。例如当时间戳在源数据表中不是唯⼀的,上⼀次同步周期最后⼀条数据的时间戳是2018-05-25
18:12:12,那么上⼀次同步周期结束后中间表中的时间戳就会更新为2018-05-25 18:12:12。如果在下
⼀个同步周期时源数据表中仍然有时间戳为2018-05-25 18:12:12的新数据,那么同步就会出现数据不⼀致。采⽤⼤于时间戳的⽅式同步就会遗漏数据,采⽤等于时间戳的⽅式同步就会重复同步数据。
2. 增加健壮性 当作业异常结束后,不⽤做任何多余的操作就可以重启。因为会删除⽬标表中时间戳及时间戳以后的数据,所以不⽤担⼼教师节快乐 英文
数据⼀致性问题
2018-09-29:对增加健壮性进⾏补充:在⼀次同步周期中脚本异常中断,这时候中间表的时间戳没有更新,但是⽬标表已经同步了部分数据,当再次启动脚本就会出现数据重复的情况,⽽且在很多时候因为主键的存在,脚本启动会报错
在组件中使⽤了上⼀步骤设置的变量,所以必须勾选使⽤变量替换
delete from test_kettle.im_message where send_time>='${TIME_STAMP}'
这⾥写图⽚描述
烟花三月歌曲4.4 抽取、⽐对和更新数据
那段自由的日子作文这⼀步才是真正的数据同步步骤,完成了数据的抽取、⽐对,并根据不同的⽐对结果删除、更新、插⼊或不做任何操作。
正如前⽂所说,为了同步删除操作,在原始表输⼊和⽬标表输⼊步骤中回滚了⼀定时间段。其中回滚的时间段设置为了全局的参数。左右空⽩处右键即可设置参数,该作业下的所有作业和转换都能使⽤,设置如下图中国卫浴
这⾥写图⽚描述
转换截图如下
这⾥写图⽚描述
原始表输⼊
红棍SELECT
id
, sender
, send_time
, receiver
, content
, is_read
, read_time
FROM ueqcsd.im_message
where send_time>= date_sub(str_to_date('${TIME_STAMP}','%Y-%m-%d %H:%i:%s'), interval ${ROLL_BACK_DAYS} day);
这⾥写图⽚描述
⽬标表输⼊
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论