[数据集成/数据同步] Apache Sea Tunnel FAQ
0 序
1 Apache Sea Tunnel FAQ
Q: SeaTunnel 作业启动时,是如何查找是否有指定的 Sink 的?
问题描述
- seatunnel-etl-job.conf
...
sink {
IoTDB {
node_urls = ["192.168.xxx.xxx:6667"]
username = "root"
password = "root"
sql_dialect = "table"
storage_group = "ods_xxx"
key_device = "device_type_vehicle_can_conditions"
key_timestamp = "collect_time"
key_tag_fields = ["vin"]
key_measurement_fields = [ "total_mileage", "subtotal_mileage", "online_status", "drive_speed", "engine_speed", "skylight_status","bms_soc","bms_soh" ]
key_attribute_fields = ["tbox_pdid", "model_code"]
batch_size = 1024
}
}

- 启动时报错:
sh bin/seatunnel.sh --config demo-jobs/mysql-to-iotdb_table.conf -m local(使用 Sea Tunnel 内置的 Zeta 引擎)
Caused by: org.apache.seatunnel.api.table.factory.FactoryException: ErrorCode:[API-06], ErrorDescription:[Factory initialize failed] - Unable to create a sink for identifier 'IoTDB'.
at org.apache.seatunnel.api.table.factory.FactoryUtil.createAndPrepareSink(FactoryUtil.java:250)
at org.apache.seatunnel.engine.core.parse.MultipleTableJobConfigParser.createSinkAction(MultipleTableJobConfigParser.java:690)
at org.apache.seatunnel.engine.core.parse.MultipleTableJobConfigParser.parseSink(MultipleTableJobConfigParser.java:613)
at org.apache.seatunnel.engine.core.parse.MultipleTableJobConfigParser.parse(MultipleTableJobConfigParser.java:260)
at org.apache.seatunnel.engine.client.job.ClientJobExecutionEnvironment.getLogicalDag(ClientJobExecutionEnvironment.java:122)
at org.apache.seatunnel.engine.client.job.ClientJobExecutionEnvironment.execute(ClientJobExecutionEnvironment.java:190)
at org.apache.seatunnel.core.starter.seatunnel.command.ClientExecuteCommand.execute(ClientExecuteCommand.java:204)
... 2 more
Caused by: java.lang.RuntimeException: Plugin PluginIdentifier{engineType='seatunnel', pluginType='sink', pluginName='IoTDB'} not found.
at org.apache.seatunnel.plugin.discovery.AbstractPluginDiscovery.createPluginInstance(AbstractPluginDiscovery.java:270)
at org.apache.seatunnel.plugin.discovery.AbstractPluginDiscovery.createPluginInstance(AbstractPluginDiscovery.java:209)
at org.apache.seatunnel.engine.core.parse.MultipleTableJobConfigParser.lambda$createSinkAction$7(MultipleTableJobConfigParser.java:686)
at org.apache.seatunnel.api.table.factory.FactoryUtil.createAndPrepareSink(FactoryUtil.java:217)
过程分析
启动过程分析:
这个报错的根因很直接:
connector-iotdb这个连接器 jar 根本不在 SeaTunnel 的插件目录里,所以插件发现阶段就找不到名为IoTDB的 Sink Factory。注意它发生在"插件查找"层,还没走到配置校验那一步。
报错分层解读
Plugin PluginIdentifier{engineType='seatunnel', pluginType='sink', pluginName='IoTDB'} not found.
意思是:SeaTunnel 扫描所有已安装连接器后,没有任何一个 jar 能提供 pluginName = "IoTDB" 的 Sink 工厂。这和你之前 Jdbc source 报的 Unable to create a source for identifier 'Jdbc' 是同一类错误——上次修好了 Jdbc,这次 IoTDB 没装。
SeaTunnel 是如何查找指定 Sink 的(排查依据 | 必读)
- 解析配置
sink { IoTDB { ... } }→ 得到pluginName = "IoTDB"、pluginType = "sink"。 - 走
AbstractPluginDiscovery.createPluginInstance(...),构造PluginIdentifier{engineType='seatunnel', pluginType='sink', pluginName='IoTDB'}。 - 扫描插件目录(由配置
plugin_dirs指定,默认connectors),逐个读取目录下 jar 的 SPI 服务文件META-INF/services/org.apache.seatunnel.api.table.factory.Factory。 - 每个连接器 jar 通过
@AutoService(Factory.class)注册自己的工厂,并在factoryIdentifier()里返回名字(如 IoTDBSinkFactory 返回"IoTDB")。 - 匹配到
pluginName→ 实例化工厂进入下一步选项校验;扫完全部 jar 都没人返回 "IoTDB" → 抛Plugin ... not found。
所以"有没有 Sink"取决于:连接器 jar 是否在
plugin_dirs指向的目录里、jar 内 SPI 是否正常。

