作者: | 来源:互联网 | 2023-09-12 18:36
为什么要出现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的解释
In-memory storage on clusters的抽象是细粒度的(fine-grained),比如kv-store,可以更新内存里的任意一条记录。但这就导致容错时需要备份数据和操作,而带宽相比内存是有限的。
因此RDD的设计是粗粒度的(coarse-grained)变换(transformations)。这样就可以只记录这些变换,而不用记录数据本身。
通过谱系图(lineage)这个DAG图进行操作,进行恢复。
RDD是只读的,就是说不能改变已有的RDD中的内容。创建新RDD的操作就是变换(transformations)。
explicitly persist 就是说用户可以显式指定RDD持久化到内存或是磁盘,因为用户可能在未来的计算中会用到这个RDD。Spark默认persist操作将RDD放在内存中,内存不够时会将RDD溢出到磁盘上,默认算法是LRU。
Spark Programming Interface
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优缺点
RDD用粗粒度的更新提升了容错的效率,能更好支持批处理计算,但对于细粒度操作不适合,比如爬虫。
Spark Programming Interface
RDD之间的依赖关系
分为宽依赖和窄依赖
区分的原因
任务调度
当遇到action,调度器会根据谱系图生成包含stage的有向无环图。
每个stage都包含尽可能多的窄依赖操作(pipelined transformations with narrow dependencies)
调度器只要调度计算不在内存中的RDD即可
调度器根据数据的局部性调度任务。