在上一篇文章中,我们讲了Spark大数据处理的可扩展性和负载均衡,今天要讲的是更为重点的容错处理,这涉及到Spark的应用场景和RDD的设计来源。

Spark的应用场景

Spark主要针对两种场景:

  • 机器学习,数据挖掘,图应用中常用的迭代算法(每一次迭代对数据执行相似的函数)
  • 交互式数据挖掘工具(用户反复查询一个数据子集)

Spark在spark-submit外,还提供了spark-shell,它就是专门用来做交互数据挖掘的工具

MapReduce等框架并不明确支持迭代中间结果/数据子集的共享,所以需要将数据输出到磁盘,然后在每次查询时重新加载,这带来较大的开销。

既然反复写磁盘和从磁盘加载数据使得性能下降,那就把数据放到内存中,这就是Spark基于内存的弹性分布式数据集(RDD)的出发点。

自动容错

MapReduce是容错性非常好的系统。处理一步就放到磁盘,再处理一步又放到磁盘,一旦哪一步有问题,重做就好了,真可谓是一步一个脚印。Spark为了上述场景下的性能,把数据放在内存中,那整个系统的容错就成了最困难的地方。

一般来说,分布式数据集的容错性有两种方式:即数据检查点和记录数据的更新。由于面向的是大规模数据分析,数据检查点操作成本很高:需要通过数据中心的网络连接在机器之间复制庞大的数据集,而网络带宽往往比内存带宽低得多,同时还需要消耗更多的存储资源(在内存中复制数据可以减少需要缓存的数据量,而存储到磁盘则会拖慢应用程序)。所以选择记录更新的方式。但是,如果更新太多,那么记录更新成本也不低。因此,RDD只支持读操作,并且只支持粗粒度转换,即在大量记录上执行的单个操作。将创建RDD的一系列转换记录下来(即Lineage),以便恢复丢失的分区。

虽然只支持粗粒度转换限制了编程模型,但是RDD仍然可以很好地适用于很多应用,特别是支持数据并行的批量分析应用,包括数据挖掘、机器学习、图算法等,因为这些程序通常都会在很多记录上执行相同的操作。

RDD抽象

RDD是只读的、分区记录的集合。RDD只能基于在稳定物理存储中的数据集和其他已有的RDD上执行确定性操作来创建。这些确定性操作称之为转换,如map、filter、groupBy、join(转换不是程开发人员在RDD上执行的操作)。

RDD含有如何从其他RDD计算出本RDD的相关信息(即Lineage),据此可以从物理存储的数据计算出相应的RDD分区。

在需要反复使用的某个数据集时,使用RDD的持久化,即persist,这个持久化优先是放在内存中的。

再来看看WordCount

说了这么多,我们依然拿WordCount来说说,帮忙小伙伴们理解,还没有看本系列前两篇文章的童鞋抓紧去看看哈。

val file = "hdfs://127.0.0.1:9000/file.txt"
val lines = sc.textFile(file)
val words = lines.flatMap(line => line.split("\\s+"))
val partialCountMap = words
.mapPartitions(convertWordsInPartitionToWordCountMap)
val wordCount = distCountMap.reduce(mergeMaps)

WordCount一共涉及到三个RDD,用于承载文本行的lines,用于承载单词的words,用于承载每个文件块上部分单词计数的partialCountMap。Lineage关系:partialCountMap的父RDD为words,words的父RDD为lines,如下图:

有了Lineage和RDD的只读特性,就可以轻松完成容错了。

如果words在slave1上的一个分区出问题了,那么我们只需要加载slave1上对应的文件块,并重新计算其lines对应的分区,进而计算得到words的这个分区。

图中每个slave中只画了一个文件块,实际上可能有多个文件块。一定要注意的是哪个分区出问题了,只会重算这一个分区,也就只会重新加载这个分区关联的文件块。

上面讨论的是窄依赖的情况,如果像groupBy这种转换,一个RDD分区需要依赖父RDD的多个分区,那么一个分区挂了,就需要计算父RDD中的多个分区。

分布式系统的三个问题:可扩展性,负载均衡,容错处理,都解决了吧。

不知道看到这里的小伙伴,心里是否有个疑问,既然RDD的API只支持粗粒度的转换,它真的能够支持这么多千奇百怪的应用场景吗?下一篇,我们一起看RDD的API,以及它对其它大数据处理框架能够处理的应用场景的等效解决方案。

推荐

动手写Count

从WordCount看Spark大数据处理的核心机制(1)

从WordCount看Spark大数据处理的核心机制(2)

RDD粗粒度转换的威力

查看《Spark大数据处理》系列文章,请进入YoyaProgrammer公众号,点击 核心技术,点击 Spark大数据处理。

分类 Spark大数据处理

优雅程序员 原创 转载请注明出处

最新文章

  1. WdatePicker 没有权限 不能执行已释放 Script 的代码
  2. Html.DropDownList
  3. 如何自定义一个优雅的ContentProvider
  4. Android 滑动效果高级篇(七)—— 华丽翻页效果
  5. JS 文本输入框放大镜效果
  6. 项目设计&重构&性能优化
  7. SQL基础理论题
  8. Spring HTTP invoker 入门
  9. oracle中的B-TREE索引
  10. P - Shopaholic
  11. 新的 Windows Azure 网络安全性白皮书
  12. java加密算法入门(三)-非对称加密详解
  13. boost::assign(标准容器填充库)
  14. JFreeChart画图+jsp页面显示实现统计图
  15. [C#]“正在终止线程”的问题
  16. c# is 和 as 的区别和使用
  17. MetaBase
  18. Generator函数自执行
  19. windows下libcurl与zlib和ssl共同编译
  20. JS里的居民们4-数组((堆)队列

热门文章

  1. 第十七章 Velocity优化实践(待续)
  2. Navicat断网时连不上数据库
  3. DAY16-Django之MTV
  4. java.lang.Class.getDeclaredMethod()方法详解
  5. Ajax入门(二)Ajax函数封装
  6. NIO/AIO
  7. Ros学习调试——rqt_console
  8. __get(),__set(),__isset(),__unset()
  9. 在Linux里安装jdk
  10. ZBar开发详解