Spark笔记

为什么要出现RDD?

迭代算法(iterative algorithms)和交互式数据处理(interactive data mining tools)不够高效。

因为在需要数据复用(data reuse)的情况下,现有的手段是将中间数据写回磁盘,造成巨大的性能开销。

Resilient Distributed Datasets (RDDs)

RDDs are fault-tolerant, parallel data structures that let users explicitly persist intermediate results in memory, control their partitioning to optimize data placement, and manipulate them using a rich set of operators.

以上是论文中作者对于RDD的解释

  • fault-tolerant

In-memory storage on clusters的抽象是细粒度的(fine-grained),比如kv-store,可以更新内存里的任意一条记录。但这就导致容错时需要备份数据和操作,而带宽相比内存是有限的。

因此RDD的设计是粗粒度的(coarse-grained)变换(transformations)。这样就可以只记录这些变换,而不用记录数据本身。

通过谱系图(lineage)这个DAG图进行操作,进行恢复。

  • read-only

RDD是只读的,就是说不能改变已有的RDD中的内容。创建新RDD的操作就是变换(transformations)。

  • persist & partition

explicitly persist 就是说用户可以显式指定RDD持久化到内存或是磁盘,因为用户可能在未来的计算中会用到这个RDD。Spark默认persist操作将RDD放在内存中,内存不够时会将RDD溢出到磁盘上,默认算法是LRU。

Spark Programming Interface

  • transformations & actions

transformations是生成RDD,actions是进行的操作

Spark是lazy模式,就是说在action前并不进行实际计算。

lines = spark.textFile("hdfs://...")
errors = lines.filter(_.startsWith("ERROR"))
errors.persist()

// Return the time fields of errors mentioning
// HDFS as an array (assuming time is field
// number 3 in a tab-separated format):
errors.filter(_.contains("HDFS"))
      .map(_.split(\t)(3))
      .collect()

persist操作显式地将errors放在内存

如上图,在collect操作时真正进行计算,返回结果

注意,pipeline transformations中间结果并不保存

RDD优缺点

image-20220210173822702

RDD用粗粒度的更新提升了容错的效率,能更好支持批处理计算,但对于细粒度操作不适合,比如爬虫。

Spark Programming Interface

RDD之间的依赖关系

image-20220210171236121

分为宽依赖和窄依赖

  • narrow dependencies 父RDD最多被一个子RDD依赖
  • wide dependencies 父RDD被多个子RDD依赖

区分的原因

  • 流水线执行(pipelined execution):一个窄依赖的partition在完成一个算子时,不必等待其他分区,可以直接进行后续计算。而宽依赖需要等它所有父RDD计算完成后,才能进行下一步。
  • 数据恢复:窄依赖恢复涉及到的父分区少,且可以并行恢复。宽依赖的恢复涉及到大量分区。

任务调度

image-20220210171336022

  1. 当遇到action,调度器会根据谱系图生成包含stage的有向无环图。

  2. 每个stage都包含尽可能多的窄依赖操作(pipelined transformations with narrow dependencies)
  3. 调度器只要调度计算不在内存中的RDD即可
  4. 调度器根据数据的局部性调度任务。
    • partition在某一结点的内存中,调度该任务到该节点
    • partition在磁盘上,调度到preferred locations(比如HDFS file)