Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

2.3_Rdbms Writer

elevenqq edited this page Sep 30, 2018 · 2 revisions

一、使用场景

Rdbms-Writer插件主要用于将其他类型数据源的增量数据进行处理和转换,最后写入关系型数据源,主要包括MYSQL、SQLSERVER、POSTGRESQL几种。目前的应用场景主要有两种:一种是线上各个系统间的基础参数表同步,另外一种是线上数据同步到OLAP系统(主要是BI)。

二、设计原理

Rdbms-Writer插件自定义的RdbEventRecordHandler继承自com.ucar.datalink.worker.api.handle.AbstractHandler,使用了系统提供的默认流程(详见深入领域),并根据需要自行扩展了一些功能,执行最终的目标端写入操作。具体的数据写入流程如下图所示:

RDBMS-Writer

  • 【构建sql】
    > 首先,Rdbms-Writer将Records按批量拆分,根据关系型数据库方言的sql构造模板,为每个Record构造相应的sql。默认批量大小为100,各批并发进行。
    > 对于EventType为INSERT的Record,若目标端数据库方言支持MergeSql(如mysql、sqlserver、oracle),则为Record构造对应的MergeSql,处理主键冲突的情况(改为update),若不支持MergeSql则构造InsertSql;对于EventType为UPDATE和DELETE的Record,分别为Record构造对应的UpdateSql、DeleteSql。
  • 【Records分组】
    Rdbms-Writer的同步模式分为全局有序、局部有序、充分并发三种。
    > 全局有序:当同步模式为DbGlobalOrdered时,不进行分组,直接按照全局顺序加载RdbEventRecords,完全按照源端日志的执行顺序进行重放
    > 局部有序:当同步模式为TablePartlyOrdered时,为每个RdbEventRecord按表进行分组,保证单表内的局部有序。当Rdbms-Writer未启用压缩合并时,因为没有根据相同sql进行batch组合,所以自动禁用批量写入,按一张表一个分组来构建batchRecords。
    > 充分并发:当Rdbms-Writer启用了压缩合并功能的时候,会在表级别基础上根据INSERT/UPDATE/DELETE进行更细粒度的分组。在合并完之后,能保证同一张表的同一条数据只有一条binlog事件,此时可以完全打乱顺序,保证最终一致即可。若同时启用了批量写入,则将原DELETE、INSERT/UPDATE分组的Records按照sql相同进行batch组合,为各组分别构建若干个大小为batchSize的batchRecords;若未启用批量写入,则将DELETE、INSERT/UPDATE分组按原样构建batchRecords。
    注:压缩合并情况下,优先执行DELETE语句,针对uniqe更新,一般会进行DELETE+INSERT的处理模式,避免并发更新。
  • 【Records加载】
    > 数据写入的最后一个环节,执行数据持久化操作,各分组的batchRecords并行加载。若Rdbms-Writer启用了批量写入,则根据batchSize进行批量更新,否则进行单条更新。
    注:若批量模式出错,则转为single模式,以保证尽可能把不报错的数据写入到目标库,并且改为single模式,才能知道具体出错的record是哪一条。
    > 根据目标端DbDialect进行相应的数据处理,并通过构建预编译对象PreparedStatement执行最终的数据写入,以提高效率。
    注:insert为更新所有字段,update只更新带有isUpdate=true的字段,delete根据主键删除。

