TALEND WEBINAR : March 27th, 2018 | Step-by-Step to Enterprise Data Integration

Talend“作业设计模式”和最佳实践 ~ 第 4 部分

Talend“作业设计模式”和最佳实践 ~ 第 4 部分

 

我们对“Talend 作业设计模式和最佳实践”的探讨即将圆满收官,这是激动人心的时刻。付出终有收获,功到自然成。本系列先前的博文持续受到好评,如果您尚未读过第 123部分,建议先行浏览。另外,我还在 Technical Boot Camp 进行了演示,在此向到场诸位表示感谢。而且,我直接向客户提供这些材料,因而催生了针对转换的内部需求。我们拟在近期围绕此系列举办几场网络讲座,目前正在筹备之中,由于需要一定的时间而且需要协调资源,有劳您耐心等候,希望第一期讲座能在 2017 年初顺利开启。我对此深表期待,也欢迎您持续关注并访问我的博客。

不过依照先前的承诺,我们接下来要继续深入了解一组 Talend 作业设计模式的最佳实践。首先要提醒您注意一个简单却经常被忽略的事实:Talend 是一种 Java 代码生成器,制定开发人员指南可以强化及简化通过作业设计模式生成 Java 代码的过程。这貌似显而易见,事实也的确如此。但设计精良的作业能生成干净的 java 代码,借助这些概念在画布上绘制是卓有成效的绝佳方式,我称之为“成功驱动型项目”

成功驱动型 Talend 项目

构建 Talend 作业的过程可能简单直接,也可能会相当复杂。成功实施的秘诀是培养良好的习惯以及引入必要的纪律。

从本系列开篇讨论“基本法则”起到现在,我的目标一直是促进对这些最佳实践的公开讨论,以便通过 Talend 实现合理而实用的作业设计模式。大多数用例将受益于原子作业设计和父/子业务流程,并且当项目包含重要的可重用代码时,可为整体成功提速。您当然要选择适合自己的路径,不过至少希望您做到一以贯之。

数据库开发生命周期 (DDLC)

要持之以恒!也许不仅仅关乎作业设计,同样关乎数据。我们在处理数据,对吧?大多数情况下,数据位于数据库中。试问数据库是否需要最佳实践?这是个设问句。数据模型(架构)随着时间的推移而变化,因此数据库设计必然也具有生命周期!这一点不言而喻。

数据库会不断演进,我们作为开发人员需要适应这一事实。此前我们已接纳 SDLC 流程,因此应该不难接受这样一个事实:我们需要一个数据库开发生命周期。在我看来这一点相当容易。对于任何环境 (DEV/TEST/PROD),数据库都需要支持:

  • 全新安装 - 基于架构的当前版本
  • 应用升级版本 - 删除/创建/更改数据库对象,升级至下个版本
  • 数据迁移 - 在发生破坏性“升级”(比如表的拆分)时

了解数据库生命周期及其对作业设计的影响变得尤其重要。数据库模型的版本控制十分关键。请遵循规定的设计流程,使用图形图表来说明设计,创建“数据字典”或“术语表”,并跟踪历史变化轨迹。我近期会就该话题另外撰写一篇博文,敬请留意。与此同时,在编制数据库模型时也请考虑以下流程,这是项更高层次的规则,而且非常奏效!

ddlc_dbdesignflow

 

更多作业设计最佳实践

那么,下面我们来了解更多作业设计模式和最佳实践,马上满足您的需要。这些内容将进一步深挖 Talend 的功能,可能涉及一些常见功能,也有一些并不常用,希望您能发现它们的价值。

另外 8 项最佳实践:

tMap 查找

我们大都知道,一些基本 tMap

tMap 组件最常见的用途是将数据流结构从源输入映射到目标输出,简单吧?当然!我们知道还可以合并多个源和目标架构数据流,为我们提供根据需要联接和/或拆分这些数据流的诸多机会,其中可能包括合并转换表达式,用来控制传入数据分散到下游的内容和方式。tMap 组件中的表达式可能出现在源架构或目标架构,还可以使用在 tMap 组件中定义的变量来进行应用。您可以在 Talend 组件参考指南中了解如何完成所有这些操作。请记住:强大的功能即意味着要担负重要的责任!

tmaplookup1tMap 组件还有一个不容忽视的用途,即并入与源数据流连接的查找。对于可应用至 tMap 组件的查找次数或查找数据的具体内容并没有物理限制,但必须合理考虑实际情况。

