【原創】Talend ETL Job日誌框架——基於P&G項目的一些思考和優化

一、背景

接觸talend也挺長一段時間了,在P&G項目中每天都是使用它開發job,做ETL,也看了前輩開發的很多ETL Job,學到不少。也接觸了TAC(talend administration center),也發現了TAC的一些優點和不足。

優點:

1、TAC可以更好的界面化管理job、部署、HA等,提升了job運行的良好環境。

2、通過plan可以更好的將不同的job進行關聯成線,更好的對數據處理做到前後順序有秩。

3、日誌比較全,還可以選擇不同的日誌級別。

缺點:

1、整個管理前端是基於tomcat的,而且整個管理網站效率不是特別好,使用起來相對沒有C/S端的流暢。

2、時不時會因爲系統的一些穩定性問題,帶來一些job運行上的異常,而且這部分監控無法捕獲。

3、整個網頁使用起來不是非常的順手,主要體現在:卡頓、時不時刷新下、偶爾出現異常等。

4、運行統計上面不是符合所有的場景,比如P&G,他們job是分層(STG,DWD,DWS,DM)的,即每一層的數據都是不同的job,這個時候的統計就不能僅僅是按照job運行來統計,有時候要幾個job合併,有時候要這個job取一點數據,另一個job取一點數據,這種場景下就不適合了。

還有一點就是P&G大部分都是通過job來調用存儲過程來計算,這就帶來2個不和諧的地方,其一無法得知那個job使用哪些存儲過程或者調用過哪些存儲過程,只能通過名稱的約定來得知,顯然這種方式對於追溯引用不是非常的方便。其次就是對於job和存儲過程的統計無法產生關聯性,對於後期的一些性能分析無法提供輔助數據依據。

因此,我們有這樣子的一些需求:

1、能很方便的提供每個job執行的記錄,比如常規的:開始時間、結束時間、耗時、屬於哪塊業務範圍等。

2、Job和存儲過程的關係,哪些job調用了哪些存儲過程,並且這些存儲過程的執行記錄等。

二、實現

1、 數據庫表設計

a) Job記錄表

該表主要是記錄每個job的信息,在一個job上了production環境的時候,就要在此表生成相應的記錄。

IF (OBJECT_ID(N'[chk].[etl_job_list]', N'U') IS NOT NULL)

BEGIN

PRINT N'刪除表:[chk].[etl_job_list]';

DROP TABLE [chk].[etl_job_list];

END

GO

CREATE TABLE [chk].[etl_job_list]

(

[scope] NVARCHAR(200) NOT NULL,--業務板塊說明,每個job歸類於一類scope,如IDS,發貨、零售等

[etl_job_id] NVARCHAR(100) NOT NULL,--UNIQUEIDENTIFIER用NEWID生成並轉CHAR存儲

[etl_job_name] NVARCHAR(200) NOT NULL,--etl job名稱,

[create_user] NVARCHAR(50) NOT NULL,--創建者

[create_date] DATETIME NOT NULL,--創建日期

[last_update_date] DATETIME NOT NULL,--最後更新日期

[remark] NVARCHAR(200) NULL--說明

)

GO

對應的存儲過程,因爲adw不支持唯一索引,但是job name需要有唯一約束的,所以通過創建存儲過程來創建可以避免唯一衝突。

存儲過程:

IF (OBJECT_ID(N'[chk].[usp_insert_etl_job_list]', N'P') IS NOT NULL)

BEGIN

PRINT N'刪除存儲過程:[chk].[usp_insert_etl_job_list]';

DROP PROC [chk].[usp_insert_etl_job_list];

END

GO

CREATE PROC [chk].[usp_insert_etl_job_list]

(

@scope NVARCHAR(200)

,@etl_job_name NVARCHAR(200)

,@create_user NVARCHAR(50)

,@remark NVARCHAR(200)

)

AS

--====================================================================================================================================

-- ProcedureName : chk.usp_insert_etl_job_list

-- Author : john.xiong

-- CreateDate : 2019-01-16

-- Description : insert data to chk.etl_job_list

/*************************************Parameters參數說明*******************************************************************************

-- @scope : 業務板塊說明,每個job歸類於一類scope,如IDS,發貨、零售等

-- @etl_job_name : etl job 名稱

-- @create_user : 創建用戶

-- @remark : 說明/備註

**************************************Modfied List修改記錄*****************************************************************************

-- Modified Date Modified User Version Modified Reason

**************************************************************************************************************************************

-- 2019-01-16 john.xiong V01.00.00 初始化版本

**************************************************************************************************************************************/

