为什么仅在清理累加器步骤

时间:2017-09-08 21:36:31

标签: apache-spark pyspark

我使用c4.2xlarge(15GB RAM / 8核心)类型的3个EC2实例启动了一个spark集群,然后将其命名为A,B和C.

配置A: 我把它作为master-server.sh启动了 start-master.sh

在这个集群上,我只推出了3个执行器。使用以下命令 start-slave.sh <master-uri> -c 3

配置B和C:

我通过在每个实例上运行以下命令在两个实例上创建了8个执行程序。

start-slave.sh <master-uri> -c 8

现在我的代码如下:

# Loading wiki dumps files.
lines = spark.read.text(sys.argv[1]).rdd.map(lambda r: r[0].encode("utf-8"))

# Running word count algorithm. and selecting with count as 1.
counts = lines.flatMap(lambda x: x.lower().split(' ')) \
              .map(lambda x: (x, 1)) \
              .reduceByKey(add) \
                .filter(lambda x: x[1] == 1) \
                .map(lambda (x,y): x)

# Making Dataframe from RDD.
df = lines.map(lambda x: (x, )).toDF(['raw_sentence'])

# Tokenizing using spark ml API.
fl = Tokenizer(inputCol="raw_sentence", outputCol="words")
df = fl.transform(df).select("words")

# Removing Stopwords. Pay attention I am converting counts to list iterator.
fl = StopWordsRemover(inputCol="words", outputCol="filtered")
fl.setStopWords(fl.getStopWords() + list(counts.toLocalIterator()))
df = fl.transform(df).select("filtered")

最初我开始工作的时候。我的服务器A,B和C正在使用所有核心。但是过了一段时间我的B和C内核不会使用任何内存 或核心,在此阶段是日志:

  

17/09/08 20:31:54 INFO BlockManagerInfo:删除了broadcast_0_piece0   172.31.35.55:45288在内存中(大小:25.0 KB,免费:6.2 GB)17/09/08 20:31:54 INFO BlockManagerInfo:删除了broadcast_0_piece0 on   172.31.44.209:39094在内存中(大小:25.0 KB,免费:6.2 GB)17/09/08 20:31:54 INFO ContextCleaner:清理累加器51

     

17/09/08 21:13:51 WARN HeartbeatReceiver:删除执行者2号   最近的心跳:232069 ms超过超时120000 ms 17/09/08   21:26:15 ERROR TaskSchedulerImpl:172.31.44.209上丢失的执行者2:   执行者心跳在232069 ms后超时   17/09/08 21:27:09错误TransportRequestHandler:发送结果时出错   RpcResponse {的requestId = 8270848140270032673,   body = NioManagedBuffer {buf = java.nio.HeapByteBuffer [pos = 0 lim = 47   cap = 64]}}到/172.31.44.209:33418;关闭连接   java.io.IOException:管道损坏

enter image description here

我的代码的第47行是上面代码的第二行,如下所示:

fl.setStopWords(fl.getStopWords() + list(counts.toLocalIterator()))

自定义配置是: SPARK_EXECUTOR_MEMORY = 12G

休息是默认值。

那么为什么第47行的任务没有按分布式运行? 为什么它崩溃了,即使我有额外的资源,特别是RAM?

1 个答案:

答案 0 :(得分:0)

RDD.toLocalIterator当时提取单个分区。所以执行模式将类似于:

  1. 计算单个分区。这可能需要来自单个执行程序(没有广泛的依赖项)或多个执行程序的活动。
  2. 数据被提取到驱动程序,本地线程开始迭代。驱动程序处于活动状态,其余代码处于空闲状态。
  3. 一旦到达块的末尾,并且有更多分区要遵循,驱动程序将请求下一个分区(转到1.)。
  4. 由于您将迭代器转换为list,因此您也可以collect。内存消耗将是相同的(并可能导致失败)但所有节点将计算其部件而不会暂停。