org.apache.seatunnel.connectors.seatunnel.iotdb.sink.IoTDBSinkFactory
org.apache.seatunnel.connectors.seatunnel.iotdb.source.IoTDBSourceFactory
逐步排查命令
cd $SEATUNNEL_HOME
① 确认 jar 是否在插件目录
确保 iotdb connector 已安装
[root@node1 seatunnel-2.3.13]# ls connectors/ | grep -i iotdb
connector-iotdb-2.3.13.jar
- 有
connector-iotdb-2.3.13.jar→ 跳到第③步(目录可能配错了)。 - 没有 → 装它,走第②步。
② 安装 connector-iotdb
sh bin/install-plugin.sh --plugin connector-iotdb
或手动从 Maven Central 下载 connector-iotdb-2.3.13.jar 拷到 connectors/seatunnel/(注意不是 lib/,连接器 jar 必须放连接器目录)。
SeaTunnel : Connectors V2 : IoTDB = org.apache.seatunnel:connector-iotdb:2.3.13
https://repo.maven.apache.org/maven2/org/apache/seatunnel/connector-iotdb/2.3.13/connector-iotdb-2.3.13.jar
其父工程 = org.apache.seatunnel:seatunnel-connectors-v2:2.3.13
其内置的 iotdb jdbc = org.apache.iotdb:iotdb-session:0.13.1 ,而非:
<dependency>
<groupId>org.apache.iotdb</groupId>
<artifactId>iotdb-jdbc</artifactId>
<version>${iotdb.version=2.0.11}</version>
</dependency>
③ 确认插件目录配置指向
grep -i "plugin_dirs" config/seatunnel-engine.config
# 或
grep -i "plugin_dirs" config/application.yaml
默认值是 connectors,确认你的 jar 确实在这个配置指向的子目录里(通常是 /connectors/)。
④ 重跑
sh bin/seatunnel.sh --config demo-jobs/mysql-to-iotdb_table.conf -m local
提前预警:装完插件后,大概率会撞上第二个错 —— 暂不支持表模型
把 jar 放进去之后,报错会从 "Plugin not found" 变成选项校验失败。因为我们前面核过源码:2.3.13 的 IoTDBSinkFactory.optionRule() 只允许这些项:
- 必填:
node_urls、username、password、key_device - 可选:
key_timestamp、key_measurement_fields、storage_group、batch_size、max_retries等
你的配置里写的 sql_dialect、key_tag_fields、key_attribute_fields 不在允许列表内,选项校验会直接拒绝(类似 The option 'sql_dialect' is not supported)。也就是说:
即使插件装好了,你这段"写 IoTDB 表模型"的配置在 2.3.13 上也跑不通——这正是之前调研结论:2.3.13 的 IoTDB sink 只实现了【树模型】,【表模型】参数是文档先行、代码目前未实现(此刻:2026.10.21)。
- 如果确实要写 IoTDB 表模型,先把 sink 改成【树模型】版跑通链路:
sink {
IoTDB {
node_urls = ["192.168.xxx.xxx:6667"]
username = "root"
password = "root"
storage_group = "root.ods_xxx"
key_device = "vin" # 用 vin 字段当设备 id
key_timestamp = "collect_time"
key_measurement_fields = ["total_mileage","subtotal_mileage","online_status","drive_speed","engine_speed","skylight_status","bms_soc","bms_soh"]
batch_size = 1024
}
}
注意:树模型下
key_device要填行里的字段名(如vin),不是你现在写的固定字符串device_type_vehicle_can_conditions(那在表模型里是表名,但树模型没这个概念)。如果想固定路径前缀,用storage_group配。
需要写表模型的话,再用 JDBC sink 走 IoTDB JDBC 接口自己
CREATE TABLE / INSERT。
Y 推荐文献
X 参考文献
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!

浙公网安备 33010602011771号