--====================================================================================================================================

BEGIN

BEGIN TRY

DECLARE

@begin_time DATETIME

,@end_time DATETIME

,@cost_time INT

,@create_date DATETIME

,@last_update_date DATETIME

,@etl_job_id NVARCHAR(100)

,@row_count INT

SET @begin_time = DATEADD(HOUR, 8, GETDATE());

INSERT INTO [chk].[tb_proc_cost_log]

(

[proc_name]

,[Object_name]

,[execute_time]

,[action]

,[remark]

,[cost_time]

)

SELECT

N'chk.usp_insert_etl_job_list' AS [proc_name]

,N'chk.etl_job_list' AS [Object_name]

,@begin_time AS [execute_time]

,N'start' AS [action]

,'' AS [remark]

,0 AS [cost_time]

IF (LTRIM(RTRIM(ISNULL(@etl_job_name, ''))) = '')

BEGIN

RAISERROR(N'etl job name不能爲null或者空,請重新輸入!', 16, 1);

END

SET @row_count = 0;

SELECT @row_count = COUNT(*) FROM [chk].[etl_job_list] WHERE LOWER([etl_job_name]) = LOWER(@etl_job_name);

IF (@row_count > 0)/*etl job name唯一性校驗,保證唯一性*/

BEGIN

RAISERROR(N'etl job name已經存在,請重新輸入!', 16, 1);

END

SET @scope = ISNULL(@scope, '缺省');

SET @create_user = ISNULL(@create_user, CONVERT(NVARCHAR(50), SUSER_SNAME()));

SET @remark = ISNULL(@remark, '');

SET @create_date = DATEADD(HOUR, 8, GETDATE());

SET @last_update_date = @create_date;

SET @etl_job_id = CONVERT(NVARCHAR(100), NEWID());

INSERT INTO [chk].[etl_job_list]

(

[scope]

,[etl_job_id]

,[etl_job_name]

,[create_user]

,[create_date]

,[last_update_date]

,[remark]

)

SELECT

@scope

,@etl_job_id

,@etl_job_name

,@create_user

,@create_date

,@last_update_date

,@remark

SET @end_time = DATEADD(HOUR, 8, GETDATE());

SET @cost_time = DATEDIFF(SECOND, @begin_time, @end_time);

INSERT INTO [chk].[tb_proc_cost_log]

(

[proc_name]

,[Object_name]

,[execute_time]

,[action]

,[remark]

,[cost_time]

)

SELECT

N'chk.usp_insert_etl_job_list' AS [proc_name]

,N'chk.etl_job_list' AS [Object_name]

,@end_time AS [execute_time]

,N'end' AS [action]

,CONVERT(NVARCHAR(50), @etl_job_id) AS [remark]

,@cost_time AS [cost_time]

PRINT N'Exec success';

PRINT N'curr_etl_job_id=' + @etl_job_id;

END TRY

BEGIN CATCH

INSERT INTO [chk].[log_proc_error_rec]

(

[proc_name]

,[error_source]

,[error_time]

,[error_severity]

,[error_state]

,[error_msg]

,[log_user]

)

SELECT

N'chk.usp_insert_etl_job_list' AS [proc_name]

,ERROR_PROCEDURE() AS [error_source]

,DATEADD(HOUR, 8, GETDATE()) AS [error_time]

,ERROR_SEVERITY() AS [error_severity]

,ERROR_STATE() AS [error_state]

,ERROR_MESSAGE() AS [error_msg]

,SUSER_SNAME() AS [log_user]

PRINT N'Exec failed';

END CATCH

END

b) Job運行記錄表

記錄每個job的每次運行的情況,如開始結束時間,用於計算耗時,運行狀態等是是否報錯,用於後期彌補tac調度的不足,例如可以自定義循環判斷job是否成功,自定義配置job之間的運行依賴等。

IF (OBJECT_ID(N'[chk].[etl_job_excc_history]', N'U') IS NOT NULL)

BEGIN

PRINT N'刪除表:[chk].[etl_job_excc_history]';

DROP TABLE [chk].[etl_job_excc_history];

END

GO

CREATE TABLE [chk].[etl_job_excc_history]

