【发布时间】:2017-05-24 17:12:01
【问题描述】:
在启用 Kerberos 的 Hadoop 集群方面面临一个问题。
我们正在尝试在 yarn-cluster 上运行流式作业,它与 Kafka(直接流)和 hbase 交互。
不知何故,我们无法在集群模式下连接到 hbase。我们使用keytab登录hbase。
这就是我们所做的:
spark-submit --master yarn-cluster --keytab "dev.keytab" --principal "dev@IO-INT.COM" --conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=log4j_executor_conf.properties -XX:+UseG1GC" --conf "spark.driver.extraJavaOptions=-Dlog4j.configuration=log4j_driver_conf.properties -XX:+UseG1GC" --conf spark.yarn.stagingDir=hdfs:///tmp/spark/ --files "job.properties,log4j_driver_conf.properties,log4j_executor_conf.properties" service-0.0.1-SNAPSHOT.jar job.properties
要连接到 hbase:
def getHbaseConnection(properties: SerializedProperties): (Connection, UserGroupInformation) = {
val config = HBaseConfiguration.create();
config.set("hbase.zookeeper.quorum", HBASE_ZOOKEEPER_QUORUM_VALUE);
config.set("hbase.zookeeper.property.clientPort", 2181);
config.set("hadoop.security.authentication", "kerberos");
config.set("hbase.security.authentication", "kerberos");
config.set("hbase.cluster.distributed", "true");
config.set("hbase.rpc.protection", "privacy");
config.set("hbase.regionserver.kerberos.principal", “hbase/_HOST@IO-INT.COM”);
config.set("hbase.master.kerberos.principal", “hbase/_HOST@IO-INT.COM”);
UserGroupInformation.setConfiguration(config);
var ugi: UserGroupInformation = null;
if (SparkFiles.get(properties.keytab) != null
&& (new java.io.File(SparkFiles.get(properties.keytab)).exists)) {
ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(properties.kerberosPrincipal,
SparkFiles.get(properties.keytab));
} else {
ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(properties.kerberosPrincipal,
properties.keytab);
}
val connection = ConnectionFactory.createConnection(config);
return (connection, ugi);
}
然后我们连接到 hbase: ….
foreachRDD { rdd =>
if (!rdd.isEmpty()) {
//var ugi: UserGroupInformation = Utils.getHbaseConnection(properties)._2
rdd.foreachPartition { partition =>
val connection = Utils.getHbaseConnection(propsObj)._1
val table = …
partition.foreach { json =>
}
table.put(puts)
table.close()
connection.close()
}
}
}
Keytab 文件没有被复制到 yarn staging/temp 目录,我们没有在 SparkFiles.get 中得到它……如果我们通过 --files 传递 keytab,spark-submit 会失败,因为它已经在 --keytab 中了。
【问题讨论】:
-
Spark 在内部使用
--principal/--keytab(或匹配的属性spark.yarn.principal/.keytab),您不必关心代码中的 UGI。由于 Spark 1.4,Launcher 应该在驱动程序启动之前获得一个“HBase 令牌”,并将其广播给执行程序——hbase-spark库(由 Cloudera 提供)提供了一个包装器,用于管理“token”自动在执行者端,所以你应该试一试...... -
顺便说一句,实际的错误消息会比您的源代码有用得多——这也是实际的 Spark 版本。
-
版本:scala:2.10.5 spark:1.6.0 hbase-client:1.2.0
-
最初我们得到:因为它无法从 SparkFiles 获取 keytab。 org.apache.hadoop.security.KerberosAuthException:用户登录失败:来自 keytab dev.keytab javax.security.auth.login.LoginException 的 dev@IO-INT.COM:无法从 org.apache.hadoop 的用户处获取密码。 security.UserGroupInformation.loginUserFromKeytabAndReturnUGI 如果我们删除 loginUserFromKeytabAndReturnUGI,假设在内部它会得到照顾,我们开始得到: org.apache.hadoop.hbase.ipc.FailedServerException: This server is in the failed servers list hbase
-
再一次,为什么不使用专门为 Spark 创建的 HBase API? hbase.apache.org/book.html#_basic_spark
标签: apache-spark hbase kerberos