来看这个基本示例:有两行生成器,一个是源,另一个是查找。运行时,首先生成查找数据,然后处理源数据。

因为查找数据上的连接设置为“一次加载”,所有记录都会加载至内存,然后根据源数据结果集进行处理。此默认行为提供高性能连接,并且可以非常高效。

tmaplookup2

此外,可以想见当加载数百万个查找行或数十列时,可能产生相当大的内存需求。的确有此可能。如果需要进行多次查找,每次都有数百万行数据,该怎么办?需要多少内存?当查找涉及海量记录或数百列时,请谨慎考虑。

tmaplookup3我们来看如何权衡:内存与性能。有三种可用的查找模型:

  • 次加载将所有符合条件的记录读入内存
  • 每行重新加载 - 仅对每条源记录读取符合条件的行
  • 每行重新加载(缓存)- 对每条源记录读取符合条件的行,并将其缓存

显然,如果查找数据已加载至内存以与源连接,那么查询速度会相当快。但如果内存约束阻止了大量查找数据,或者您不想加载所有查找数据(因为用例可能并不需要),请使用“每行重新加载”查找模型。请注意,想要发挥其作用,您需要了解一些技巧。

首先在 tMap 组件内,可将查找模式更改为“每行读取”。注意下方区域会展开,以允许输入需要执行查找的“键”。添加这些键,以便有效定义 tMap 组件之外可用的全局变量。

tmaplookup4

对于查找组件,请在 SQL 语法的“WHERE”子句中使用 (datatype)globalMap.get(“key”) 函数,以在查找数据集上应用 tMap 中定义的已保存键值。这样就完成了对于从源进行处理的每条记录的查找检索,

tmaplookup5

无论采用哪种方式,都可实现高效查找。

全局变量

定义和使用我们所认为的“全局变量”涉及以下几个方面。开发人员一直都在 Talend 作业中创建和使用这些变量,我们称之为“上下文变量”。这些变量有时“内置”到本地作业中,有时出现在“项目存储库”中作为上下文组,因而可在多项作业之间重复使用。

无论是哪一种,都属于“全局变量”,其值在运行时确定,并可在赋予其定义的作业中用于任何位置。每当 context.varname 嵌入到组件、表达式或触发器中时,您就在使用一个这样的变量。别忘了将常用变量放在“参考项目”中,以便最大限度用于其他项目。

Talend 还提供 tSetGlobalVar 和 tGlobalVarLoad 组件,可在运行时定义、存储和使用“全局变量”。tSetGlobalVar 组件会在作业中存储键值对,类似于使用“上下文变量”提供更好的控制(如错误处理)。请参考我给出的示例,其中检索到单一 MAX(date) 值,随即将其应用于后续 SQL 查询以筛选另一个记录集检索。

tsetglobalvar1

要访问全局变量,请在 SQL“WHERE”子句中使用 (datatype)globalMap.get(“key”) 函数。建议熟悉此函数,体会到其强大之处之后,您很可能会经常使用!tglobalvarload1

The tGlobalVarLoad 组件为无法使用 tSetGlobalVar 组件的大数据作业提供类似的功能。来看我的示例,其中计算了一个聚合值,随即在后续读取中用于限定要返回的记录。


tglobalvarload2

我们继续这个话题。隐藏在普通视域中的是一组“系统全局变量”,可在作业中使用,其值由组件本身确定。我们之前在本系列第 1 部分的错误处理最佳实践中探讨过其中的 CHILD_RETURN_CODE 和 ERROR_MESSAGE。这些系统全局变量通常在组件执行设置其值后立即可用。因组件而异,可以使用不同的系统变量。以下列出其中一部分:

  • ERROR_MESSAGE / DIE_MESSAGE / WARN_MESSAGE
  • CHILD_RETURN_CODE / DIE_CODE / WARN_CODE / CHILD_EXCEPTION_STACK
  • NB_LINE / NB_LINE_OK / NB_LINE_REJECT
  • NB_LINE_UPDATED / NB_LINE_INSERTED / NB_LINE_DELETED
  •  global.projectName /global.jobName (这些为系统级别;用途显而易见)

加载上下文

 

'上下文组'支持高度可重用的作业设计,但有时我们对灵活性的需求更高。例如,假设您要在外部维护上下文变量的默认值。有时将它们存储在文件甚至数据库中会更有意义。具备在外部维护相应值的能力会非常有效,甚至可以支持一些安全考虑。tContextLoad 组件在此大有用武之地。

tcontextload1

