-
Kettle运行作业之前的初始化过程
本文主要描述Kettle是如何通过GUI调用代码启动线程执行作业的。
之前用英文写了一篇文章《The execution process of kettle’s job》 ,这篇文章只是用于英语写技术博客的一个尝试。由于很久没有使用英语写作了,故那篇文章只是简单的通过UML的序列图描述kettle运行job的一个java类调用过程。将上篇文章的序列图和这篇文章联系起来,会更加容易理解本文。
在Spoon界面点击运行按钮,Spoon GUI会调用Spoon.runFile()方法,这可以从xul文件(ui/menubar.xul)中的描述看出来。关于kettle中的xul的使用,不是本文重点故不在此说明。
public void runFile() { executeFile(true, false, false, false, false, null, false); } public void executeFile(boolean local, boolean remote, boolean cluster, boolean preview, boolean debug, Date replayDate, boolean safe) { TransMeta transMeta = getActiveTransformation(); if (transMeta != null) executeTransformation(transMeta, local, remote, cluster, preview, debug, replayDate, safe); JobMeta jobMeta = getActiveJob(); if (jobMeta != null) executeJob(jobMeta, local, remote, replayDate, safe, null, 0); } public void executeJob(JobMeta jobMeta, boolean local, boolean remote, Date replayDate, boolean safe, String startCopyName, int startCopyNr) { try { delegates.jobs.executeJob(jobMeta, local, remote, replayDate, safe, startCopyName, startCopyNr); } catch (Exception e) { new ErrorDialog(shell, "Execute job", "There was an error during job execution", e); } }
runFile()方法内部调用executeFile()方法,executeFile方法有以下几个参数:
local:是否本地运行
remote:是否远程运行
cluster:是否集群环境运行
preview:是否预览
debug:是否调试
replayDate:回放时间
safe:是否安全模式executeFile方法会先获取当前激活的转换,如果获取结果不为空,则执行该转换;否则获取当前激活的作业,执行该作业。 本文主要讨论作业的执行过程,关于转换的执行过程,之后单独一篇文章进行讨论。
executeJob委托SpoonJobDelegate执行其内部的executeJob方法,注意,其将JobMeta传递给了executeJob方法。SpoonJobDelegate还保存着对Spoon的引用。
SpoonJobDelegate的executeJob方法主要完成以下操作:
1.设置Spoon的执行配置JobExecutionConfiguration类,该类设置变量、仓库、是否执行安全模式、日志等级等等。
2.获得当前Job对应的图形类JobGraph。
3.将执行配置类JobExecutionConfiguration的变量、参数、命令行参数设置给jobMeta。
4.如果本地执行,则调用jobGraph.startJob(executionConfiguration),如果远程执行,则委托给SpoonSlaveDelegate执行。JobExecutionConfiguration类是保存job执行过程中的一些配置,该类会在Spoon、JobGraph类之间传递。
本文只讨论本地执行的情况,故往下查看jobGraph.startJob(executionConfiguration)方法。该方法被synchronized关键字修饰。
JobGraph类包含当前Spoon类的引用、以及对Job的引用。初始情况,Job的引用应该为null。该类会做以下操作:
1.如果job为空或者没有运行或者没有激活,则先保存,然后往下执行作业。
2.在仓库不为空的时候,通过仓库加载Job获得一个运行时的JobMeta对象,名称为runJobMeta;否则,通过文件名称直接new一个JobMeta对象,名称也为runJobMeta。
3.通过仓库和runJobMeta对象构建一个Job对象,并将jobMeta对象(此对象通过JobGraph构造方法传入)的变量、参数共享给Job对象。
4.Job对象添加JobEntry监听器、Job监听器。
5.调用Job的start方法,启动线程开始执行一个job。Job继承自Thread类,该类的run方法内部会递归执行该作业内部的作业项,限于篇幅,本文不做深究。
一条评论 -
The execution process of kettle’s job
How to execute a kettle job in Spoon GUI or command line after we create a job in Spoon GUI? In Spoon GUI,the main class is “org.pentaho.di.ui.spoon.Spoon.java”.This class handles the main window of the Spoon graphical transformation editor.Many operations about a job or transformation such as run,debug,preview,zoomIn,etc,are all in this class.This post just writes about the code execution process.
When we start a job or transformation,Spoon invokes the method runFile(),and then is distributed to executeTransformation() or executeJob().At now,we mainly study about executeJob() method.
This is a simple sequence diagram below.It contains several classes for Starting to execute a job using execute(int nr, Result result) in Job.java.We can see the relation of these classes from it.
What is the detail process of job execution? You should look into the Job.run() method for detail information.
-
kettle中定义错误处理
在kettle执行的过程中,如果遇到错误,kettle会停止运行。在某些时候,并不希望kettle停止运行,这时候可以使用错误处理(Step Error Handling)。错误处理允许你配置一个步骤来取代出现错误时停止运行一个转换,出现错误的记录行将会传递给另一个步骤。在Step error handling settings对话框里,需要设置启用错误处理。
下面例子中读取postgres数据库中的a0表数据,然后输出到a1表:
a1表结构如下:
CREATE TABLE a1 ( a double precision, id integer NOT NULL, CONSTRAINT id_pk PRIMARY KEY (id ), CONSTRAINT id_unin UNIQUE (id ) )
从表结构可以看出,a1表中id为主键、唯一。
Read More » -
使用kettle数据迁移添加主键和索引
Kettle是一款国外开源的etl工具,纯java编写,绿色无需安装,主要用于数据抽取、转换、装载。kettle兼容了市面上几十种数据库,故用kettle来做数据库的迁移视乎是个不错的选择。
kettle的数据抽取主要在于抽取数据,而没有考虑数据库的函数、存储过程、视图、表结构以及索引、约束等等,而这些东西恰恰都是数据迁移需要考虑的事情。当然,如果在不考虑数据库中的函数、存储过程、视图的情况下,使用kettle进行数据的迁移还算是一个可行的方案。
这篇文章主要是讲述在使用kettle进行数据库的迁移的时候如何迁移主键和索引,为什么要迁移主键和索引?异构数据库之间的迁移很难无缝的实现自定义函数、存储过程、视图、表结构、索引、约束以及数据的迁移,所以多数情况下只需要异构数据库之间类型兼容、数据一致就可以了。但是在有些情况下需要对输出表进行查询以及数据比对的时候,需要有主键和索引方便对比和加快查询速度。
先来看看kettle中的一些组件。
下图是kettle中的一个表输出组件。
在该组件里可以指定表名、字段等信息,并且还可以建表的sql语句。打开建表的sql语句,你可以看到该语句里只指定了字段名称和类型,没有指定主外键、约束、和索引。显然,该组件只是完成了数据的输出并没有将表的主键迁移过去。
Read More » -
kettle进行数据迁移遇到的问题
使用kettle进行oracle或db2数据导入到mysql或postgres数据库过程中遇到以下问题,以下只是一个简单描述,详细的说明以及所做的代码修改没有提及。下面所提到的最新的pdi程序是我修改kettle源码并编译之后的版本。
1. 同时运行两个pdi程序,例如:一个为oracle到mysql,另一个为oracle到postgres,其中一个停止运行
原因:从oracle迁移到mysql创建的作业和转换文件和oracle到postgres的作业和转换保存到一个路径,导致同名称的转换相互之间被覆盖,故在运行时候会出现混乱。
解决办法:将新建的作业和转换分别保存在两个不同的路径,最好是新建两个不同路径的仓库,关于如何新建仓库,请参考《kettle使用说明》文档。2. 关键字的问题。Oracle初始化到mysql,关键字前面会加上前缀“MY_”。如果在建表的时候出现错误,则需要检查表的字段中是否有关键字。
解决办法:出差的表单独进行处理,新建一个转换,实现关键字段该名称然后初始化出错的表。具体操作参见文档。oracle中的字段名从中可以有#号,但是到mysql会报错
解决办法:字段改名称,去掉#号3. Db2初始化到mysql或是postgres出错
原因:1)db2数据库连接用户没有权限访问出错的表;2)出错的表名存在小写字母
解决办法:使用更新后的pdi程序,更新后的程序会将db2的表名使用双引号括起来。4. Oracle到mysql和pg时日期类型数据值有偏差
原因:从oracle中读取日期类型的数据时候,读取结果与oracle数据库中的数据已经存在偏差。少数记录使用oracle10g的驱动读取数据少一个小时,用oracle11g的驱动会多一个小时,该问题尚待oracle工程师给出解决方案。5. 主键从ORACLE导入不到MYSQL和POSTGRES
原因:pdi程序中没有对主键进行处理
解决办法:使用更新的pdi程序,执行Tools-Wizzard-Copy Tables Extension…功能添加主键;执行Tools-Wizzard-Copy Tables Data Only…功能可以只复制数据6. Oracle中存在ascii字符导入到postgres时候报错:ERROR: invalid byte sequence for encoding “UTF8″: 0×00
原因:PostgreSQL内部采用C语言风格的字符串(以0×00)表示结尾,因而不允许字符串中包括0×00,建议在转换时先对字符串类型的数据进行清洗,也就是增加一个节点用于删除字符串数据中的特殊字符0×00。
解决办法:使用新的pdi程序。
在kettle的DataBase类中修改PreparedStatement.setString(int index,String value)方法传入的参数,将value的值trim之后在setString7. 异构数据库之间的类型兼容问题。日期类型和时间类型的数据初始化到mysql或postgres中都为时间类型的数据,导致数据对比时候数据不一致。
原因:Pdi程序中的类型转换采用的是向上兼容的方式,故日期和时间类型都转换为时间类型数据。
解决办法:针对与db2数据初始化到mysql和postgres,该问题在最新的pdi程序中已经处理。因为oracle中的日期类型字段既可以存日期又可以存时间,故没针对oracle数据做出处理。8. Db2中没有主键的数据初始化到mysql和postgres需要添加索引
解决办法:使用最新的pdi程序,最新的pdi程序会添加主键和索引。9. Db2中decimal(n,m)类型的数据初始化到postgres数据库被四舍五入。
原因:Db2中decimal(n,m)类型的数据初始化到postgres中的类型不对。
解决办法:使用最新的pdi程序。10. 导数据中途时没有报错,直接软件退出
原因:1)jvm内存溢出,需要修改jvm参数;2)pdi程序报swt错误
解决办法:修改jvm参数11.初次使用kettle做db2的初始化会报错
原因:kettle中的db2的jdbc驱动与使用的db2版本不对应。
解决办法:从db2的安装目录下拷贝jdbc驱动到kettle目录(libext/JDBC)下 -
Mondrian and OLAP
Mondrian是一个用Java编写的OLAP引擎。他执行用MDX语言编写的查询,从关系数据库(RDBMS)中读取数据并且通过Java API以多维度的格式展示查询结果。
Online Analytical Processing
联机分析处理(OLAP)指在线实时的分析大量数据。与联机事务处理系统(On-Line Transaction Processing,简称OLTP)不同,OLTP中典型的操作如读和修改单个的少量的记录,而OLAP批量处理数据并且所有操作都是只读的。“online”意味着即使是处理大量的数据—-百万条数据记录,占有几个GB内存—-系统必须足够快的反回查询结果以允许数据的交互式响应。正如我们将看到,数据展示面临相当大的技术挑战。 OLAP引入了一种多维度查询的技术。鉴于一个关系数据库以行和列的形式存储所有数据,一个多维数据集包括轴和列。考虑下面的数据集:
行轴包括”All products”, “Books”,”Fiction”等等,并且列轴包括生产年份”2000″”和”2001″、”Growth”的计算值以及”Unit sales”和”Dollar sales”的测量值。每个单元代表在某一年的一个产品类别的销售额,例如2001年Magazines的$销售额是2426美元。
这是一个比关系型数据库展现出来的更加丰富的视图。多维数据集的只不是永远都来自于一个关系数据库的列。 ‘Total’, ‘Books’ and ‘Fiction’ 是一个具有层次结构连续的成员,每一个成员都包括其下一层的成员。即使是在”2000″和”2001″一行,”Growth”是一个计算出来的值,它引入一个公式从其他列计算当前列的值。
该例中使用的维度有:产品、生产线和测量值,仅仅是这个数据集可以分类和过滤的许多维度中的三个。维度,层次结构和测量值的集合被称为一个立方体。
结论
我希望我已经证明垛位是一个首选的数据显示方式。虽然一些多维数据库以多维度的格式存储数据库,我仍然认为这比以关系的格式存储数据要简单。
现在,你可以看看OLAP系统的架构。查看Mondrian architecture。http://mondrian.pentaho.com/documentation/architecture.php说明
这是一篇翻译,原文来自http://mondrian.pentaho.com/documentation/olap.php。翻译水平有限,难免翻译不当,请见谅。



