Apache SeaTunnel 是下一代高性能、分布式、海量数据集成平台,已经在 B 站、腾讯云等 100+ 家公司生产使用。目前处于 incubator 阶段。作为公司内部使用的 ETL 工具,Seatunnel 可以基于已有的 Spark、Flink 计算平台进行数据交换也可以运行在 k8s 平台上,作为公司大数据团队小小小组长在调研了海量的开源项目(其实就一两个)最终选用 Seatunnel 作为公司的 ETL 工具的底层。而在前期测试过程中发现 Seatunnel 依然存在一些 bug,而本人也在结合公司数据迁移业务发现了若干 bug 并提交代码进行解决同时结合业务场景提交了一个 feature,如果你也想成为它的 contributors 那你就需要认真阅读这篇文章了。下面将从零开始教你成为 Seatunnel 源码贡献者。
一、写在前面
首先你必须要有使用 Seatunnel 的需求,如果只是学习、测试已经很难发现 bug,因为 Seatunnel 从 2017 年开始,经过近五年的发展一些浅显的 bug 早就不复存在,加上 Seatunnel 严格的 e2e 通过对产品的简单使用很难发现问题(一些冷门的连接器除外)。
二、如何编译
官方文档已经给出了源码编译的过程,但随着项目的开发和我实际编译过程中出现的问题,对文档做出补充。下面是我在三端(mac、windows、linux)编译过程中出现的问题的总结以及解决方案
spotless插件下载失败[403]
根据报错信息,发现是 javac-shaded-9+181-r4173-1.jar(当你看到这里的时候可能已经不是这个版本了)下载失败 403 错误,解决方案:
maven 中心仓库中手动下载 jar 包
项目根路径下执行(注意 jar 包路径的替换)
mvn install:install-file -DgroupId=com.google.errorprone -DartifactId=javac-shaded -Dversion=9+181-r4173-1 -Dpackaging=jar -Dfile=/root/Project/lib/javac-shaded-9+181-r4173-1.jar
jindo 系列包不存在
这类问题主要是阿里云 oss 连接器的问题,jindo 的介绍可以看这里 下载地址 。他的 jar 目前没有上传至 maven 各大仓库(阿里云自己的maven也没有),因此需要离线下载 下载地址,解压之后我们需要给 Seatunnel 安装下面两个 jar,都在下载的 tar 的 lib 目录下
mvn install:install-file -DgroupId=com.aliyun.jindodata -DartifactId=jindo-core -Dversion=4.6.1 -Dpackaging=jar -Dfile=/Users/wjun/Documents/Program/lib/jindosdk-4.6.1/lib/jindo-core-4.6.1.jar
mvn install:install-file -DgroupId=com.aliyun.jindodata -DartifactId=jindosdk -Dversion=4.6.1 -Dpackaging=jar -Dfile=/Users/wjun/Documents/Program/lib/jindosdk-4.6.1/lib/jindo-sdk-4.6.1.jar
这样基本上都可以编译通过,例如:
编译整个项目
mvn clean package -pl seatunnel-dist -am -Dmaven.test.skip=true
编译某个模块
mvn clean package -pl seatunnel-connectors-v2/connector-redis -am -DskipTests -T 1C
三、如何运行&调试
官方文档已经给出了本地运行的方式,但如果你运行其他连接器时就会出现
Caused by: java.lang.RuntimeException: Plugin PluginIdentifier{engineType='seatunnel', pluginType='source', pluginName='Elasticsearch'} not found.
at org.apache.seatunnel.plugin.discovery.AbstractPluginDiscovery.createPluginInstance(AbstractPluginDiscovery.java:219)
at org.apache.seatunnel.engine.core.parse.ConnectorInstanceLoader.loadSourceInstance(ConnectorInstanceLoader.java:63)
at org.apache.seatunnel.engine.core.parse.JobConfigParser.sampleAnalyze(JobConfigParser.java:352)
at org.apache.seatunnel.engine.core.parse.JobConfigParser.parse(JobConfigParser.java:133)
at org.apache.seatunnel.engine.client.job.JobExecutionEnvironment.getLogicalDag(JobExecutionEnvironment.java:155)
at org.apache.seatunnel.engine.client.job.JobExecutionEnvironment.execute(JobExecutionEnvironment.java:147)
at org.apache.seatunnel.core.starter.seatunnel.command.ClientExecuteCommand.execute(ClientExecuteCommand.java:122)
... 2 more
例如我在调试 Elasticsearch 插件时就出现这个问题,很显然运行时的相关 jar 没有被加载,只需要在 seatunnel-engine-examples
模块的 pom 文件添加上对应插件模块的依赖即可,例如调试 es
<?xml version="1.0" encoding="UTF-8"?>
<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.seatunnel</groupId>
<artifactId>seatunnel-examples</artifactId>
<version>${revision}</version>
</parent>
<artifactId>seatunnel-engine-examples</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.seatunnel</groupId>
<artifactId>seatunnel-starter</artifactId>
<version>${project.version}</version>
</dependency>
<!-- seatunnel-transforms-v2 -->
<dependency>
<groupId>org.apache.seatunnel</groupId>
<artifactId>seatunnel-transforms-v2</artifactId>
<version>${project.version}</version>
</dependency>
<!-- seatunnel-transforms-v2 -->
<dependency>
<groupId>org.apache.seatunnel</groupId>
<artifactId>connector-console</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.seatunnel</groupId>
<artifactId>connector-elasticsearch</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
</dependencies>
</project>
这里排除 guava 只是针对 Elasticsearch,之前的作者在开发 Elasticsearch 支持 https 协议时使用的 airlift 依赖的 guava 与 Seatunnel 统一定义的 guava 版本冲突了(这个问题已经被我顺带解决了pr#4076) ,这时候就可以在 IDE 上随意打断点了。
四、如何PR
当你在使用过程中出现了 bug 首先你应该去 github 上搜索或提出 issue,因为你所使用的 release 版本这个 bug 可能已经被发现和解决,这时候你只需要拉取最新的 dev 分支代码后重新编译出现 bug 的模块后替换 jar 包即可。如果在 issue 或 pr 上没有发现这个 bug,那么需要你贡献力量的时候到了。
首先你需要 fork 源代码到你的私有仓库 -> clone 私有仓库到本地 -> 创建bug分支并修改代码 —> 本地运行测试
如果你为 Seatunnel 添加了 feature 你还需要为其编写 e2e 和补齐 docs
当一切没有问题时不要着急提交你的代码,你可能需要走一遍 CI,当然这个 CI 你可以推到远程仓库交由 github 执行,如果你不想 review 的成员看到你因为通过 CI 而疯狂 commit 最好在本地跑一遍 CI
个人建议首先通过插件格式化一下代码(这也是 CI 的一部分,即使你只是修改了一下文档),命令如下
mvn spotless:apply
如果修改过 e2e 则也需要走一遍 CI(最好跑一遍,我的多次提交就是因为过分相信自己让 github 跑 CI),注意:e2e 的 CI 需要本地有 Docker 环境,命令如下
mvn -T 1C -B verify -DskipUT=true -DskipIT=false -D"license.skipAddThirdParty"=true --no-snapshot-updates -pl :connector-elasticsearch-e2e -am -Pci
经过三端测试,相同配置在 linux 上跑 e2e 的 CI 最快,可能是因为 Docker 在 windows、mac 独特的运行模式吧
当 CI 本地没有问题时就可以提交代码并创建 PR 了,此时你需要按照规范编写一段详细的 commented 并关注绑定 github 的邮箱邮件即可。Seatunnel 社区成员还是很活跃很大一部分都是国人,但在沟通时最好还是使用英文(机翻即可,啊哈哈哈!!!)