对于通过适当的排序调度和监控而言,多个应用程序之间的数据传输可能是一个巨大的挑战,这些应用程序是由各种资源构成的并涉及众多相互依赖的进程。异常终止的进程通常需要从它们的故障转移点重新启动,以实现它们的业务要求。另外,用户常常需要接收关于进程历史的信息,以进行审计跟踪和监控。
本文介绍一个解决方案,事实证明,该方案在应对这些要求和挑战方面非常有用,可以使用最小的资源构建。该解决方案可以使用 IBM® DB2® 关系数据库功能或其他关系数据库系统构建。无需使用任何特定调度程序或昂贵的监控工具即可监控和调度复杂的进程。该方案非常经济实惠,只需很少的技术即可开发和维护。
有一些业务问题与数据库进程和调度相关。这些问题可能会影响盈利能力,阻止用户实现它们的功能和经营目标。
- 不能在数据库之外跟踪的内部数据库进程的执行和完成,通常需要经过培训的资源来在数据库级别或运营系统的级别理解和监控。
- 有些进程可能会成功完成,但需要的执行时间不正常,可能会导致意想不到的值,这是一个真正的业务威胁。这种情况可能会发生在附属进程的最低级别,这还会导致其他主要进程的操作失败和功能异常。公司需要确保那些小型附属进程的完美执行。
- 多个源可能会以不同的顺序和时间轴将数据传递到各种进程中。这些进程必须被适当管理和调度,以避免数据不一致和进程重叠。在多格式的复杂数据集成项目中,实现适当的调度可能是一个艰巨的任务。
- 异常的进程终止或进程完成失败是数据集成进程流中的一个常见情况。根据业务需求,数据可能需要立即通过人工干预从故障转移点恢复或者自动恢复。
以下的用例有效地回答了这些业务问题。
- 第一个用例是进程执行的参与者查询进程历史。
- 第二个用例是业务活动监控。业务活动监控存储、查询、或者分析进程执行日志来找到关于进程的有用统计信息。例如,这种监控能够反映进程的每个步骤平均花费的时间和瓶颈出现的位置。
- 第三个用例是取消功能和恢复某些失败的进程。进程日志可用于取消和恢复不成功的进程。
- 最后一个用例是进程调度程序,它能够满足复杂的数据加载频率的要求。
要解决这些问题,首先必须根据组件的功能特性识别它们,设计数据模型来为日志存储和检索关键的数据元素。识别组件并准备好数据模型后,就可以像使用操作和功能测试用例一样开发和测试进程模块。开发的模块可用作现有 ETL 系统的插件,也可以用于插入和更新各个数据库实体中的数据。日志操作从数据库中的一个进程日志足迹开始,然后继续记录日志直到进程完成, 不管执行成功还是失败。
系统架构包含三个主要组件:
- 进程日志组件:适用用例 1、2 和 3。
这个组件负责为模块中的特定进程生成进程相关信息。每当一个新进程启动时,组件使用一个预定义的执行状态记录其信息。在进程成功完成或被弃用之前,组件保持活动状态,并尝试记录该进程在数据库中的最新状态。组件在进程启动之时与进程调度组件交互,并与进程错误管理组件交互,记录处理过程中发生的错误。 - 进程和程序调度组件:适用用例 4。
这个组件控制进程的启动顺序。这是个附属组件,与进程日志组件交互,按计划执行与进程关联的代码。 - 进程错误管理组件:适用用例 2、3 和 4。
这个组件负责从预定义的错误列表生成和更新错误数据,并将信息更新到进程日志组件。
这个问题的解决方案非常有效,尤其是在数据集成和数据转换(ETL)应用程序中。这个解决方案在其他消息驱动的集成项目中也有效,在那些项目中,许多进程以固定的间隔执行。图 1 展示了解决方案数据流。
图 1. 数据流图表
这个解决方案有两个主要部分:
- 设计数据模型
- 设计和构建操作逻辑
逻辑数据模型包含以下实体:
- Process Master
- Process Program
- Process Program Schedule
- Process Log Detail
- Error Master
图 2 展示了这个逻辑数据模型。
图 2. 逻辑数据模型图表
以下小节将分别检查这些实体。
这个实体包含应用程序中的所有进程的有关信息,这是以层级格式存储在表中的主信息,即,一个进程可以有一个父进程,也可以拥有祖父进程。进程层级需要精确定义,以确保相互链接的进程的正确排序。其他信息对于存储也是有用的,但不是强制的。
在一个数据仓库系统中,涉及大量进程,比如元数据的阶段化(staging),数据质量分析、转换和合并,将数据加载到数据市场,等等。为了将那些进程定义并分发到 Process Master 中,我们可以通过以下方式安排数据:
表 1. Process Master
| 进程描述 | 进程 ID | 父进程 ID | 注释 |
|---|---|---|---|
| Database Process | 00000 | 00000 | 从 “00000” 开始的数据库进程 |
| Source Data Staging Process | 10000 | 00000 | 在三个主进程中,“Source Data Staging” 是第一个父进程为 “Database Process” 的进程,这个 Process ID 从 1 开始(10000) |
| Staging Source System -1 | 11000 | 10000 | 有多个源系统,“Source System -1” 的 Process ID 为 “11000”,即,系统可以处理 9000 个源系统 |
| Staging Source System -1 – Subsystem – 1 | 11100 | 11000 | 有许多 Subsystems 链接到 “Source System -1”,因此 “Subsystem -1” 的 Process ID 为 “11100”,这意味着系统最多可以处理 900 个子系统 |
| Staging Source System -1 – Subsystem – 1 – Europe Data | 11101 | 11100 | 这个子系统在一些不同国家运行,源数据也可以从那些国家获取,这里,系统最多可以处理 90 个国家 |
| Data Transformation Process | 20000 | 00000 | 转换进程是父 “Database Process” 的第二个主要进程,它的 ID 从 2 开始 |
| Transform Source System -1 | 21000 | 20000 | 与 “Staging processes” 的方式相同,这个转换进程可以被分发,都带有前缀 “2”,确定每个 “Staging Process” 的 “Transformation Process |
| Transform Source System -1 – Subsystem – 1 | 21100 | 21000 | 21000 的子进程 |
| Transform Source System -1 – Subsystem – 1 – Europe Data | 21101 | 21100 | 21100 的子进程 |
| Hyperion Module Process | 90000 | 90000 | 这是一个不同的独立模块,可以加入 process master(或者,也连接到 “Database Process”) |
| Hyperion Module Process – Data Manipulation Process -1 | 91000 | 90000 | 它拥有自己的进程分发,但也可以在输出流中调度和记录 |
表 2. Process Master 实体结构
| 列 | 列描述 | 数据类型和宽度 | 默认值 | 强制(M)或可选(O) |
|---|---|---|---|---|
| Process ID | 包含 Unique Process Identification Number | Char 5 | NA | M |
| Process Parent ID | 包含一个特定进程的 Parent Process ID并建立一个层级 | Char 5 | NA | M |
| Process Description | 进程的描述 | Varchar 200 | NA | M |
| Process Sequence | 进程在其层级中的序列编号(比如,此进程是其父层级中的第 5 个进程,因此值应该为 “5”) | Char 2 | NA | O |
| Process CL Parameters | Process Command Line 参数 | Varchar 2000 | NA | O |
| Process Max Error Allowed | 这个进程允许的错误数量(系统可以查询这个数字并可以据此强制终止进程) | Char 3 | 999 | O |
| Application Name | 此进程针对其定义的应用程序的名称 | Varchar 1000 | NA | M |
| Module Name | 此进程针对其定义的模块的名称 | Varchar 1000 | NA | O |
| Process Logging Flag | 进程是否需要进行日志记录 | Char 1 | Y | M |
| Scheduler Flag | 调度程序是否连接到这个进程 | Char 1 | Y | M |
一个进程可以包含一个或多个程序(代码和数据结构)。一旦一个进程被执行,系统开始从数据库表搜索关联的程序。(注意:这种情况仅当调度程序没有连接到这个进程时发生。请查看 Process Master 表中的 Scheduler Flag。) 一个进程可以关联到多个程序,因此,这个实体具有从进程到程序的 “一对多” 基数性。
表 3. Process-Program 实体结构
| 列 | 列描述 | 数据类型和宽度 | 默认值 | 强制(M)或可选(O) |
|---|---|---|---|---|
| Process Program Surrogate Key | 包含这个实体的 Surrogate 键 | Integer | NA | M |
| Program Name | 包含程序名称(我们可以在这里分别保存 Program Master 实体和参考程序 ID) | Varchar 50 | NA | M |
| Process ID | 进程识别编号 | Char 5 | NA | M |
| Program CL Parameters | Program Command Line 参数 | Varchar 2000 | NA | O |
每个单独程序都可以被调度为以预定义的顺序执行。这个实体促使程序关联到一个或多个调度,还能够定义和构造具有特定频率的重复 Process-Program 信息。(例如,某个程序可以以 5 分钟的间隔运行。)这个实体具有从 Process-Program 实体到 Process-Program-Schedule 实体的 “一对多” 基数性。
表 4. Process-Program-Schedule 实体结构
| 列 | 列描述 | 数据类型和宽度 | 默认值 | 强制(M)或可选(O) |
|---|---|---|---|---|
| Process Program Schedule Surrogate Key | 包含这个实体的 Surrogate 键 | Integer | NA | M |
| Process Program Surrogate Key | 包含 Process Program 的 Surrogate 键(Foreign Key) | Integer | NA | M |
| Schedule Year | 包含年度 | Varchar 4 | NA | M |
| Schedule Month | 包含月份名称 | Varchar 20 | NA | M |
| Schedule Day | 包含日期 | Varchar 2 | NA | M |
| Schedule Hour | 包含小时 | Varchar 2 | NA | M |
| Schedule Minute | 包含分钟 | Varchar 2 | NA | M |
| Repeat Frequency | 这个字段包含频率信息(即,#5 表示这个程序将从开始时每 5 分钟执行一次) | Varchar 2 | NA | M |
| Skip Schedule | 程序是否按照其调度执行 | Char 1 | NA | M |
| Trigger File Flag | 这个程序是否从另一个应用程序预期一个 “Trigger File” | Char 1 | N | O |
一个进程被发起后,系统就开始从 Process-Program-Schedule 搜索一个特殊程序,并在 Process Log 表中创建一个条目。系统根据进程状态控制进程的执行。在进程的每个执行步骤中,都有一个附加的特定状态码,系统在进程本身的执行状态的基础上更新这个状态码字段。一个特殊进程可以使用一些不同的状态码,如表 5 所示。
表 5. 进程执行状态 - 状态码示例
| 状态码 | 状态描述 | 注释 |
|---|---|---|
| 0 | 由于已知的错误码而失败 | Error Code 可以从 Error Master 获取 |
| 1 | 程序启动 | 等待完成 |
| 2 | 进程成功结束 | 仅当进程结束、没有错误时 |
| 3 | 处理了 0 条记录 | 目标记录计数为 0 |
| 4 | 源实体中的 0 记录 | 源计数为 0 |
| 5 | 进程链接错误 | 进程不能被连接到它的父进程(附属进程情况) |
| 6 | 异常完成时间 | 进程成功但时间异常 |
| 7 | 进程进展错误 | 进程启动但下一条记录读取没有发生 |
| 8 | 进程重启 | 进程重启代码 |
| 9 | 失败的错误为 UNKNOWN 错误 | 错误代码不能获取 |
| * | 关联父进程的状态(仅当它的此前状态为 “2”) | 一旦一个子进程或附属进程启动以执行(仅当它的父进程已经成功完成且状态码位 “2” 时可能),系统将其父进程状态从 “2” 转换为 “*” |
| # | 处于执行状态的进程 | 当附属进程系统执行时,系统将父进程状态从 “*” 转换为 “#” |
| $ | 父进程成功 | 一旦附属进程成功完成,系统将其父状态从 “#” 转换为 “$”。这意味着没有必要再次处理。 |
- 启动一个进程。
- 搜索 Process-Program-Schedule 以确认关于调度的信息并获取程序名称。
- 获取 Process ID。
- 在 Process Log 实体中插入一条记录。
- Process Status Flag 应该从 “1” 开始。
- 使用程序的命令行参数执行程序。
- 提交
- 在进程成功完成时:
- 使用以下细节更新记录:
"Process End Time" = (end timestamp)
"Process Target Record Count" = (target table record count)
"Process Status Flag" = "2" (if successful)
"Process Execution Time" = (end time - start time)
"Process Comments" = (comments with SQL ERROR code and description) - 如果这是一个附属进程,将 “Parent Process” 状态标志从 “2” 转换为 “*”
- 根据列表更新这个父进程状态。这种机制确保进程可恢复性和连续性,而且还控制附属进程执行。
- 使用以下细节更新记录:
- 在成功完成之时:
- 更新相同记录。
- “Status Code” 应该不是 “2”。从列表选择适当的状态码。
- 提交
表 6. Process Log 实体结构
| 列 | 列描述 | 数据类型和宽度 | 默认值 | 强制(M)或可选(O) |
|---|---|---|---|---|
| Process Log ID | 惟一地识别一条 Process Log 记录。这个 ID 可以插入到目标文件/表(基于每条记录插入一个单独的列中),以便控制下一个附属进程执行。下一个进程将只从表/文件访问那些记录,这个表/文件已经被处理,且正在等待进一步转换。 | Integer | NA | M |
| Process ID | 正在处理的 Process ID | Char 5 | NA | M |
| Process Start Time | 流程的启动时间戳 | Timestamp | NA | M |
| Process Log ID | 惟一地识别一条 Process Log 记录。这个 ID 可以插入到目标文件/表(基于每条记录插入一个单独的列中),以便控制下一个附属进程执行。下一个进程将只从表/文件访问那些记录,这个表/文件已经被处理,且正在等待进一步转换。 | Integer | NA | M |
| Process End Time | 流程的结束时间戳 | Timestamp | NA | M |
| Process Source File Name | 源的文件/表的名称 | Varchar 100 | NA | O |
| Process Source Record Count | 源文件/表中的启动记录计数 | Integer | NA | M |
| Process Target Record Count | 流程的结束记录计数 | Integer | NA | M |
| Process Status Flag | 流程的状态(从状态列表获取) | Varchar 2 | NA | M |
| Process Start Module | 启动流程的模块 | Varchar 100 | NA | O |
| Process End Module | 进程结束的模块 | Varchar 100 | NA | O |
| Process Execution Time | 实际流程执行时间(可能不是从开始时间和结束时间之间的确切差) | Decimal | NA | M |
| Process User Log ID | 启动流程的用户 | Varchar 50 | NA | M |
| Process System Status | System (OS / Network) 相关信息 | Varchar 2000 | NA | O |
这个实体已经定义了流程相关的预定义错误代码和描述,用于流程执行步骤。当一个错误发生时,系统从这个表查找相关的错误代码,并根据 Process Log ID 从表更新 Process Log 表。
表 7. Process-Error 实体结构
| 列 | 列描述 | 数据类型和宽度 | 默认值 | 强制(M)或可选(O) |
|---|---|---|---|---|
| Error Code | 包含错误码 | Char 5 | NA | M |
| Error Description | 包含错误描述 | Varchar 100 | NA | M |
| Error Type | 哪种错误类型:“SQL”、“SYSTEM”、“DATA”、“CODE” | Varchar 10 | NA | M |
| Critical Status | 5 = 最关键, 1= 最不关键 | Char 1 | NA | O |
下面展示了一个样例伪代码,它在 Process Log 表中插入记录。
Main Procedure "Process Log Insert" Define 5 input parameters 1st parameter is the input "Process ID" [by searching right process from Process- Program-Schedule" Entity ] 2nd parameter is the "Start Time" 3rd parameter is the "Start Module" 4th parameter is the "Mode" [either "Insert" or "Update"] 5th parameter is the "Process Log ID" (optional - for control the next process execution) >>Insert a new record in the "Process Log" Entity with the input parameter specified above, use DB2 INSERT statement to insert the record. >> Update existing record in the "Process Log" Entity, use DB2 UPDATE statement to update the record. |
这个解决方案最重要的部分是使用适当的进程层级构建 Process Master 实体。成功创建 Process Master 后,需要根据进程的运行顺序和频率定义 Process Program Scheduler 数据。这两个活动是总体解决方案的先决条件。
现在,您应该能够跟踪整个应用程序的所有进程以及单独的、嵌套的、细粒度进程。这个解决方案是一个概念,可以使用任何 RDBMS(包括 DB2 和 Informix)构建,无需太多开发工作和资源利用。
要获取最优性能,您需要在 Process Log 表上的物理数据模型中创建适当的数据库索引。这个解决方案的另一个用途是进程可恢复性,当应用程序崩溃并需要重启时。这可以基于 Process Log 表中的那个特殊进程条目执行。为了重启进程,系统需要获取最新状态码和详细的进程信息。
这个解决方案没有提供任何界面来加载主数据或者为终端用户生成报告,用户需要单独构建它们。另外,自动可恢复性也需要单独设计。
学习
- 在 developerWorks 上的 Information Management 专区,获取提高您的 IBM Information Management
产品组合技术所需的资源。
- 随时关注 developerWorks 技术活动 和 网络广播。
获得产品和技术
- 下载 IBM 产品评估版 或 在线试用 IBM SOA Sandbox,并开始使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。
- 通过 IBM 试用软件 构建您的下一个开发项目,可直接从 developerWorks 下载。
讨论

Arindam Chakraborty 是 Enterprise Application Development and Management Practice 的一位数据架构师。Chakraborty 拥有超过 13 年的数据库设计和咨询经验,重点关注技术管理、软件生命周期方法系统、数据库管理、性能、架构设计、以及应用程序开发和实现。他曾管理 Information Services 和业务单位高级管理层之间的关系,计划、开发和实现了大量应用程序,提供实际业务问题的解决方案。他的软件专长领域包括通过竞争激烈的考试获取的一个 Oracle DBA 和 DB2 认证,以及根据 IBM 可靠的方法系统推动咨询方案。Chakraborty 还擅长数据架构、数据建模、企业数据仓库设计和数据市场、以及基于性能优化的数据库管理。