关于进行作业设计以在运行时初始化上下文变量,上面的示例给出一种简单的方法。用于加载的外部文件包含以逗号分隔的键值命名对,并且读入时将覆盖作业中已定义上下文变量的当前值。这种情况下,将加载数据库连接详细信息,以确保提供所需的连接。请注意,您可以控制某些错误处理操作,实际上这提供了能以编程方式立即退出作业的另一个点:“遇到错误时退出”,这非常少见。当然,tContextLoad 组件同样也可以轻松地使用数据库查询,我知道有些客户这么做。

利用相应的 tContextDump 组件,将当前上下文变量值写出到文件或数据库中,这在编制高适应性作业设计时非常有用。

使用动态模式

经常有人问我如何构建处理动态模式的作业。这么问未免意义含混,因为有多种用例涉及处理动态模式。最常见的情形是将多个表中的数据移动到另一组相应的表,可能分属不同数据库系统(例如从 Oracle 到 MS SQL server)。创建作业来移动这些数据看似简单,但我们几乎立即可以判定:针对每个表构建作业并不切合实际。要是有数百个表怎么办?我们能不能简单地构建可以处理所有表的单一作业?很遗憾,Talend 在这一方面确实存在局限。不过也莫沮丧,我们可以分成两个作业来实现这一点:一个用于转储数据,另一个用于加载数据。这样能接受吧?

tsetdynamicschema1

来看我的作业示例:建立三个连接,前两个分别检索“表”和“列”的列表,第三个检索实际数据。只需通过迭代每个表,保存其中的列,我就可以使用 tSetDynamicSchema 组件对位置平面文件进行数据读写(转储进程)。类似作业同理,不同的是第三个连接将读取位置文件并写入目标数据存储(加载进程)。

在该场景中,开发人员必须对其主机数据库的内部工作稍有了解。大多数系统(如 Oracle、MS SQL Server 和 MySQL)都有系统表,通常称为“信息模式”,其中包含表及其列等有关数据库的对象元数据。下面的查询将从我的 TAC v6.1 MySQL 数据库中提取完整的表/列的列表。(我的首选 SQL 语法格式是否合您意?):

screen-shot-2017-01-09-at-11-04-28-am

此数据库通常受保护,请务必使用具有相应“选择”权限的连接凭据。

请注意我使用 tJavaFlex 组件来迭代找到的表名称。我保存每个“表名称”并设置“控置中断”标志,然后迭代找到的每个表并检索其排序列的列表。在对列长度中的任何空值进行调整后,保存的“动态模式”即已完成。当表名称更改时,条件“IF”将检查“控制中断”标志并开始当前表的转储过程。搞定!

动态 SQL 组件

动态代码非常有用,Talend 提供了几种实现的方法。在之前的作业设计中,我使用直接方法从数据库中检索表和列的列表。Talend 实际上提供主机系统特定组件来执行相同操作。这些 t{DB}TableList 和 t{DB}ColumnList 组件(其中 {DB} 由主机组件名称替换)提供对“信息模式”元数据的直接访问,无需实际了解任何相关信息。也可使用这些组件代替之前所描述冷工作的转储/加载进程,不过具体有何意义?

并非所有 SQL 查询都需要检索或存储数据。有时需要其他数据库操作。针对这些需要登记 t{DB}Row 和 t{DB}SP 组件。前者可用于执行几乎任何不返回结果集的 SQL 查询,如“DROP TABLE”;后者则用于执行“存储过程”。

最后一项要点是 t{DB}LastInsertId 组件,可从数据库输出组件检索最近插入的“ID”,有时这非常有用。

CDC

另一个常见问题是,Talend 是否支持 CDC:“变更数据捕获”?答案是肯定的。当然,可通过“发布/订阅”机制直接与所涉及的主机数据库系统进行关联。需要注意的是,并非所有数据库系统都支持 CDC。以下是 Talend 作业中明确的 CDC 支持“当前”列表:

screen-shot-2017-01-09-at-11-15-36-am

有三种 CDC 模式可供选择,包括:

  • 触发器(默认) - 使用可以跟踪插入、更新和删除的数据库主机触发器
  • 重做/归档日志 - 仅与 Oracle 11g 及更早版本搭配使用
  • XStream - 仅与 Oracle 12 和 OCI 搭配使用

这三种模式中,您最有可能使用的是“触发器”模式,鉴于此,我们来了解其架构:

cdcprocessflow

