`
chenshangge
  • 浏览: 87721 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类

记一次kettle6升级kettle8引发的内存溢出

 
阅读更多

起因

基于一些原因,需要将kettle6.1升级到新版的kettle8.2。升级后发现kettle8每隔几天出现

GC overhead limit exceeded 或者 OutOfMemoryError:Java heap space;

一开始猜测kettle8为了提高性能,而牺牲更多的堆内存,便从开始的Xmx2048m 增加到 Xmx4096m.

可是没过几天还是一样出现问题,又从4096m增加到6144m.

问题依旧得不到解决.

 

通过排查日志发现内存溢出的问题发现: 定时重复执行的作业出现数据库连接不上,

导致好几天的作业一直都在报错数据库连接拒绝,一直到内存溢出,kettle奔溃.

排查发现,只要作业是正常执行,kettle8.2就不会出现内存溢出的问题.

但是只要有作业一直报异常,那么只要1-2天(也可能更短,看作业执行频率),

kettle8.2就会内存溢出挂掉,

kettle6.1不会出现此种情况.

 

场景重现

测试环境部署kettle8.2,模拟重现.

在kettle8.2 启动脚本增加 

-Dcom.sun.management.jmxremote.port=9008 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false

本地jconsole可以远程实时监控kettle运行时的内存与线程情况

增加

-Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n

本地idea可以远程debug

 

在idea中git clone kettle8.2的源码.

 

往kettle上发了10个作业,每隔5秒重复执行.其中9个作业是正常执行的,

1个作业连接一个不存在的数据库,会一直报连接拒绝错误

jconsole监控如下图



 

红框时间区间是该错误job停用的时间段,期间内存能维持稳定。
在测试服务器上使用命令jmap -heap,发现老年代内存居高不下,无法回收。

 

排查

 

再使用命令jmap -histo:live >> a.log(JVM会先触发gc)排查哪些对象没有被回收

 

           327          83712  org.pentaho.di.trans.Trans

           327          20928  org.pentaho.di.trans.steps.selectvalues.SelectValuesMeta

           327          20928  org.pentaho.di.trans.steps.tableinput.TableInputMeta

           327          31392  org.pentaho.di.trans.steps.insertupdate.InsertUpdateMeta

           866          27712  org.pentaho.di.trans.TransHopMeta

 

基本上可以断定是每次错误执行的作业中的转换(trans)没有被GC回收。

但是仅根据堆内存中的对象数量无法判断是哪里还在引用这些对象。

 

使用命令 jmap -dump:live,format=b,file=./dump.dat 生成内存镜像

使用命令 jhat -J-Xmx1024M ./dump.dat (jdk自带分析工具)

执行后等待console 中输入start HTTP server on port 7000 即可使用浏览器访问 IP:7000

 



随机查看了几个引用trans对象的对象,看不出什么

kettle的对象互相引用太多太复杂,jhat这个工具很难直观找到最上层的引用对象

 

下载dump文件到本机,使用eclipse的插件 memory anaylize 分析dump

如下图


在树形图上容易trans对象没有被回收是因为被最上层的HashMap引用

 

在树形图中找到容易定位问题代码对象是

org.pentaho.osgi.blueprint.collection.utils.ServiceMap

查看源码,猜测作业执行异常的情况,没有执行itemRemoved方法,导致本该被回收的对象在内存越积越多

在源码中新增、修改两个方法打上断点,开启远程debug 如下图

 

调试一个正常的作业和错误的作业,发现确实如推测的,执行报错的作业最终没有执行itemRemoved.

调试过程跳过

定位具体代码 org.pentaho.di.trans.Trans

 

  public void execute( String[] arguments ) throws KettleException {
    prepareExecution( arguments );
    startThreads();
  }

 

 正常执行的job 会在 prepareExecution方法中的transMeta.setEmbeddedMetastoreProviderKey(....)

中调用serviceMap的itemAdded()

并在startThreads()方法中的transMeta.disposeEmbeddedMetastoreProvider()中

调用serviceMap的itemRemoved()

 

异常的job会在prepareExecution方法中初始化step时抛出数据库连接异常,导致后续不会进入到startThreads().

 

这下内存溢出的问题明确了,稍微修改源码,打包替换原先的kettle-engine.8.2.0.jar.

至此,kettle8.2内存泄漏问题彻底解决

后续

1、对比kettle6和kettle8的源码,发现了 EmbeddedMetastoreProvider   
   是kettle8新增的一个点,所以kettle6此场景不存在内存泄漏
2、测试过kettle8.3,也存在与8.2一样的内存泄漏问题.

 

 

 

 

 

 

  • 大小: 3.9 KB
  • 大小: 38.4 KB
  • 大小: 473.9 KB
  • 大小: 77.8 KB
分享到:
评论

相关推荐

    kettle内存溢出(Java heap space)以及解决方法.docx

    1. **大数据量处理**:当Kettle处理大量数据时,如在表输入、表输出、聚合、Join、过滤等步骤中,如果一次性加载太多数据到内存,可能会超出JVM的堆内存限制。 2. **内存管理不当**:Kettle的默认配置可能不适合特定...

    Kettle实现步骤循环执行

    Kettle是一款开源的数据集成工具,也被称为Pentaho Data Integration(PDI),它提供了强大的ETL能力。本文将深入探讨如何在Kettle中实现步骤的循环执行,以满足重复处理数据的需求。 标题"Kettle实现步骤循环执行...

    Kettle生成1亿条数据导入oracle

    在这个项目中,Kettle被用来生成一亿条信用卡号模拟数据,并将这些数据成功地导入到Oracle数据库中,同时避免了常见的内存溢出问题。 【描述】提到的"生成了一亿条信用证卡号"展示了Kettle在生成测试数据方面的强大...

    Kettle循环遍历结果集.zip

    需要注意的是,处理大量数据时,应合理优化SQL查询,避免内存溢出,同时监控Job和Transformation的性能,以确保高效运行。 通过深入理解Kettle的Job和Transformation之间的数据交互机制,以及如何使用"作业循环...

    kettle动态分页与循环抽取大数据

    在大数据环境中,一次性加载所有数据通常是不可行的,因为它可能导致内存溢出或系统性能下降。动态分页允许我们按需逐页处理数据,减少一次性处理的数据量。在Kettle中,这可以通过创建一个工作流或者转换来实现,...

    java集成kettle执行作业文件.rar

    同时,合理配置Kettle的内存使用,避免内存溢出。 综上,Java集成Kettle执行作业文件是利用Kettle的强大ETL能力,结合Java的灵活性和控制力,实现数据处理任务的自动化执行。通过这种方式,可以构建复杂的数据管道...

    kettle定时调度监控方案选型策略

    在测试并行作业时,可能会出现内存溢出错误,甚至会出现资源消耗过大导致系统不稳定的现象。深入研究发现,pan和kitchen在执行过程中会不断初始化Kettle环境,这不仅耗时也消耗大量资源。 最后,通过Java代码直接...

    kettle优化

    - **数据分块**:对于大数据量,可以考虑分块处理,每次处理一部分数据,避免一次性加载大量数据导致内存溢出。 - **性能监控**:通过日志和性能监控工具跟踪Kettle作业运行情况,找出瓶颈并进行优化。 综上所述,...

    kettle常见控件(输入、输出,字段选择、设置变量、记录集连接、值映射、字符串替换、js、Java)的使用案例

    在实际使用过程中,可能会遇到一些常见问题,例如连接配置错误、SQL语法错误、内存溢出等。因此,了解Kettle的错误日志和调试机制至关重要,以便快速定位并解决问题。同时,配合SQL脚本和预定义的工作流文件(kjb、...

    kettle使用问题处理汇总整理.rar

    Kettle,又称Pentaho Data Integration(PDI),是一款强大的ETL(Extract, Transform, Load)工具,广泛应用于数据仓库和大数据处理项目中。它提供了图形化的界面,使得数据抽取、转换和加载过程变得直观易懂,非常...

    基于Kettle工具的企业级数据同步方案

    2. **OOM问题**:大量数据可能导致内存溢出。可以通过调整Kettle的工作线程、增加内存分配或优化数据处理策略来防止。 3. **数据同步遗漏**:定时轮询策略可能错过实时数据。为解决这个问题,可以调整轮询间隔,或者...

    Kettle初步的练习说明--入门级

    - 若遇到栈溢出错误(StackOverFlowError),可添加`-Xss`参数并根据本机内存配置进行适当调整。 #### 五、KETTLE_HOME环境变量设置 - **作用**:`.kettle`文件夹用于存储Kettle的各种配置文件,默认位于C盘用户...

    关于Java中内存溢出的解决办法

    关于Java中内存溢出的解决办法 关于Java中内存溢出的解决办法

    ETL工具-kettle的探索

    - 修改Spoon.bat配置,防止内存溢出和编码问题。 - 运行Spoon.bat启动工具,利用转换和作业功能构建数据流。 - 表输入和输出节点用于读写数据,配置数据库连接,根据需求编写SQL或设置字段映射。 2. Linux环境下...

    java大数据案例_6Hive、Kettle

    ### Java大数据案例_6Hive、Kettle #### 安装部署Hive **知识点概述:** 本案例涉及的关键技术包括Hive的安装与配置、Hive的基本操作以及Hive与MapReduce的集成使用。Hive是一种数据仓库工具,可以方便地对存储在...

    处理大数据量excel

    1. **读取Excel**:使用Apache POI等库读取Excel文件,可以逐行或按需加载数据,避免一次性加载整个文件导致内存溢出。 2. **预处理数据**:在读取数据后,可能需要进行数据清洗、格式转换等预处理步骤,以符合...

    Java堆内存又溢出了!教你一招必杀技(推荐)

    在Java 8之前的版本,这部分内存被称为永久代,容易因类数量过多而引发内存溢出。而元空间使用本地内存,通过MetaspaceSize和MaxMetaspaceSize两个参数来控制其大小,从而解决了永久代可能导致的溢出问题。 Java的...

    kettle 转换控件翻译.txt

    从给定的文件信息来看,主要涉及的是Kettle这一数据集成工具中的转换控件及其功能。Kettle,也称为Pentaho Data Integration (PDI),是开源数据集成平台的一部分,用于执行ETL(Extract, Transform, Load)操作,即...

Global site tag (gtag.js) - Google Analytics