(

[exec_id] NVARCHAR(100) NOT NULL,--UNIQUEIDENTIFIER用NEWID生成並轉CHAR存儲

[etl_job_id] NVARCHAR(100) NOT NULL,--UNIQUEIDENTIFIER用NEWID生成並轉CHAR存儲

[etl_job_name] NVARCHAR(200) NOT NULL,--etl job名稱,

[begin_date] DATETIME NULL, --etl job運行開始時間

[end_date] DATETIME NULL, --etl job運行結束時間,如果沒有結束時間就有可能是運行報錯。

[exec_status] INT NULL, --0:運行報錯,1運行成功,2正在運行

[remark] NVARCHAR(500) NULL,--說明,如果是報錯就是錯誤信息。

[create_date] DATETIME NOT NULL, --創建日期

[create_user] NVARCHAR(50) NOT NULL--創建人

)

存儲過程:分爲insert和update兩個,用於創建和更新

創建的exec_id參數其實可以在存儲過程中生成,並且使用out屬性輸出,這樣子就不用每次都傳遞一個參數進去,但是因爲P&G的adw數據倉庫不支持out參數,所以只能使用talend生成一個全局的guid傳遞進去,這樣子才能保證同一個ID的操作和更新等。

IF (OBJECT_ID(N'[chk].[usp_insert_etl_job_excc_history]', N'P') IS NOT NULL)

BEGIN

PRINT N'刪除存儲過程:[chk].[usp_insert_etl_job_excc_history]';

DROP PROC [chk].[usp_insert_etl_job_excc_history];

END

GO

CREATE PROC [chk].[usp_insert_etl_job_excc_history]

(

@exec_id NVARCHAR(100)

,@etl_job_name NVARCHAR(200)

,@begin_date DATETIME

)

AS

--====================================================================================================================================

-- ProcedureName : chk.usp_insert_etl_job_excc_history

-- Author : john.xiong

-- CreateDate : 2019-01-16

-- Description : insert data to chk.etl_job_excc_history

/*************************************Parameters參數說明*******************************************************************************

-- @exec_id : UNIQUEIDENTIFIER用NEWID生成並轉CHAR存儲

-- @etl_job_id : etl job id UNIQUEIDENTIFIER用NEWID生成並轉CHAR存儲

-- @etl_job_name : etl job 名稱

-- @begin_date : job運行開始時間

**************************************Modfied List修改記錄*****************************************************************************

-- Modified Date Modified User Version Modified Reason

**************************************************************************************************************************************

-- 2019-01-16 john.xiong V01.00.00 初始化版本

**************************************************************************************************************************************/

--====================================================================================================================================

BEGIN

BEGIN TRY

DECLARE

@begin_time DATETIME

,@end_time DATETIME

,@cost_time INT

,@row_count INT

,@etl_job_id NVARCHAR(100)

,@end_date DATETIME

,@exec_status INT

,@remark NVARCHAR(500)

,@create_date DATETIME

,@create_user NVARCHAR(50)

SET @begin_time = DATEADD(HOUR, 8, GETDATE());

INSERT INTO [chk].[tb_proc_cost_log]

(

[proc_name]

,[Object_name]

,[execute_time]

,[action]

,[remark]

,[cost_time]

)

SELECT

N'chk.usp_insert_etl_job_excc_history' AS [proc_name]

,N'chk.etl_job_excc_history' AS [Object_name]

,@begin_time AS [execute_time]

,N'start' AS [action]

,'' AS [remark]

,0 AS [cost_time]

SET @row_count = 0;

SELECT @row_count = COUNT(*) FROM [chk].[etl_job_list]

WHERE LOWER([etl_job_name]) = LOWER(@etl_job_name);

IF (@row_count = 0)/*etl job name唯一性校驗,保證唯一性*/

BEGIN

RAISERROR(N'etl job name不存在,請重新輸入!', 16, 1);

END

SELECT TOP (1) @etl_job_id = [etl_job_id] FROM [chk].[etl_job_list]

WHERE LOWER([etl_job_name]) = LOWER(@etl_job_name)

ORDER BY [create_date] DESC

SET @begin_date = ISNULL(@begin_date, DATEADD(HOUR, 8, GETDATE()));

SET @end_date = NULL;

SET @exec_status = 2;

SET @remark = NULL;

SET @create_date = DATEADD(HOUR, 8, GETDATE());

SET @create_user = CONVERT(NVARCHAR(50), SUSER_SNAME());

