本文目的:记录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的引用。