数据库表同步的三种方法

6 篇文章 0 订阅

1、前言:

最近项目准备上线,要先做一下并行,所以要把调用接口的请求 请求到生产环境的同时也请求到并行环境。我刚开始,写了一个程序,多线程去生产数据库(接口有记录表,记录请求报文)取到请求报文,然后再拼接成curl请求命令,请求到并行环境,结果跑了没半天就差点儿把生产数据库搞挂。原因是,我的程序每五分钟调用一次,调用会获取11个数据库连接,结果因为生产上数据量大,五分钟没有处理完成,另一个调度就调起来了,这样一下午累积下来,产生了上百个连接,生成cpu飙到了%90以上,触发了告警,领导收到了告警短信才发现了问题。
之后应领导要求,我的并行程序不能直接连接生产库,需要异步处理(需要数据库做中转),那么就涉及到一个如何获取生产数据库中的报文数据的问题。通过上网查询,大体有三个方案:

1.1 使用触发器

在接口报文记录表上添加一个触发器,每次请求的报文插入生产记录表的同时触发器插入到中转数据库。
优点:编程简单,只需要几行
缺点:会影响生产数据库性能,同时该触发器需要配合dblink,可能存在潜在危险。

-- 一个简单的oracle触发器
CREATE OR REPLACE TRIGGER MY_TGR
BEFORE INSERT ON jd.ims_json_soap_1_0
FOR EACH ROW--对表的每一行触发器执行一次,插入test_b的同时插入test_a
BEGIN
insert into cd.ims_json_soap_1_0(name,age,school,home,ext)  values(:NEW.name,:NEW.age,:NEW.school,:NEW.home,:NEW.ext);
END;
1.2 使用canal

canal是阿里巴巴提供的一个开源工具,通过监听数据库binlog日志,解析出语句,然后执行,该程序对于mysql很友好,但是oracle(归档日志)貌似支持部分.太新的版本应该还不支持,这个还没有尝试。

1.3 使用kettle

kettle是一款国外的开源ETL工具,使用的时候只需要下载解压就可以使用,数据抽取速度可以达到每秒上万条数据的同步。

2、kettle的使用

2.1 下载安装kettle

我这里使用的是pdi-ce-7.1.0.0-12
在这里插入图片描述

2.2 表同步生成ktr文件

因为生产数据是实时有调用记录插入的,所以我的同步方案是增量同步。
通过目标表的最新时间到生产源表里面获取最新的记录

2.2.1 最终转换效果

在这里插入图片描述

2.2.2 MaxDate

获取目标表(中转数据库中的表)最大时间做为一个表输入。
在这里插入图片描述

2.2.3 常规(生产数据库)

注意下面的从步骤插入数据,sql语句中的问号会在执行的时候替换为下面的MaxData(该名字需要和上一步中的步骤名称保持一致)
在这里插入图片描述

2.2.4 表输出

这里其实还可以使用 插入/更新 但是这种方式相对慢一些,但是更灵活,可以自定义同步的字段,由于我这里表结构都是相同的,所以我采用表输出的方式,这样的效率更高。

在这里插入图片描述

在这里插入图片描述
最后按住shirt通过拖拉将两个输入和一个输出连接起来就可以了
在这里插入图片描述
我这里应为分表的关系有十张分表都需要同步,所以我复制了十个这样的转换。

2.3 执行ktr文件

在这里插入图片描述
转换过程
在这里插入图片描述

3、java整合kettle,通过程序调用执行ktr文件

由于我的需要放在服务器上去定时调度,所以我采用的是Java + crontab的方式实现的定时调度执行ktr文件。

   /**
     * 执行ktr文件
     * @param args
     */
    public static void main(String[] args) throws KettleException {
        //初始化ketlle
        KettleEnvironment.init();
        //创建转换元数据对象
        //TransMeta meta = new TransMeta("etl/update_insert_Trans.ktr");
        TransMeta meta = new TransMeta("D:\\Tools\\Kettle\\save\\常规到紧急0分表.ktr");
        Trans trans = new Trans(meta);
        trans.prepareExecution(null);
        trans.startThreads();
        // 等待执行完成
        trans.waitUntilFinished();
        if(trans.getErrors()!=0){
            System.out.println("执行失败!");
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值