INSERT INTO [chk].[etl_job_excc_history]

(

[exec_id]

,[etl_job_id]

,[etl_job_name]

,[begin_date]

,[end_date]

,[exec_status]

,[remark]

,[create_date]

,[create_user]

)

SELECT

@exec_id

,@etl_job_id

,@etl_job_name

,@begin_date

,@end_date

,@exec_status

,@remark

,@create_date

,@create_user

SET @end_time = DATEADD(HOUR, 8, GETDATE());

SET @cost_time = DATEDIFF(SECOND, @begin_time, @end_time);

INSERT INTO [chk].[tb_proc_cost_log]

(

[proc_name]

,[Object_name]

,[execute_time]

,[action]

,[remark]

,[cost_time]

)

SELECT

N'chk.usp_insert_etl_job_excc_history' AS [proc_name]

,N'chk.etl_job_excc_history' AS [Object_name]

,@end_time AS [execute_time]

,N'end' AS [action]

,CONVERT(NVARCHAR(50), @etl_job_id) AS [remark]

,@cost_time AS [cost_time]

PRINT N'Exec success';

PRINT N'curr_exec_id=' + @exec_id;

END TRY

BEGIN CATCH

INSERT INTO [chk].[log_proc_error_rec]

(

[proc_name]

,[error_source]

,[error_time]

,[error_severity]

,[error_state]

,[error_msg]

,[log_user]

)

SELECT

N'chk.usp_insert_etl_job_excc_history' AS [proc_name]

,ERROR_PROCEDURE() AS [error_source]

,DATEADD(HOUR, 8, GETDATE()) AS [error_time]

,ERROR_SEVERITY() AS [error_severity]

,ERROR_STATE() AS [error_state]

,ERROR_MESSAGE() AS [error_msg]

,SUSER_SNAME() AS [log_user]

PRINT N'Exec failed';

END CATCH

END

IF (OBJECT_ID(N'[chk].[usp_update_etl_job_excc_history_by_exec_id]', N'P') IS NOT NULL)

BEGIN

PRINT N'刪除存儲過程:[chk].[usp_update_etl_job_excc_history_by_exec_id]';

DROP PROC [chk].[usp_update_etl_job_excc_history_by_exec_id];

END

GO

CREATE PROC [chk].[usp_update_etl_job_excc_history_by_exec_id]

(

@exec_id NVARCHAR(100)

,@end_date DATETIME

,@exec_status INT

,@remark NVARCHAR(500)

)

AS

--====================================================================================================================================

-- ProcedureName : chk.usp_update_etl_job_excc_history_by_exec_id

-- Author : john.xiong

-- CreateDate : 2019-01-16

-- Description : update data to chk.etl_job_excc_history

/*************************************Parameters參數說明*******************************************************************************

-- @exec_id : 執行的GUID

-- @end_date : etl job 名稱

-- @exec_status : job運行狀態0運行錯誤,1運行成功,2正在運行....

-- @remark : 說明,如錯誤信息等

**************************************Modfied List修改記錄*****************************************************************************

-- Modified Date Modified User Version Modified Reason

**************************************************************************************************************************************

-- 2019-01-16 john.xiong V01.00.00 初始化版本

**************************************************************************************************************************************/

--====================================================================================================================================

BEGIN

BEGIN TRY

DECLARE

@begin_time DATETIME

,@end_time DATETIME

,@cost_time INT

,@row_count INT

SET @begin_time = DATEADD(HOUR, 8, GETDATE());

INSERT INTO [chk].[tb_proc_cost_log]

(

[proc_name]

,[Object_name]

,[execute_time]

,[action]

,[remark]

,[cost_time]

)

SELECT

N'chk.usp_update_etl_job_excc_history_by_exec_id' AS [proc_name]

,N'chk.etl_job_excc_history' AS [Object_name]

,@begin_time AS [execute_time]

,N'start' AS [action]

,'' AS [remark]

,0 AS [cost_time]

SET @row_count = 0;

SELECT @row_count = COUNT(*) FROM [chk].[etl_job_excc_history]

WHERE [exec_id] = @exec_id;

IF (@row_count = 0)/*檢查exec id是否存在*/

BEGIN

RAISERROR(N'exec id不存在,請重新輸入!', 16, 1);

END

IF (ISNULL(@exec_status, -1) = -1)

BEGIN

RAISERROR(N'exec status不能爲空,請重新輸入!', 16, 1);

END

