本文目的:記錄Kerberos環境下,通過Kettle將MySQL數據清洗到HDFS過程解決的2個問題,希望對大家有所幫助。
Kettle版本:pdi-ce-7.1.0.0-12
1、在Kerberos與Kettle集成過程中,我們有如下場景:將數據從MySQL定時抽出,然后寫到HDFS。
在從MySQL取數並寫入HDFS過程中,需要Kettle取得KDC認證,但無論怎么配置,還是無法解決寫入HDFS的時候安全認證問題。我們最終定位是Kettle與Kerberos集成的問題。(在Kettle中通過Hive寫HDFS依然有問題,不過我們自己解決了)。所以,如果要解決這個問題,方案有2:
a、通過StreamSets或者NiFi實時拉取MySQL數據到HDFS,而StreamSets或者NiFi本身和Kerberos能較好的集成在一起。
b、通過sqoop實現。
a方案看起來很美好,但是在我們的場景下,有幾個問題需要解決:
a、從MySQL寫入HDFS只是整個ETL任務的其中一環,如果用方案1,那么任務的前后銜接如何處理?
b、從MySQL寫入HDFS的任務中,需要一些輸入參數(需要讀取的MySQL表,讀取數據的時間),而目前1方案還無法支持靈活的輸入參數配置。
所以我們選擇了b方案。在這個方案中,
a、通過Kerberos配置可以保證Client有sqoop訪問數據庫和文件系統的權限
b、將Kettle中的MySQL抽數並寫入HDFS的過程包裝成shell腳本,將sqoop需要的輸入參數query和target-dir等參數外部傳入。
2、在實現方案b的時候,我們將sqoop import的參數動態傳入,類似
./xxx.sh sql target-dir值
xxx.sh 的內容非常簡單:
sqoop import --connect jdbc:mysql://ip:3306/db --username userXXX --password passXXX --target-dir $2 --fields-terminated-by '|' --split-by 'ID' --m 1 --as-textfile --num-mappers 10 --query $1
注意sqoop import的格式是--query '...'/--query "..." ,query內容前后用了引號,所以在$1引用的時候必須用"$1",否則sqoop會報"uncategorized parameter ..."
sqoop import --connect jdbc:mysql://ip:3306/db --username userXXX --password passXXX --target-dir $2 --fields-terminated-by '|' --split-by 'ID' --m 1 --as-textfile --num-mappers 10 --query "$1"
另外需要注意的是shell中,'$1'和"$1"是有區別的,如果某個變量賦值為'$1',則打印的結果還是'$1';如果是"$1",則會打印$1的引用。