有啥方法可以提高火花写入性能?
Posted
技术标签:
【中文标题】有啥方法可以提高火花写入性能?【英文标题】:Is there any way to improve spark write performance?有什么方法可以提高火花写入性能? 【发布时间】:2020-08-27 06:53:24 【问题描述】:我正在将数据从 elasticsearch 移动到 hdfs。 数据大小约200GB,8000万条数据。
这是我的代码。非常简单。只需读取es,然后写入hdfs。
// 1. config setting
public Map<String, String> esConfigParam()
return new ImmutableMap.Builder<String, String>()
.put("es.nodes", params.getEsNodes())
.put("es.mapping.date.rich", "false")
.put("pushdown", "true")
.put("es.scroll.size", params.getScrollSize())
.put("es.read.field.as.array.include","label")
.put("es.input.json", "true")
.put("es.read.metadata", "true").build();
// 2. load ES data
Dataset<Row> dataSet = JavaEsSparkSQL.esDF(session.getSqlContext(), indexAlias, esConfigParam());
// 3. write to hdfs
dataSet.write()
.mode(SaveMode.Overwrite)
.option("compression", "gzip")
.parquet(params.getWritePath());
我认为以下是提高性能的调整点。
-
火花设置:
executor-cores 5 / num-executors 16 / executor-memory 4g / driver-memory 4g
ES 读取设置:params.getScrollSize()=2000
在这种情况下大约需要 30 分钟。 请告诉我如何通过提高写入性能来缩短时间。 (例如,申请 colesce(10) ??)
【问题讨论】:
【参考方案1】:非常有趣的问题!
为了讨论建议,我假设您的集群有 4 个节点,每个节点 16 个核心,每个节点 64GB。
(对于您的特定情况,您需要了解此信息并应用以下示例)
由于三个原因,您无法使用集群的所有资源:
每个节点至少需要 1 个内核和 1GB 来运行 OS 和 YARN 进程。 也许其他应用程序可以同时使用集群。 我们假设 AM 在其中一个节点中运行。好吧,在那之后,你真的有 4 个节点,15 个核心/节点和 63GB/节点免费使用。
您可以认为一个好主意必须是--num-executors 4 --executor-cores 15 --executor-memory 63G,但不是!
原因:
首先考虑内存开销(大约 7% 的执行程序内存),即 63GB + 7% = 67.41 > 64GB 其次,您将使用节点中的所有内核,但您需要在其中一个内核中添加 1 个额外内核才能运行 AM(应用程序管理器) 最后,每个执行程序 15 个内核会导致 HDFS I/O 吞吐量下降。一个好的方法是 --num-executors 11 --executor-cores 4 --executor-memory 19G:
节点 1、2、3:每个节点将使用 3 个执行程序和 12 个内核(3 个内核免费用于 SO 和其他进程) 节点 4:将使用 2 个执行器和 8 个内核(其他 8 个内核可免费用于 AM、SO 和其他进程) 每个执行程序将使用 19GB + 7%(开销)=20.33GB 节点 1、2、3:将使用 20.33 * 3 个执行器 = 60.99GB(3GB 免费) 节点 4:将使用 40.66GB(23.44GB 免费用于 AM、SO 和其他进程)这不是您可以使用的唯一配置,还有其他配置。
结论,调整火花始终是一项艰巨的任务。您必须了解您的集群资源(内存、节点和核心)。
更多信息见cloudera官方博客:https://blog.cloudera.com/how-to-tune-your-apache-spark-jobs-part-2/
【讨论】:
以上是关于有啥方法可以提高火花写入性能?的主要内容,如果未能解决你的问题,请参考以下文章