SET @end_date = ISNULL(@end_date, DATEADD(HOUR, 8, GETDATE()));

SET @remark = ISNULL(@remark, '');

UPDATE [chk].[etl_job_excc_history]

SET end_date = @end_date, [exec_status] = @exec_status, [remark] = @remark

WHERE [exec_id] = @exec_id;

SET @end_time = DATEADD(HOUR, 8, GETDATE());

SET @cost_time = DATEDIFF(SECOND, @begin_time, @end_time);

INSERT INTO [chk].[tb_proc_cost_log]

(

[proc_name]

,[Object_name]

,[execute_time]

,[action]

,[remark]

,[cost_time]

)

SELECT

N'chk.usp_update_etl_job_excc_history_by_exec_id' AS [proc_name]

,N'chk.etl_job_excc_history' AS [Object_name]

,@end_time AS [execute_time]

,N'end' AS [action]

,CONVERT(NVARCHAR(50), @exec_id) AS [remark]

,@cost_time AS [cost_time]

PRINT N'Exec success';

PRINT N'curr_exec_id=' + @exec_id;

END TRY

BEGIN CATCH

INSERT INTO [chk].[log_proc_error_rec]

(

[proc_name]

,[error_source]

,[error_time]

,[error_severity]

,[error_state]

,[error_msg]

,[log_user]

)

SELECT

N'chk.usp_update_etl_job_excc_history_by_exec_id' AS [proc_name]

,ERROR_PROCEDURE() AS [error_source]

,DATEADD(HOUR, 8, GETDATE()) AS [error_time]

,ERROR_SEVERITY() AS [error_severity]

,ERROR_STATE() AS [error_state]

,ERROR_MESSAGE() AS [error_msg]

,SUSER_SNAME() AS [log_user]

PRINT N'Exec failed';

END CATCH

END

c) Job&存儲過程運行記錄表

該表用於記錄每個job 調用存儲過程的情況,如開始結束時間等,也可以記錄下哪些job調用了哪些存儲過程,方便查詢每個job和存儲過程之間的關係。

Ø 參數中的etl_job_name需要用talend的jobName全局變量帶入。

Ø 剩餘的其它參數是該存儲過程實際需要的,用於做業務邏輯處理的參數。

IF (OBJECT_ID(N'[chk].[etl_job_proc_exec_history]', N'U') IS NOT NULL)

BEGIN

PRINT N'刪除表:[chk].[etl_job_proc_exec_history]';

DROP TABLE [chk].[etl_job_proc_exec_history];

END

GO

CREATE TABLE [chk].[etl_job_proc_exec_history]

(

[exec_id] NVARCHAR(100) NOT NULL,--UNIQUEIDENTIFIER用NEWID生成並轉CHAR存儲

[proc_name] NVARCHAR(100) NOT NULL,--存儲過程名

[object_name] NVARCHAR(100) NOT NULL,--操作的對象名字,大部分是表名字、也可以是其它的視圖等

[etl_job_id] NVARCHAR(100) NOT NULL,--UNIQUEIDENTIFIER用NEWID生成並轉CHAR存儲

[etl_job_name] NVARCHAR(200) NOT NULL,--etl job名稱,

[begin_date] DATETIME NULL, --調用開始時間

[end_date] DATETIME NULL, --調用結束時間,如果沒有結束時間就有可能是運行報錯。

[error_msg] NVARCHAR(4000) NULL,--錯誤信息

[remark] NVARCHAR(500) NULL,--備註說明

[create_date] DATETIME NOT NULL, --創建日期

[create_user] NVARCHAR(50) NOT NULL,--創建人

[last_update_date] DATETIME NULL

)

GO

d) 業務執行的存儲過程的改造

存儲過程需要增加一個參數@etl_job_name,這個是在talend中調用存儲過程的時候一起傳遞進來的。

其它的參數都是核心業務處理需要的,和以前的一樣。

如下是一個測試的存儲過程

IF (OBJECT_ID(N'[chk].[usp_job_proc_exec_his_test]', N'P') IS NOT NULL)

BEGIN

PRINT N'刪除存儲過程:[chk].[usp_job_proc_exec_his_test]';

DROP PROC [chk].[usp_job_proc_exec_his_test];

END

GO

CREATE PROC [chk].[usp_job_proc_exec_his_test]

(

@etl_job_name NVARCHAR(200)

,@currDate NVARCHAR(20)/*業務處理邏輯需要用的參數*/

)

