需求
使用Apache NiFi实时分发企业主数据到下游业务系统时,下游系统有MySQL、PostgreSQL、Oracle等业务系统,其中NiFi不直接支持Oracle Upsert语义,导致产品、物料等主数据大量更新时,通过insert-error-update的方式分发Orace数据给下游,性能不足。故计划通过自定义Processor,通过借助Oracle 内置的Merge into语法实现Upsert功能。
在Apache NiFi自定义Processor中
介绍了Apache NiFi 自定义开发Processor环境搭建流程,本文介绍通过修改NiFi源码中PutDatabaseRecord.java类的方式实现NiFi支持Oracle内置的Merge into功能。
开发环境准备
请详细参考Apache NiFi自定义Processor中介绍的步骤,完成开发环境搭建。
自定义Oracle upsert Processor
VS Code查看NiFi源码
笔者喜欢使用IDEA做Java开发IDE,使用VS Code作为单纯的代码检索或者数仓、前端、Rust等开发工具。VS Code的启动速度感觉比IDEA快不少。
通过探索NiFi源码,找到PutDatabaseRecord.java文件。
- Github 下载NiFi最新代码
- 通过探索NiFi源码,找到PutDatabaseRecord.java文件
搭建IDEA开发环境
步骤1:注释掉整个MyProcessor.java类文件
步骤2:复制PutDatabaseRecord.java到IDEA开发环境中
直接复制源码到IDEA中后,可能有如上图显示的错误,修正方法如下:
- 主工程pom文件中,需要将1.4.0修改为15.3
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-nar-bundles</artifactId>
<version>1.15.3</version>
</parent>
<groupId>com</groupId>
<artifactId>cvte</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>nifi-cvte-processors</module>
<module>nifi-cvte-nar</module>
</modules>
</project>
- processor子工程pom,引入依赖包
<!-- DB控件服务相关包,数据库链接之类的配置-->
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-standard-services-api-nar</artifactId>
<version>1.15.3</version>
<type>nar</type>
</dependency>
<!-- PutDatabaseRecord相关包 注释掉以下包,重写 DatabaseAdapter类,否则会生成1.0版本的标准Processor,详见源码-->
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-standard-processors</artifactId>
<version>1.15.3</version>
<scope>provided</scope>
</dependency>
<!-- org.apache.nifi.serialization.RecordReaderFactory -->
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-record-serialization-service-api</artifactId>
<version>1.15.3</version>
<scope>provided</scope>
</dependency>
步骤3:修改类名
避免自定义的PutDatabaseRecord类文件名与NiFi 标准Processor的类名冲突,使用Idea的rename将类名修改为:PutOracleDatabaseRecordMerge。修改后,需要修改资源文件中引用的类名。
增加操作数据库Adaper类
- 复制NiFi源码DatabaseAdapter修改类名为CvteDatabaseAdapter,不修改代码内容
- 复制NiFi源码PostgreSQLDatabaseAdapter修改类名为CvteOracleDatabaseAdapter,修改代码如下:
修改PutDatabaseRecordMerge代码
修改Meta-info
https://github.com/dawsongzhao1104/nifi/tree/main/nifi-processorhttps://github.com/dawsongzhao1104/nifi/tree/main/nifi-processor
步骤4:打包运行
⚠️问题: 大量标准组件,多了1.0版本。这个貌似是我们引入的。查看我们编译的PutDatabaseRecordMerge.nar包,大于58MB。标准的processor nar包大概12MB左右。猜测,应该是我们的打包工具把标准的Processor复制到自己的Processor中导致。
- 解决标准组件多了1.0版本问题
注释掉nifi-standard-processors
依赖Jar包。重写DatabaseAdapter类
验证测试
配置数据库服务
配置JsonTreeReader
配置JsonRecordSetWriter
配置ExecuteSQLRecord
配置验证环境
参考资料
[1] https://community.cloudera.com/t5/Community-Articles/Build-Custom-Nifi-Processor/ta-p/244734
[2] https://www.youtube.com/watch?v=v2u0WsPs2Ac
总结
本文讲解了改写PutDatabaseRecord源码的方式实现Oracle merge,探索了通过重写DatabaseAdapter,并注释掉nifi-standard-processors
依赖规避产生自定义版本号的标准Processor问题。
对于文中任何疑问,欢迎加Q讨论:568072887