适用于groupBy的AWS EMR Spark应用有超过300,000个组

时间:2019-03-04 18:52:19

标签: amazon-web-services apache-spark amazon-emr

步骤:

1)从S3(140-200 GB)读取文件。

2)然后我应用filter()函数,以删除记录的大多数映射(将删除大约70%)。

3)对于剩余的记录(总计约40-50 GB),请使用map()创建MyObj的JavaRdd。

4)之后,我使用group by按sesisonId字段对对象进行分组。对于40-50 GB的总空间,我预计groupBy中将有大约300,000个组。

5)然后,对于每个组,我执行processSingeGroupOfEvents()(此函数如下:它需要Interable,然后为每个Iterable进行一些简单的工作(总计300,000个))。

6)之后,我使用coalesce()和saveAsTextFile将结果输出到S3(输出文件大小约为1-2 GB)。

伪代码:

 JavaRDD<MyObj> eventsCollection = context.textFile(input)
                .filter(data -> applySomeFilter(data))      // This will filter ~70% of records 
                .map(data ->  createMyObjFromData(data));

JavaPairRDD<String, Iterable<MyObj>> eventsCollectionGroupedById = eventsCollection
                .groupBy(x -> x.getSessionId())
                .persist(StorageLevel.MEMORY_AND_DISK());;

JavaPairRDD<String, String> groupedByIdResults = eventsCollectionGroupedById
                .mapValues(iterable -> processSingeGroupOfEvents(iterable, additionalVariable1, additionalVariable2 ));

groupedByIdResults
                .coalesce(1) // Union all partitions into single one (in order to avoid multiple output files)
                .map(data ->  data._2()) 
                .saveAsTextFile(outputS3Location);

我对AWS EMR Spark应用程序的当前配置是:

  • 4个r3.8xlarge核心实例类型
  • 主节点的r3.8xlarge中有1个
  • EMR发行标签:emr-5.11.0
  • maximizeResourceAllocation = true。
  • Spark 1.4版(我现在无法将Spark更新到最新版本)

目前,大约需要30到50分钟才能执行此作业。但是,将来,我希望输入数据的大小将增加一倍(〜300 GB数据=>〜600,000个组,以根据会话ID进行汇总)

我如何估计,如果我的数据加倍,我的集群将能够处理这样的负载?另外,有时我会出错,说r3.8xlarge实例类型超出了我所在区域的配额限制,因此我担心如果添加更多硬件,则会更经常出现此问题。

更新: processSingeGroupOfEvents()方法对具有相同会话ID的事件组(可迭代)进行迭代,并执行一些棘手的计算(例如,计算运行总计,查找组中某些元素的最大值,解析时间戳等)。它会返回逗号分隔的字符串,其中包含特定会话ID的汇总值。

1 个答案:

答案 0 :(得分:1)

processSingeGroupOfEvents是否减少了数据量?如果是,则用groupBy替换mapValuesaggregateByKey可以大大减少要重排的数据量。

之后,我建议您遵循通用的Spark调整指南https://spark.apache.org/docs/latest/tuning.html。检查Spark Web UI的垃圾回收时间。 EMR随Ganglia一起提供,可用于监视群集中的各个节点。节点之间的CPU和内存使用是否均匀?

最后,您可以使用当前的数据量执行作业,但将集群中的节点数减半。如果工作完成但花费了大约两倍的时间,则这是一个很好的信号,表明负载分布均匀并且可能会扩大。如果它崩溃或没有显着降低速度,则说明该工作存在一些严重的瓶颈。