AS

BEGIN

BEGIN TRY

DECLARE

@exec_id NVARCHAR(100)

,@proc_name NVARCHAR(100)

,@object_name NVARCHAR(100)

,@etl_job_id NVARCHAR(100)

,@begin_date DATETIME

,@end_date DATETIME

,@error_msg NVARCHAR(4000)

,@remark NVARCHAR(500)

,@create_date DATETIME

,@create_user NVARCHAR(50)

,@last_update_date DATETIME

SET @etl_job_id = '';

SELECT @etl_job_id = [a].[etl_job_id] FROM [chk].[etl_job_list] AS a

WHERE LOWER([a].[etl_job_name]) = LOWER(@etl_job_name)

SET @etl_job_id = ISNULL(@etl_job_id, '');

SET @exec_id = CONVERT(NVARCHAR(100), NEWID());/*生成exec_id*/

SET @proc_name = 'chk.job_proc_exec_his_test';

SET @object_name = 'you_table_name';/*例如:stg.envt_ids_sales_daily*/

SET @begin_date = DATEADD(HOUR, 8, GETDATE());

SET @create_date = @begin_date;

SET @last_update_date = @create_date;

SET @create_user = CONVERT(NVARCHAR(50), SUSER_SNAME());

SET @end_date = NULL;

SET @remark = @currDate;

/*記錄開始*/

INSERT INTO [chk].[etl_job_proc_exec_history]

(

[exec_id]

,[proc_name]

,[object_name]

,[etl_job_id]

,[etl_job_name]

,[begin_date]

,[end_date]

,[error_msg]

,[remark]

,[create_date]

,[create_user]

,[last_update_date]

)

SELECT

@exec_id

,@proc_name

,@object_name

,@etl_job_id

,@etl_job_name

,@begin_date

,@end_date

,NULL

,@remark

,@create_date

,@create_user

,@last_update_date

/*其它的業務處理邏輯*/

--SELECT 1/0 AS [ret]/*樣例:有意引發錯誤*/

SELECT DATEADD(HOUR, 8, GETDATE());

/*記錄正常結束*/

SET @end_date = DATEADD(HOUR, 8, GETDATE());

SET @last_update_date = @end_date;

UPDATE [chk].[etl_job_proc_exec_history]

SET [end_date] = @end_date, [last_update_date] = @last_update_date

WHERE [exec_id] = @exec_id;

PRINT N'Exec success';

END TRY

BEGIN CATCH

INSERT INTO [chk].[log_proc_error_rec]

(

[proc_name]

,[error_source]

,[error_time]

,[error_severity]

,[error_state]

,[error_msg]

,[log_user]

)

SELECT

N'chk.job_proc_exec_his_test' AS [proc_name]

,ERROR_PROCEDURE() AS [error_source]

,DATEADD(HOUR, 8, GETDATE()) AS [error_time]

,ERROR_SEVERITY() AS [error_severity]

,ERROR_STATE() AS [error_state]

,ERROR_MESSAGE() AS [error_msg]

,SUSER_SNAME() AS [log_user]

/*記錄異常結束*/

SET @end_date = DATEADD(HOUR, 8, GETDATE());

SET @last_update_date = @end_date;

SET @error_msg = ERROR_MESSAGE();

UPDATE [chk].[etl_job_proc_exec_history]

SET [end_date] = @end_date, [error_msg] = @error_msg, [last_update_date] = @last_update_date

WHERE [exec_id] = @exec_id;

PRINT N'Exec failed';

END CATCH

END

2、 talend job記錄每個job的開始和結束信息

11

設置exec id,通過UUID獲取,還有其它的一些變量

12

記錄開始

13

創建結束的一些參數

14

更新結束的記錄

15


三、總結

1、 Talend 的tac因爲一些調度薄弱,所以我們的job就需要記錄更多的一些信息來輔助後期的管理和追查原因。

2、 藉助這套日誌小框架,我們也可以更好的管理talend通過調用存儲過程這樣子的方式的job,提升一些可管理性、錯誤識別方面的能力。

3、 Talend的job的統一錯誤處理感覺還是比較薄弱,就是能有一個統一的錯誤處理的如果,而不用依賴於每個組件去判斷是否有發生錯誤。(可能我還沒有發現吧)

如果您覺得此文章對您有幫助,請點擊右下方【推薦】讓更多人看到,thanks!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章