使用 Kerberos 设置 Spark SQL 连接
Posted
技术标签:
【中文标题】使用 Kerberos 设置 Spark SQL 连接【英文标题】:Setting up a Spark SQL connection with Kerberos 【发布时间】:2017-12-14 21:06:21 【问题描述】:我有一个简单的 Java 应用程序,它可以使用 Hive 或 Impala 连接和查询我的集群,使用类似的代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
...
Class.forName("com.cloudera.hive.jdbc41.HS2Driver");
Connection con = DriverManager.getConnection("jdbc:hive2://myHostIP:10000/mySchemaName;hive.execution.engine=spark;AuthMech=1;KrbRealm=myHostIP;KrbHostFQDN=myHostIP;KrbServiceName=hive");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from foobar");
但现在我想尝试使用 Spark SQL 执行相同的查询。不过,我很难弄清楚如何使用 Spark SQL API。具体如何设置连接。我看到了如何设置 Spark Session 的示例,但不清楚我需要提供哪些值
SparkSession spark = SparkSession
.builder()
.appName("Java Spark SQL basic example")
.config("spark.some.config.option", "some-value")
.getOrCreate();
我如何告诉 Spark SQL 使用什么主机和端口,使用什么架构,以及我如何告诉 Spark SQL 我正在使用哪种身份验证技术?例如,我使用 Kerberos 进行身份验证。
以上Spark SQL代码来自https://github.com/apache/spark/blob/master/examples/src/main/java/org/apache/spark/examples/sql/JavaSparkSQLExample.java
更新:
我取得了一些进展,我想我知道如何告诉 Spark SQL 连接使用什么主机和端口。
...
SparkSession spark = SparkSession
.builder()
.master("spark://myHostIP:10000")
.appName("Java Spark Hive Example")
.enableHiveSupport()
.getOrCreate();
我在 pom.xml 文件中添加了以下依赖项
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-hive_2.11</artifactId>
<version>2.0.0</version>
</dependency>
通过此更新,我可以看到连接越来越远,但现在似乎失败了,因为我没有通过身份验证。我需要弄清楚如何使用 Kerberos 进行身份验证。这是相关的日志数据
2017-12-19 11:17:55.717 INFO 11912 --- [o-auto-1-exec-1] org.apache.spark.util.Utils : Successfully started service 'SparkUI' on port 4040.
2017-12-19 11:17:55.717 INFO 11912 --- [o-auto-1-exec-1] org.apache.spark.ui.SparkUI : Bound SparkUI to 0.0.0.0, and started at http://myHostIP:4040
2017-12-19 11:17:56.065 INFO 11912 --- [er-threadpool-0] s.d.c.StandaloneAppClient$ClientEndpoint : Connecting to master spark://myHostIP:10000...
2017-12-19 11:17:56.260 INFO 11912 --- [pc-connection-0] o.a.s.n.client.TransportClientFactory : Successfully created connection to myHostIP:10000 after 113 ms (0 ms spent in bootstraps)
2017-12-19 11:17:56.354 WARN 11912 --- [huffle-client-0] o.a.s.n.server.TransportChannelHandler : Exception in connection from myHostIP:10000
java.io.IOException: An existing connection was forcibly closed by the remote host
【问题讨论】:
Spark 原生集成到 Hive Metastore 和 HDFS。在其他作品中,它不应该使用到 Impala 或 HS2 的 JDBC 连接;因为它取代了它们。 在 Linux 中,定义 env var HADOOP_CONF_DIR 以指向包含 Hadoop 和 Hive 的 conf 文件的目录(或多个目录)。在 Windows 中...由于 Hadoop 实现 Kerberos 身份验证的方式,它要复杂得多。 阅读HiveContext
——如果你有一个带有Hive集成的Spark构建,并且在启动时检测到conf文件,那么它就像启动一个spark-shell并输入spark.sql("show databases").show
一样简单
对于 Windows 调整,找到 Jacek Laskowski 的 GitBook “掌握 Apache Spark 2” 并直接转到“在 Windows 上运行 Spark 应用程序”。我可以对使用 HADOOP_HOME 和 PATH 而不是 -Dhadoop.home 和 -Djava.library.path 进行一些挑剔,但他的建议很有效。
@SamsonScharfrichter 如果您想创建答案,我已经在这个问题上创建了 50 分赏金。我刚刚意识到你提到的那本书是在线免费的,所以我现在正在阅读。
【参考方案1】:
您可以尝试在运行连接之前进行 Kerberos 登录:
Configuration conf = new Configuration();
conf.set("fs.hdfs.impl", DistributedFileSystem.class.getName());
conf.addResource(pathToHdfsSite);
conf.addResource(pathToCoreSite);
conf.set("hadoop.security.authentication", "kerberos");
conf.set("hadoop.rpc.protection", "privacy");
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(ktUserName, ktPath);
//your code here
ktUserName 是这里的主体,例如 - user@TEST.COM 你需要在你的机器上安装 core-site.xml、hdfs-site.xml 和 keytab 来运行它。
【讨论】:
【参考方案2】:Dataframe creation using Impala with Kerberos authentication
我可以通过 kerberos 身份验证进行 Impala 连接。在这里查看我的 git 存储库。也许这会有所帮助。
【讨论】:
以上是关于使用 Kerberos 设置 Spark SQL 连接的主要内容,如果未能解决你的问题,请参考以下文章
Oozie Spark 使用 kerberos 访问 hive
在远程集群上从 Spark 运行 hive 查询时,客户端无法通过以下方式进行身份验证:[TOKEN, KERBEROS]