三、功能介绍

  • 【HA机制】
    > 目标端依靠自己的HA机制实现高可用,如:向mysql同步时指定的是vip,mysql通过pxc或mha实现HA。
  • 【有序消费】
    > Rdbms-Writer支持Binlog局部有序消费和全局有序消费。
    1)当同步模式为TablePartlyOrdered时,按表分组保证局部有序,即单表的执行顺序和Binlog一致;
    2)当同步模式为DbGlobalOrdered时,完全按照Binlog的顺序进行replay。
  • 【并发消费】
    > Rdbms-Writer支持并发消费,以提升消费速度。
    1)当按表分组时,是全局并发,即先并发,然后每个并发线程再有序运行。若未开启批量更新,并发数=分组数,若开启了批量更新,并发数=分组的批次总数(分组的Records.size()/batchSize);
    2)当未按表分组时,是局部并发,即先保证有序,运行到每条数据的时候再考虑并发。
  • 【批量更新】
    > Rdbms-Writer向目标端进行写入的时候,可以启用压缩合并与批量更新,并设置每次写入的batchSize,以增大吞吐率,提高系统性能。
    系统默认情况下是单条写入,当需要同步的数据量比较大时,可以开启批量更新模式。
  • 【主键冲突处理】
    > 当插入出现主键冲突时,Rdbms-Writer有两种处理方式:
    1)若目标端数据库方言支持MergeSql(如mysql、sqlserver、oracle),则构造MergeSql处理,当insert出现主键冲突时自动改为update。
    2)若目标端数据库方言不支持MergeSql,当insert出现主键冲突时,会忽略该Record。
  • 【ddl拦截器】
    > Rdbms-Writer在AbstractHandler内置的基础拦截器前面增加自定义拦截器DdlEventInterceptor,对ddl类型的Record进行sql解析。
    1)当配置全库同步时,自动同步sql类型为CreateTable的Record;

    2)当目标表的数据量不超过500万时,自动同步sql类型为AlterTable的Record。
  • 【自动加字段】
    > 当发现目标表缺字段时,可以设置Rdbms-Writer自动构造sql补全所缺字段。
    目前源端只支持mysql,目标端支持mysql、sqlserver、postgresql,且目标表记录总数不超过500万
  • 【过滤机制】
    > 过滤字段:每张表可以设置列映射模式,通过黑白名单过滤特定的字段,白名单时可以配置字段别名。
    > 过滤Records:可以通过内置拦截器,设置主键黑名单,跳过指定主键的Records;也可以自定义拦截器,对某些Records进行过滤或特殊处理
    ,来满足特定场景下的同步需求。
    目前Rdbms-Writer用到的拦截器举例:
    OrderEntRecordInterceptor,用于拦截非企业订单,只同步企业订单。
    UcarincGpsInterceptor、ZucheGpsInterceptor,用于不同库的不同表数据同步到同一个目标库的同一个表中时,对一些Records的特殊处理逻辑。
    ObdRecordInterceptor,用于拦截一些表的字段满足特定条件的Records。

四、插件参数说明

在继承Writer插件通用参数基类(PluginWriterParameter,详见深入Task)的基础上,RdbmsWriterParameter还针对Rdbms类型数据库的特点扩展了自己的参数类,用户可以根据需求在页面更改其参数配置。

RdbmsWriterParameter扩展参数 参数描述 默认值 备注

SyncMode

同步模式

TablePartlyOrdered

Rdbms-Writer同步模式分为两种:

DbGlobalOrdered,//库级别,全局有序

TablePartlyOrdered;//表级别,局部有序

五、Mapping参数说明

一个Mapping代表同步方向的同时也定义了同步行为,即同步过程中需要经过哪些特殊处理。Rdbms-Writer插件的相关Mapping配置参数如下:

Mapping参数 参数描述 默认值 备注

targetMediaSourceId

目标端数据源的id

目标数据源,这里指要同步到的RDBMS类型数据库

targetMediaName

目标端表的名字

支持目标端有表别名,用于源端和目标端表名不一致的情况

targetMediaNamespace

目标端数据源的namespace

目标端数据源schema

ColumnMappingMode

列映射模式

NONE

支持列名黑白名单与列别名:

NONE,//所有列均同步到目标端

INCLUDE,//只同步白名单中的列,可以设置列别名

EXCLUDE;//黑名单中的列不同步

writePriority

同步优先级

5

数值越小优先级越高

interceptorId

拦截器id

拦截器可以对Records进行特殊处理,满足少数特定功能的需求

skipIds

主键黑名单

可以通过指定主键id来过滤源端的某些异常Records

valid

是否有效

同步映射有效时,才进行同步

六、版本说明

关联技术 稳定版本 待测版本

mysql

5.1.35

其他

sqlserver

4.0

其他

postgresql

42.1.4

其他

七、注意事项

Rdbms-Writer的内置拦截器DdlEventInterceptor对ddl同步的一些限制:

对于sql类型为CreateTable的Record,在全库同步的情况下自动同步,若不是全库同步,则直接忽略。
对于sql类型为AlterTable的Record,当目标表的数据量不超过500万时自动同步,若超过了500万,则提示人工介入。
对于sql类型为DropTable或者其他类型的Record,直接忽略,暂时只支持CreateTable和AlterTable类型的ddl自动同步。
对于异构数据源之间的ddl类型的Record,直接忽略,暂时只支持同构数据源之间的ddl自动同步,例如mysql同步到mysql。
对于配置了白名单和列别名的情况,暂时不做更细粒度的判断,直接忽略ddl语句。
对于配置了拦截器的情况,暂时不支持ddl自动同步。

八、FAQ

sqlserver merge sql 参考文档:https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /