kettle簡介
Kettle是一款免費開源的基於Java的企業級ETL工具,功能強大簡單易用,無可抗拒。
kettle有兩個比較重要且常用的腳本文件:1)轉換(Transformation)和作業(Job),其中轉換是對數據處理的容器,包含對數據的各種處理,有多個步驟(Step)組成;作業相對於轉換可以配置出更多高級的操作,可以將多個轉換組合成一塊進行數據處理
kettle的使用方式
1.圖形化界面工具(spoon)
上圖截取了數據處理的轉換腳本,可以看出基於圖形化界面操作kettle進行數據處理,只需按照數據處理的流程配置相應的步驟即可,簡單易用,但不適合在程序中集成
2.依賴jar包的方式
應用程序集成kettle更多采用的是maven依賴jar包的方式,在jar包依賴之後可以通過兩種方式對數據進行處理:
1)通過調用kettle腳本的方式:
在kettle圖像化界面配置好腳本(工作或轉換),然後通過應用程序加載執行腳本即可完成對數據的處理操作,程序實例如下:
// 轉換腳本路徑
String filename = "C:/Desktop/person_import_data.ktr";
// 初始化kettle環境
KettleEnvironment.init();
// new tran的源數據對象
TransMeta transMeta = new TransMeta(filename);
// 創建tran對象
Trans trans = new Trans(transMeta);
// 異常處理
trans.prepareExecution(null);
// 開始執行
trans.startThreads();
// 記錄最後一個步驟的數據
final List<RowMetaAndData> rows = new ArrayList<RowMetaAndData>();
RowListener rowListner = new RowListener() {
public void rowWrittenEvent(RowMetaInterface rowMeta, Object[] row)
throws KettleStepException {
rows.add(new RowMetaAndData(rowMeta, row));
}
public void rowReadEvent(RowMetaInterface arg0, Object[] arg1)
throws KettleStepException {
}
public void errorRowWrittenEvent(RowMetaInterface arg0,Object[] arg1) throws KettleStepException {
}
};
List<StepMetaDataCombi> steps = trans.getSteps();
String stepname = steps.get(steps.size() - 1).stepname;
StepInterface stepInterface = trans.findRunThread(stepname);
stepInterface.addRowListener(rowListner);
// 等待執行完畢
trans.waitUntilFinished();
if (trans.getErrors() > 0) {
log.error(LogFormatter.toLog(CommonErrorCode.ERR_ERROR, "message"), "transformation of kettle occurred error while extracting data");
throw new BaseRuntimeException(CommonErrorCode.ERR_ERROR);
}
for (int i = 0; i < rows.size(); i++) {
RowMetaAndData rmad = rows.get(i);
String[] fields = rmad.getRowMeta().getFieldNames();
Map<String, Object> map = new HashMap<>();
for (String field : fields) {
map.put(field, rmad.getString(field, null));
}
list.add(map);
}
2)調用kettle的api:通過kettle的api可以模擬步驟(step),脫離圖形化界面,下面通過kettle的api模擬了一個表輸入步驟,但是通過kettle的api模型步驟,適用常用的步驟,很多步驟在api中是沒有的
//添加數據連接
DatabaseMeta dataBaseInput = new DatabaseMeta("DbInput", dbInfo.getDbType(), "Native", dbInfo.getIp(), dbInfo.getDbName(),dbInfo.getPort(), dbInfo.getUser(), dbInfo.getPassWord());
transMeta.addDatabase(dataBaseInput);
//表輸入
TableInputMeta tableInputMeta = new TableInputMeta();
tableInputMeta.setDatabaseMeta(transMeta.findDatabase("DbInput"));
tableInputMeta.setSQL(dbInfo.getSql());
StepMeta inputStep = new StepMeta("table",tableInputMeta);
//inputStep.setLocation(50,50);
inputStep.setDraw(true);
transMeta.addStep(inputStep);
kettle性能分析
在對數據進行同步時,測試了分別在數據庫中生成10萬、100萬、1000萬和1億數據,通過kettle處理入庫,觀察其性能。性能如下表所示:
數據量(萬條) | 同步時間(s) |
10 | 3.8 |
100 | 37.5 |
1000 | 620 |
10000 | 5987 |
常見問題
- Kettle連接mysql並不支持目前springboot規定的mysql-connector-java版本(8.0.19),可以用5.1.47版本的驅動解決這個問題
- Oracle可以根據數據庫服務名(service_name)和數據庫實例名(instance_name,SID)連接數據庫,jdbc連接oracle時,可以根據不同的url形式,決定採用service_name還是instance_name進行連接;kettle默認是採用instance_name連接oracle數據庫的,如果想要採用service_name連接oracle,則需要在service_name前加上“/”。