先说结论:这个需求我落地过不止一次,而且踩过的坑比想象中多。Kettle(现在更常见的叫法是Pentaho Data Integration,Spoon是它的图形化客户端)本身是一款老牌ETL工具,日常大家用它做数据抽取、转换、加载,连接Oracle、MySQL、SQL Server都很顺手。但一旦碰到达梦数据库,很多人就开始挠头——驱动找不到、URL怎么写都不对、测试连接报错一片红,更别提把达梦直接当成Kettle的资源库来用了。
这篇文章要解决的问题就一个:怎么让Kettle顺顺利利连到达梦数据库,并且把达梦库当成Kettle的资源库(存储转换、作业等元数据)。资源库这个功能对团队协作特别重要,所有人都连同一个资源库,谁改过哪个转换、哪个作业,打开就能看到最新版本,不用天天传文件。如果你正卡在“Kettle连不上达梦”或“用达梦建资源库一直失败”这一步,这篇文章应该能帮你省掉至少两天的排查时间。
我会把整个方案拆成四个部分讲:先用项目视角分析这个需求的本质,再讲清楚驱动插件和资源库的底层原理,然后给出可以直接照抄的完整操作步骤,最后是典型问题排查速查表。每步讲完都会标注我实操过程中觉得最重要的注意事项,这些都是普通教程不会写的东西。
1. 项目概述与方案选型
1.1 这个需求到底在解决什么问题
先说“Kettle连接达梦资源库数据库插件”这句话拆开看是什么。Kettle支持把各种数据库声明成数据源,在“数据库连接”里能看到MySQL、PostgreSQL、Oracle这些常见类型;同时它还支持“资源库”,相当于一个集中存放转换和作业元数据的数据库,所有开发人员共享一套配置。
如果你的公司或项目组要求数据库国产化适配,需要把原本跑在Oracle/MySQL上的Kettle调度全部迁移到达梦平台,那就涉及两件事:
- 让Kettle能连接达梦,也就是把达梦当成普通数据源来读写数据;
- 让Kettle用达梦来存资源库,也就是把达梦当成元数据库来存转换定义、步骤配置、字段映射这些内部信息。
这两件事在Kettle里本质上是同一套机制——都是通过JDBC驱动建立连接。区别只在于“数据源”负责处理业务数据,而“资源库”会在目标库里自动生成一堆Kettle的内部表,用来保存转换、作业、步骤参数等元数据。
很多人会被“插件”两个字带偏,以为要去Kettle官方找专门的达梦插件,或者自己开发一个插件。真实情况是,Kettle连接任何数据库都走JDBC,所谓“插件”其实就是达梦官方提供的JDBC驱动包。只要驱动放对了、连接串写对了,Kettle就可以把它当成一个普通数据库来用。
1.2 为什么选择“驱动+资源库”这套方案
在评估方案时,有人建议用通用数据库连接(Generic Database)来碰运气,也有人建议先手工建好资源库再关联,还有人干脆绕开资源库,让Kettle直接读写文件。我的建议很明确:在Kettle里新建一个达梦驱动类型的数据库连接,再基于这个连接创建资源库,一步到位。
先说为什么不推荐Generic Database。Kettle里确实有一个“Generic database”类型,可以填任意JDBC驱动类名和任意URL,但它有两个问题:第一,很多依赖Kettle内部方言的功能(比如资源库建表、写Clob字段、分页查询)对数据库方言有隐式依赖,Generic的方式很容易在“测试连接”成功之后,建表或保存元数据时报出莫名其妙的错误;第二,Kettle后续升级版本时,Generic方式的兼容性最差,你可能今天还能用,换个小版本就崩了。所以更稳妥的方案是在Kettle的驱动管理里自己定义一个“达梦”类型,把达梦的JDBC驱动类名、URL模板、默认端口都填进去,之后每次建立数据库连接都能直接选到这个类型,一劳永逸。
再说为什么建议用达梦做资源库而不是继续用文件资源库。文件资源库(.ktr/.kjb)在单机开发时没问题,但一旦多人协作,版本覆盖、并发修改、历史回滚都很痛苦。数据库资源库把元数据存在表里,Kettle会自己管理版本,任何一个转换被修改保存后,都能在资源库的版本记录里看到差异。把这个库落在达梦上,等于整个ETL的元数据管理也一起国产化适配了,底层都是达梦的库表,省掉一套额外维护的中间件。
2. 准备工作与核心原理
2.1 你需要的软件和驱动清单
开始操作前先把材料备齐,我列一下我实际用过并且确认没问题的版本组合:
- Kettle版本:8.3.x / 9.x 都行,推荐9.x及以上,JDK8环境即可,JDK11也可以跑新版
- 达梦数据库:DM8(8.1及以上版本均可),安装到能正常使用SYSDBA登录
- 达梦JDBC驱动:DmJdbcDriver18.jar(DM8配套)
- Kettle安装目录:比如
/opt/data-integration或D:\data-integration,下文统称KETTLE_HOME
这步最容易被忽略的是驱动版本。DM8的驱动通常自带在达梦数据库安装目录的drivers/jdbc下面,也可以直接在某台已经装了达梦客户端的机器上找DmJdbcDriver18.jar。如果拿错成旧版Dm7JdbcDriver16.jar,连DM8一般也能连上,但偶尔会在资源库建表时踩到字符集或timestamp兼容问题。所以能用18就用18。
还有一个细节:Kettle的lib目录里已经有大量的jar包,不要把达梦驱动随便扔到KETTLE_HOME/system下的某个子目录,要明确放到KETTLE_HOME/lib这个主类加载目录里。注意不同版本Kettle的lib目录位置略有差异(比如从9.3开始部分平台改成了lib根目录统一管理),但绝大多数情况下放KETTLE_HOME/lib就对了。
2.2 JDBC插件的原理:Kettle是怎么认出达梦的
Kettle之所以能连这么多数据库,核心是JDBC这套Java标准接口。数据库厂商只要提供实现了java.sql.Driver接口的jar包,任何Java程序都能通过统一的接口去连接它。Kettle做的事情,就是把这个jar包放到类加载路径里,然后在界面里维护一个“数据库类型”和“驱动类名”的映射关系。
达梦的驱动类名是dm.jdbc.driver.DmDriver,连接URL模板是jdbc:dm://{HOST}:{PORT}。默认端口5236,默认用户名/密码一般是SYSDBA/你在安装时设置的口令。这里要特别注意,jdbc:dm是达梦自己注册的JDBC子协议,跟MySQL的jdbc:mysql一样,由达梦驱动自己识别。如果你从网上随手找一个“通用JDBC连接串”把dm换成别的,那一定连不上。
Kettle在“数据库连接”里新建连接时,下拉框里默认看不到达梦类型。这是因为Kettle把数据库类型定义在KETTLE_HOME/plugins/databases下的各个子目录里,默认只带了Oracle、MySQL、PostgreSQL这些常见类型。没有达梦目录没关系,我们用Kettle自带的“驱动管理”功能,手动登记一个自定义数据库类型,把驱动类名、URL模板、端口这些信息填上,Kettle就会在下拉框里多出一个“达梦”选项。
所以在动手之前,脑子里要建立一个模型:Kettle连接达梦 = JDBC驱动包 + 数据库类型定义 + URL/账号密码。三者缺一不可。资源库创建则是在这个连接基础上,让Kettle自动执行一系列建表DDL,把元数据模型落到达梦的物理表里。
3. 实操:让Kettle先连上达梦数据源
3.1 安装/添加达梦JDBC驱动
驱动安装这一步没有太多技巧,但至少要做对路径。关闭Spoon,把DmJdbcDriver18.jar复制到KETTLE_HOME/lib目录下。建议复制前先检查这个目录里有没有旧版本的Dm7JdbcDriver16.jar或重名的DmJdbcDriver18.jar,有的话先删掉再放新的,避免类冲突。
驱动放好后,还要确认权限。Linux环境下尤其容易踩这个坑:你当前用户对lib目录没有写权限,驱动虽然复制进去了,但启动Spoon的进程读不到。我习惯用ls -l DmJdbcDriver18.jar确认文件归属,然后用chmod 644给它只读权限就够,没必要给777。
在Windows下复制驱动后,如果Spoon已经开着,一定要重启。不要只关转换再重开,Kettle的类加载器在启动时就扫了一遍lib目录,运行中往lib里丢jar是不生效的。这是很多人放完驱动后测试连接依然报Driver class not found的最常见原因。
3.2 新建数据库连接并定义驱动
重启Spoon之后,进入主界面。点击左侧“主对象树”窗口,找到“转换”节点,右键新建一个转换,然后看顶部工具栏或左侧“视图”的“数据库连接”面板,点击“新建”。
连接类型的下拉列表里这时候大概率还是没有达梦。我们需要先到Kettle的驱动管理器里登记一下。操作路径是:
- 点击菜单
工具→数据库→驱动 - 在“自定义驱动类”面板里点“新建”
- 填写驱动名称、驱动类名、默认端口、URL模板
我常用的填写示例:
| 参数名 | 填写内容 |
|---|---|
| 驱动名称 | dimeng(随便写,建议跟品牌一致) |
| 驱动类名 | dm.jdbc.driver.DmDriver |
| 默认端口 | 5236 |
| URL模板 | jdbc:dm://{HOST}:{PORT}/{DBNAME} |
注意URL模板里的{HOST}、{PORT}、{DBNAME}是Kettle约定的占位符,不能随意换名字。DBNAME对应达梦数据库名,不是用户名,通常安装时创建的是DAMENG或者你建库时自定义的名字。如果只填IP和端口不填库名,默认会连到SYSDBA库,这在连接普通数据源时也能用,但配置资源库时最好填上明确的库名。
3.3 测试连接与参数核对
驱动定义完成并保存后,回到“新建数据库连接”对话框,下拉选择刚才定义的达梦类型,填写以下内容:
- 主机名称:达梦数据库所在IP
- 数据库名称:实际库名,比如DAMENG
- 端口号:5236
- 用户名:SYSDBA
- 密码:安装时设置的口令
填完点“测试”,正常情况会弹出“连接成功”的提示。如果失败,先不要急着怀疑驱动,先检查网络和端口。在命令行执行telnet [IP] 5236(Windows自带telnet不一定开启,可以用Test-NetConnection或nc命令),确认达梦端口能从当前机器访问到。
另外,如果达梦数据库开启了SSL或者限制IP白名单,测试连接也会失败,这种通常在达梦的dm.ini或会话参数里配置,需要DBA配合排查。
连接成功之后,还可以顺手验证一下元数据读取能力:点“浏览”或直接看“连接”的高级选项,能列出达梦的表列表,才说明驱动和数据源都没问题。这一步验证很关键,因为等下创建资源库时,Kettle还会再用同一套连接去自动建表,如果连表列表都读不出来,资源库必然建不成。
4. 配置达梦资源库
4.1 创建资源库之前要想清楚的事
资源库本质上是Kettle用来描述“转换、作业、步骤、连线、字段映射”的元数据库。Kettle支持把资源库放在多种数据库里,默认的表结构由Kettle在创建时自动生成。用达梦做资源库之前,有两个决策点要先确认。
第一,资源库要建在哪个库下。资源库里会有几十张内部表,比如R_TRANSFORMATION、R_JOB、R_STEP、R_FIELD等,这些表与业务数据无关,纯粹是Kettle自己用的。建议单独建一个用户或单独建一个schema,不要让资源库表和业务表混在一起。达梦里创建用户时默认会创建同名schema,例如创建一个用户KETTLE_REPO,则它的默认schema就叫KETTLE_REPO,这样在权限上也隔离得很干净。
第二,谁来访问资源库。团队成员连接资源库时用的账号,建议只授予资源库那几个表所在的schema的读写权限,不要默认给SYSDBA。虽然开发期图省事用SYSDBA很正常,但上线后维护和审计会比较难受。合理的做法是建一个最小权限账号,只让它对资源库schema有增删改查权限。
4.2 新建资源库的具体步骤
准备工作做完,就可以创建资源库了。操作路径如下:
- 在Spoon主界面左侧,找到“资源库”面板(如果没有,菜单
工具→资源库→连接到资源库) - 资源库管理窗口里选择“创建一个新的资源库”,类型选择“数据库仓库”
- 在“选择数据库连接”界面,点“新建”,按第3步的方式配置达梦连接
- 连接测试成功后,选择这个达梦连接,点击确定
- Kettle会提示“将在指定数据库中创建资源库表”,确认后开始建表
整个建表过程通常几十秒。如果达梦库性能不错,一闪而过。如果建表失败,不要反复点创建,先看第4.3节的排查思路。
资源库创建完成后,默认会弹出一个登录窗口,输入账号密码就能连上。登录后看Spoon的左侧面板,会变成资源库视图,原来的转换/作业节点会变成从数据库中读出来的元数据。此时进入开发模式,新建的转换会直接保存到达梦库中。
4.3 资源库建表失败的处理思路
建表失败是我见到最多的情况,代码报错五花八门。最常见的三种原因:
一是权限不够。Kettle自动建表时涉及CREATE TABLE、CREATE INDEX、ALTER TABLE等DDL权限,如果你的数据库账号只有DML权限,那建表一定失败。解决方向很清晰:建表期间用一个有DDL权限的高权限账号(比如SYSDBA)来创建资源库,建完后如果出于安全考虑要切换到低权限账号,再把DML权限授给它。
二是字段长度或类型兼容。Kettle内部表里有一些大字段,比如存储转换XML内容的R_TRANSFORMATION表里有CLOB类型字段。达梦对CLOB的支持没问题,但如果你在初始化时选择了错误的字符集(比如UTF-8和GBK混乱),可能在插入中文注释时出问题。尽量保证达梦初始化时使用UTF-8,并且JDBC连接URL里带上?compatibleMode=oracle这类参数不必要,保持默认即可,别乱加参数。
三是Kettle与驱动版本不兼容。如果DmJdbcDriver18.jar版本太旧,Kettle在用DatabaseMeta获取元数据时可能拿不到正确的表名或字段列表,从而生成非法的DDL。建议去达梦官网下载最新的DmJdbcDriver18.jar,替换后重新建。
如果你已经把资源库建了一半,报错中止了,不能直接再用同一个库名重新创建,数据库里会残留半张表或已建好的部分表。这种情况要么清理掉残留表再重建,要么换一个schema/库名再创建。清理残留表时,可以查USER_TABLES把Kettle以R_开头的内部表都删掉,注意只删这个schema里的,别误删业务表。
5. 用实际跑一次验证效果
5.1 搭建一个达梦到文件的抽取转换
资源库配置好之后,所有新建的转换都会存到达梦库里。我建议你立刻做一个小转换来验证“连接达梦数据源 + 资源库存储”两条链路都正常。最稳妥的验证方式是做一个“表输入 - 文本文件输出”的流程。
具体步骤:
- 在资源库视图下,右键“转换”节点,新建一个转换,命名为
DM_TEST_001 - 拖入“表输入”步骤,双击打开,选择刚才用的达梦连接
- 在SQL框里输入
SELECT 1 AS TEST_COL FROM dual。注意:达梦兼容Oracle模式时支持dual;如果你不确定你的库是什么模式,可以直接查一张真实表,比如SELECT COUNT(*) AS CNT FROM SYSDBA.TEST_TABLE,前提是你有该表权限 - 测试这个“表输入”,能看到结果集,说明达梦数据源完全正常
- 拖入“文本文件输出”步骤,连接到表输入的输出
- 文本文件输出配置一个本地路径,比如
/tmp/dm_test_result.txt - 点击转换右上角的“运行”按钮,选择“本地执行”
运行结束后,检查/tmp/dm_test_result.txt的内容,能看到1或查到的计数,就说明整条链路跑通了。
这个验证过程不需要很复杂,目的只在于用最小工作量确认三件事:第一,JDCB驱动在运行态正常;第二,SQL和连接串都正确;第三,转换能保存资源库并正常执行。很多项目在“测试连接”能过、实际跑的时候才报错,就是因为驱动在运行态加载和设计态加载的时机不一样。轻量测试能提前暴露问题。
5.2 运行日志与正常输出长什么样
跑通的小转换,日志大概长这样:
- 执行开始后,日志面板出现
Starting to run... - 然后是
Table input.0 - Finished processing (I=0, O=0, R=1)之类的一行,说明表输入读到了1行 - 文本文件输出步骤会有写入成功的提示,最后是
Finished.或者Transformation complete
如果看到这些输出,就能很笃定地说Kettle和达梦的连接是健康的。如果这步都没跑通,那问题大概率还是出在连接配置层面,和后续的资源库无关。所以我的建议是一个环节一个环节排查,不要带着连接配置问题去建资源库,那样只会叠加更多错误。
6. 常见问题与排查心得
6.1 高频报错速查表
我整理了工作中最常遇到的几类问题,直接对照着看:
| 报错现象 | 可能原因 | 解决办法 |
|---|---|---|
找不到类dm.jdbc.driver.DmDriver | 驱动jar没放对位置或没重启 | 确认jar在KETTLE_HOME/lib,重启Spoon |
| 连接超时 / 网络不可达 | 端口未开或IP限制 | 用telnet/nc测5236端口,检查防火墙白名单 |
| 驱动版本太旧导致兼容错误 | DmJdbcDriver版本低 | 换成最新的DmJdbcDriver18.jar |
| 建资源库表失败,提示无权限 | 账号缺少DDL权限 | 先用SYSDBA或高权限账号创建资源库 |
| 表名/列名找不到 | schema不对 | 在表名前加schema前缀,如KETTLE_REPO.R_TRANSFORMATION |
| 中文写入乱码 | 字符集不一致 | 达梦初始化用UTF-8,连接串不加乱参数 |
| 转换存不进资源库 | 资源库登录态失效 | 重新连接资源库,检查资源库账号密码 |
| 执行时报“表或视图不存在” | 数据源schema和登录用户不一致 | 在表输入SQL里显式指定schema |
为了方便排查,我强烈建议在Kettle日志级别里把“基本日志”改成“详细日志”。路径在运行对话框的“日志级别”下拉框里。详细日志会打印每一条JDBC错误的堆栈,很多问题马上就能定位。平时跑批用基本日志,排查问题先开详细日志,这个习惯能帮你省大量时间。
6.2 几个容易被忽略的细节
我再分享几个没写在官方文档里的经验。
第一个是URL里要不要带库名。有些人在通用驱动里填URL只写jdbc:dm://IP:5236,不写库名,结果连接成功,但看到的是默认库的表。如果后续在资源库里保存转换找不到预期的表,先检查URL是不是漏了库名。我的习惯是始终写完整的jdbc:dm://IP:5236/DAMENG,让每个连接对象都指向明确的库。
第二个是达梦大小写敏感问题。达梦在Linux上安装时,如果初始化参数设置了大小写敏感,表名会被转成大写存储。如果建资源库时的表名和Kettle内部查询表名用的字符串大小写不一致,可能会导致查不到元数据。解决办法是SQL里统一使用大写表名,或者连接串里加?CaseSensitive=0,但这个参数会影响全库行为,必须在建库阶段就规划好,不要在执行阶段乱加。
第三个是连接池参数。Kettle本身默认不使用外部连接池,但如果你在JDBC连接串里看到了类似?maximumPoolSize=10这类池参数,基本是照搬了别的项目配置。达梦的JDBC驱动对这些参数不一定都认,无效参数有时会被直接忽略,有时会报错。我个人经验是:Kettle连接达梦时URL保持最简格式最稳,连接性能问题交给Kettle的“连接池”选项卡来控制,不要在JDBC串里手动拼一堆池参数。
第四个是关于资源库的备份。达梦资源库里的元数据变更很频繁,一旦误删了一个转换,资源库版本记录也不一定能救回来。我建议每天对资源库里Kettle相关的表做一次逻辑备份,比如用达梦的dexp工具导出整个schema,放到独立的备份目录。这个操作不复杂,但遇到突发情况时能救命。
还有一个经验是版本管理。团队开发时,资源库虽然解决了“多人共用”的问题,但Kettle转换在资源库里的diff其实不好看,重要转换仍然建议定期把.ktr/.kjb文件导出版本备份。数据库资源库不是唯一的元数据管理方式,很多时候我反而建议“数据库资源库 + 文件快照”双保险。毕竟Kettle转换文件本身是XML,放到版本控制工具里做diff和回溯都方便,而资源库更适合日常多人协作开发。
结语
做Kettle对接达梦这件事,真正动手之后会发现,核心其实就三件事:驱动放对、连接配好、资源库建对。原理不复杂,难的是各种细节和环境差异。希望这篇基于实操经验的踩坑记录,能让你少走一些弯路。尤其最后再强调一次:驱动版本一定要用新的、资源库建表账号权限一定要够、URL一定要写清楚库名。把这三点做到位,百分之八十的问题都能提前避免。剩下那百分之二十,打开详细日志,逐行看报错,基本都能找到答案。我在实际项目中,从第一台测试环境到达梦资源库稳定运行,大概花了一个下午,其中一半时间都耗在定位驱动版本上。你如果照着这篇来操作,应该比我快很多。