The 《Talend 用户指南》第 11 章全面探讨了有关 Studio 内以及与主机数据库系统协调的 CDC 进程、配置和使用。虽然在概念上非常简单,但是需要进行大量设置。应预先充分了解您的需求、CDC 模式和作业设计参数,并在开发人员指南中做好记录!

建立 CDC 环境后,其将提供强大的机制,使下游目标(通常是数据仓库)保持最新状态。使用 Talend 作业中的 t{DB}CDC 组件对于自上次提取后已更改的数据进行提取。配置和实施 CDC 需要时间和精力,但其功能的确非常有用!

自定义组件

Talend 现有调色板提供超过 1,000 个组件,不过您仍有众多理由自行构建。Talend 开发人员常在自定义组件中封装特定功能。部分开发人员已构建组件并将其产品化,另一些开发人员则将组件发布于最近现代化的 Talend Exchange 上供免费访问。对于 Talend 调色板不提供的组件,可在该处进行搜索,可能会找到合您所需的内容。需使用“Talend Forge”帐户(不过您可能已经创建)。

customcomponents1

首先请确保正确设置存储自定义组件的目录。从“首选项”菜单中执行此操作,并选择一个所有开发人员都会使用的通用位置。单击“应用”,然后单击“确定”。

在菜单栏上找到“交换”链接,以便选择和安装组件。第一次执行此操作时,请选中“始终在后台运行”并单击“在后台运行”按钮,因为加载包含大量可用对象的列表需要一些时间。从此列表中可以“查看/下载”感兴趣的对象。完成组件下载后,单击“下载的扩展”进行实际安装,以便在 Studio 中使用。完成后,组件将显示为“已安装”,并可从调色板使用。

customcomponents2

组件及其相关文件安装完成后,可能不容易找到,可以查看这两个位置:

{talend}/studio/plugins/org.talend.designer.components.exchange{v}
{talend}/studio/plugins/org.talend.designer.components.localprovider{v}

如果想要自行创建自定义组件,请在 Studio 中切换到“组件设计器”透视图。大多数自定义组件使用“JavaJet”,这是用于针对“Eclipse IDE”封装 Java 代码的文件扩展名。有关“如何创建自定义组件”的教程内容精当,适合初学者。虽然该教程有点过时(2013 年左右发布),但其中包含您需要掌握的基础知识。此外也可参考第三方教程(部分在以上教程中列出),比如我推荐“Talend 示例:自定义组件”。您还可借助 Google 搜索有关创建“自定义组件”的更多信息。

作业脚本 API

通常我们使用“设计器”来编制 Talend 作业,然后生成底层 Java 代码。您有没有想过可否自动生成 Talend 作业?的确有一种方法!打开您的任意一项作业。画布底部有三个选项卡:“设计器”、“代码”和“作业脚本”。这里值得细究,您可能用过“代码”选项卡来检查生成的 Java 代码,有没有单击过“作业脚本”选项卡?如果有,知道自己看到的是什么吗?我打赌多数人并不知道。该选项卡显示的是代表作业设计的脚本。下次不妨仔细看看。看到与作业设计有关的熟悉的内容了吧?没错…

那么,您说说看?好吧,我来揭晓答案。假设您在某个位置创建和维护有关作业设计的元数据,并通过创建的进程引擎来运行,生成格式正确的作业脚本,或者调整关键元素以创建作业的多个排列。这时情况会很有意思!

jobscript1

查看 代码>例程分区下的“项目存储库”,找到“作业脚本”文件夹。新建一个作业脚本(我命名为“test_JobScript”)。打开任何作业并复制“作业脚本”选项卡内容,将其粘贴到作业脚本文件中并保存。右键单击该作业脚本,然后选择“生成作业”。现在看看“作业设计”文件夹,您会发现一项新作业。想象一下现在能做什么吧,太棒了!

结语

咻!以上就是全部内容。并不是说创建和维护 Talend 作业设计就没有其他最佳实践了,相信还有更多, seo-small-business-competition-300x300 不过可以在更广泛的社区对话中接着讨论。我们介绍的这一系列最佳实践(共 32 项)兼具广度和深度,将对使用 Talend 的成功驱动型项目有所助益。


在此可以期待本系列的下一篇博文,我们会转移方向,探讨如何将所有这些最佳实践应用于传统用例。适用的技术、完善的方法以及解决方案有助于实现预期的结果,构成使用这些最佳实践和作业设计模式的支柱。期待下次再会!

Most Downloaded Resources

Browse our most popular resources - You can never just have one.

Join The Conversation

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *