TALEND WEBINAR : March 27th, 2018 | Step-by-Step to Enterprise Data Integration

Apache Spark 分区简介 – 您需要知道些什么

Apache Spark 分区简介 – 您需要知道些什么

  • Lokesh Poojari Gangadharaiah
    Lokesh Poojari G is a Customer Success Architect at Talend. His field of expertise include Integration technologies , Project management & other programming languages. He has over 15 yrs work experience spanning organizations like Accenture, Thomson Financials, MetricStream etc in GRC, Telecom, Investments, Mobility & Media domains. He is Certified Scrum Master and has worked in the roles Senior Solution Architect, Delivery Manager, Product Manager & Business Analyst for various IT programs prior to joining Talend.
  • March 05, 2018

Apache Spark 的弹性分布式数据集 (RDD) 是一个包含各种数据的集合,这些数据非常大,以致于无法放入单一节点,因此必须在不同节点之间进行分区。Apache Spark 可自动对 RDD 进行分区,并将这些分区分布到不同节点。评估过程非常缓慢(即在触发可改进可管理性、保存计算并提升优化和速度的动作之前,将不会开始执行),而且转换存储为有向非循环图(DAG)。因此,RDD 上的每一动作都会导致 Apache Spark 重新计算 DAG。

要提高性能、调试和错误处理能力,了解 Apache Spark 中分区的特征就至关重要。

以下是有关分区的一些基础知识:

  • Spark 集群中的每一节点都包含一个或多个分区。
  • Spark 中使用的分区数量可以配置,分区太少(造成并发性降低、数据倾斜和资源利用不当)或太多(造成任务调度花费比实际执行时间更长的时间)都不是件好事。默认情况下,分区数量设置为所有执行器节点上核心的总数。
  • Spark 中的分区不能跨多台机器。
  • 须保证同一分区中的元组在同一机器上。
  • Spark 为每个分区分配一个任务,且每一工作线程一次可以处理一个任务。

Apache Spark 中的哈希分区和范围分区

Apache Spark 支持两种类型的分区,即“哈希分区”和“范围分区”。您可以根据数据中键的分布或排序方式,以及您想对数据执行的动作,选择合适的技术。在选择分区类型时,需要考虑许多因素,比如:

  • 可用资源 — 可在其上运行任务的核心的数量。
  • 外部数据源 — 视本地集合、Cassandra 表或 HDFS 文件的大小确定分区数量。
  • 用于派生 RDD 的转换当一个 RDD 是由另一 RDD 派生而来时,可运用多种规则确定分区数量。

如您所见,在使用 Apache Spark 时,需要注意许多方面。在本篇博客中,我想强调一下完全了解业务数据、Spark 处理相关键和物理资源,尤其是网络、CPU 和内存的重要性。

我们先来说下使用 Apache Spark 分区时常常碰到的误区:

倾斜数据和混排块

使用 Apache Spark 的默认分区执行作业处理可能导致数据倾斜,从而造成聚合操作期间出现混排问题,或者单个执行器没有充足的内存。

倾斜数据示例

可以看到在分区中“key-a”具有更大的数据量,因此 Exec-5 上的任务完成起来要比其他五个任务花费的时间更多。另外,还需记住 Spark 混排块不得大于 2 GB(从内部讲,这是因为 ByteBuffer 抽象的 MAX_SIZE 设置为 2GB)。例如,如果您正在运行诸如聚合、连接或缓存操作等操作,将会出现 Spark 混排,分区数量少或数据倾斜就会造成严重的混排块问题。因此,如果出现混排导致的与 MAX_SIZE 超出限值相关的错误,您就能知道其中原因,因为这可能是数据倾斜造成的。

合理分区

如何才能避免倾斜数据和混排块呢?答案就是合理分区。要应对内存压力并确保充分利用执行器节点上的资源,合理分区不可或缺。务必要了解您的数据,比如数据的大小、类型和分布方式。下面这些最佳实践要记在心里:

  • 了解并为 reduceByKey 或 aggregateByKey 等动作选择合适的操作符,以便消除驱动器面临的压力,并在执行器上正确执行任务。
  • 如果您的数据是放在几个不可分割的大型文件中,InputFormat 指定的分区可能在每一分区中放入大量记录,而无法生成充足的分区来充分利用所有可用的核心。在这种情况下,在加载数据后通过大量的分区调用重新分区,将使得随后的操作可以更为充分地利用集群的 CPU。
  • 另外,如果数据发生倾斜,建议使用合适的键均匀地分布负载,以进行重新分区。

Talend 提供的 tPartition 组件可以根据您选择的适当键满足您的重新分区需求。

如何获得合适的分区数量呢?

对于 RDD 的每一分区,Apache Spark 仅可以运行单个并发任务,直到达到集群中的核心数量为止(可能是这个数的 2-3 倍)。因此,就选择“合适”数量的分区而言,为确保并行性通常需要至少与执行器数量一样多的分区。您可以通过调用 sc.defaultParallelism 获取此计算值。分区最大容量最终取决于执行器的可用内存。

也可能出现令人费解的情况,这就需要使用适当的重新分区键来确保数据均匀分布。因此,可以使用加盐等方法,添加一个新的“伪”键,并连同当前键一起使用,从而改善数据分布,比方说下面这个例子:

  • 向大型 RDD 添加一个随机元素,用它创建新的连接键,类似于“加盐键 = 实际连接键 + 随机伪键,其中伪键的值在 1 到 N 之间,N 表示分布级别”
  • 使用笛卡儿积 (1-N) 向小型 RDD 添加一个随机元素,以增加条目数量并创建新的连接键
  • 在新的连接键上连接 RDD,由于是随机种子设定,数据集将得到更好的分布。
  • 从连接键中删除随机伪键,获得最终的连接结果

在上例中,查找数据集中的伪键将为笛卡儿积 (1-N),而对于主数据集,将为每一行源数据集的随机键 (1-N),N 表示分布级别。

Talend 和 Apache Spark

Talend Studio 提供可生成源生代码的图形工具和向导,帮助您轻松上手 Apache Spark、Spark Streaming,甚至对您的数据进行合理分区。以上这些技术只需使用 Talend 的 tMap 组件即可实施。如果您对数据非常了解,还可以使用 TalendtPartition 组件满足重新分区需求,我们的 tMap 组件可以执行加盐和随机数技术,解决与键倾斜或为空值(视情况而定)的数据有关的问题。

希望您能在这篇简短的博客帖子中了解到一些关于 Apache Spark 分区和处理的新的基础知识。如需进一步了解Talend 和 Apache Spark如何协力帮您加快并扩展大数据处理,敬请访问我们的解决方案页面。

参考文献:

https://issues.apache.org/jira/browse/SPARK-6235

https://0x0fff.com/spark-architecture

https://www.youtube.com/watch?v=WyfHUNnMutg

http://blog.cloudera.com/blog/2015/05/working-with-apache-spark-or-how-i-learned-to-stop-worrying-and-love-the-shuffle/

http://blog.cloudera.com/blog/2015/03/how-to-tune-your-apache-spark-jobs-part-1/

https://stackoverflow.com/questions/40373577/skewed-dataset-join-in-spark

 

Most Downloaded Resources

Browse our most popular resources - You can never just have one.

Join The Conversation

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *