好吧。从哪里开始?我正在将一组Spark应用程序部署到Kubernetes集群。我有一个Spark Master,2个Spark Workers,MariaDB,一个Hive Metastore(使用MariaDB -它不是一个完整的Hive安装-它只是Metastore),和一个Spark Thrift Server(与Hive Metastore对话并实现Hive API)。
因此,除了Thrift服务器作业的设置(thrift服务器pod上Spark sbin目录中的start-thriftserver.sh)之外,这个设置可以很好地工作。通过良好的工作,我说我可以在集群之外创建spark作业并将其提交给master,然后使用Web UI,我可以看到我的代码测试应用程序使用两个worker运行完成。
现在问题来了当您启动www.example.com时start-thriftserver.sh,它会将自己作为驱动程序提交给集群(我相信,这是正确的行为)。当我通过WebUI查看相关的spark作业时,我看到它有工人,他们反复孵化,然后很快退出。当我查看worker的stderr日志时,我看到每个worker都启动并尝试连接回spark. driver. port上的thrift服务器pod。我认为这是正确的行为。问题是连接失败,因为它说未知的主机异常,并且它使用了thrift服务器pod的kubernetes原始pod名称(不是服务名称,名称中没有IP)来表示它找不到发起连接的thrift服务器。现在,Kubernetes DNS存储服务名称,然后仅存储pod名称,以其私有IP为前缀。换句话说,pod的原始名称(没有IP)从未向DNS注册。这不是Kubernetes的工作方式。
所以我的问题是。我正在努力弄清楚为什么spark worker pod使用一个原始pod名称来尝试查找thrift服务器。它似乎永远不应该这样做,而且永远不可能满足这一要求。我想知道是否有一些spark配置设置,可以告诉工人它需要搜索的(节俭)驱动实际上是spark-thriftserver. my-namespace. svc。但我找了半天也没找到。
有这么多的设置,进入这样的集群,我不想弹幕你的信息。有一件事可以澄清我的设置:以下字符串被转储到失败的工作日志的顶部。请注意driver-url的节俭服务器的原始pod名称。如果有人有任何线索采取什么步骤来解决这个问题,请让我知道。我会编辑这篇文章和分享设置等人们的要求。谢谢你帮忙
Spark Executor Command: "/usr/lib/jvm/java-1.8-openjdk/jre/bin/java" "-cp" "/spark/conf/:/spark/jars/*" "-Xmx512M" "-Dspark.master.port=7077" "-Dspark.history.ui.port=18081" "-Dspark.ui.port=4040" "-Dspark.driver.port=41617" "-Dspark.blockManager.port=41618" "-Dspark.master.rest.port=6066" "-Dspark.master.ui.port=8080" "org.apache.spark.executor.CoarseGrainedExecutorBackend" "--driver-url" "spark://CoarseGrainedScheduler@spark-thriftserver-6bbb54768b-j8hz8:41617" "--executor-id" "12" "--hostname" "172.17.0.6" "--cores" "1" "--app-id" "app-20220408001035-0000" "--worker-url" "spark://Worker@172.17.0.6:37369"
1条答案
按热度按时间col17t5w1#
以下是如何成功运行Spark Thrift Service on Kubernetes的简要指南:
Spark Thrift Server是Spark的多用户JDBC/ODBC可访问服务,可以按照Spark Thrift Server的设计以客户端模式部署在Kubernetes上。这意味着Spark Submit在客户端模式下运行时,将在执行spark-submit命令的节点上启动。为了克服设计限制,您可以在客户端模式下从Kubernetes中的节点启动Thrift Server,使该节点成为驱动程序。
在客户端模式下在Kubernetes上运行Spark时需要考虑几个关键点:
*客户端组网:Spark执行器必须能够通过可路由的主机名和端口连接到Spark驱动程序。您可以使用headless服务为您的驱动程序pod提供一个稳定的、可路由的主机名。这可以通过
spark.driver.host
和spark.driver.port
来指定。*客户端模式Executor Pod垃圾回收:如果您的Spark驱动程序在Pod中运行,强烈建议将
spark.kubernetes.driver.pod.name
设置为该Pod的名称。这确保了一旦驱动程序pod从集群中删除,应用程序的所有执行器pod都将被删除。*Executor Pod清理:如果您的应用程序没有在pod中运行,或者当您的应用程序在pod中运行时没有设置
spark.kubernetes.driver.pod.name
,则当应用程序退出时,executor pod可能不会被正确删除。*主控Executor Pod名称:您可以使用
spark.kubernetes.executor.podNamePrefix
来控制执行器pod名称。使其在同一命名空间中的所有作业中唯一,以避免冲突。部署包括两个部分:Service和StatefulSet。该服务对于集群内的网络访问至关重要,并允许Spark执行器通过可路由的主机名和端口连接到Spark驱动程序。您可以定义公开两个端口的无头服务:一个用于Thrift服务器,另一个用于Spark驱动程序。
StatefulSet将管理Spark Thrift Server的部署。在StatefulSet配置中,您将指定Spark Thrift Server镜像、启动Thrift Server的命令以及几个Spark配置。使用StatefulSet而不是Deployment或ReplicaSet的关键决定主要是由于需要一致的pod名称,这是
spark.kubernetes.driver.pod.name
配置提出的要求。Kubernetes中的StatefulSet通过提供稳定和可预测的pod名称来内在地支持这一要求,无论是否重新调度。总之,由于设计限制,在Kubernetes上运行Spark Thrift Server需要在客户端模式下运行服务器。
简短的例子: