我有一个关于Apache Spark的一般性问题:
我们有一些spark流脚本使用Kafka消息。问题:它们随机失败而没有特定的错误…
当我手动运行它们时,有些脚本在工作时什么也不做,其中一个失败的消息是:
ERROR SparkUI: Failed to bind SparkUI地址已在使用:Service 'SparkUI'重试16次后失败!
所以我想知道是否有一种特定的方式来并行运行脚本?
它们都在同一个jar中,我用Supervisor运行它们。Spark安装在Cloudera Manager 5.4 on Yarn上
下面是我启动脚本的方法:sudo -u spark spark-submit --class org.soprism.kafka.connector.reader.TwitterPostsMessageWriter /home/soprism/sparkmigration/data-migration-assembly-1.0.jar --master yarn-cluster --deploy-mode client
谢谢你的帮助!
更新:我改变了命令,现在运行这个(它停止了现在特定的消息):
root@ns6512097:~# sudo -u spark spark-submit --class org.soprism.kafka.connector.reader.TwitterPostsMessageWriter --master yarn --deploy-mode client /home/soprism/sparkmigration/data-migration-assembly-1.0.jar
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/cloudera/parcels/CDH-5.4.7-1.cdh5.4.7.p0.3/jars/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/opt/cloudera/parcels/CDH-5.4.7-1.cdh5.4.7.p0.3/jars/avro-tools-1.7.6-cdh5.4.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
15/09/28 16:14:21 INFO Remoting: Starting remoting
15/09/28 16:14:21 INFO Remoting: Remoting started; listening on addresses :[akka.tcp://sparkDriver@ns6512097.ip-37-187-69.eu:52748]
15/09/28 16:14:21 INFO Remoting: Remoting now listens on addresses: [akka.tcp://sparkDriver@ns6512097.ip-37-187-69.eu:52748]
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/cloudera/parcels/CDH-5.4.7-1.cdh5.4.7.p0.3/jars/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/opt/cloudera/parcels/CDH-5.4.7-1.cdh5.4.7.p0.3/jars/avro-tools-1.7.6-cdh5.4.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
如果多个用户试图同时启动spark会话或现有的spark会话没有属性关闭,则会发生此问题
有两种方法可以解决这个问题。
-
在不同的端口上启动新的spark会话,如下
spark-submit --conf spark.ui.port=5051 <other arguments>`<br>`spark-shell --conf spark.ui.port=5051
-
查找使用4041 ~ 4056端口的所有spark会话并使用kill命令杀死进程,netstat和kill命令可以分别查找占用该端口的进程并杀死进程。用法如下:
sudo netstat -tunalp | grep LISTEN| grep 4041
以上命令将产生如下输出,最后一列是进程id,在本例中PID是32028
tcp 0 0 :::4040 :::* LISTEN 32028/java
一旦你找到了进程id(PID),你可以使用下面的命令杀死spark进程(spark-shell或spark-submit)
sudo kill -9 32028
您还可以增加spark.port.maxRetries
的值集。
根据文档:
绑定端口后放弃的最大重试次数。当端口被给定特定值(非0)时,每次后续重试都会在重试之前将前一次尝试中使用的端口增加1。这实际上允许它尝试从指定的起始端口到port + maxRetries的一系列端口。
以上答案正确。
但是,我们不应该尝试更改spark.port.maxRetries
值,因为这会增加同一服务器上的负载,从而降低集群性能并可能将节点推入死锁状态。可以在会话中使用uptime
命令检查负载
这个问题的根本原因是当您试图通过--deploy-mode client
运行所有spark应用程序时。
如果您的集群中有分布式容量,最好的方法是使用--deploy-mode cluster
运行它。
这样,每次它都会在不同的节点上运行spark应用程序,从而减轻了同一节点上的端口绑定问题。
希望这对你有帮助。干杯!