Spark,一个奇迹的诞生

知识就是力量,时间就是生命。这篇文章主要讲述Spark,一个奇迹的诞生相关的知识,希望能为你提供帮助。
UC Berkeley的AMP Lab推出的Spark更快执行速度和更友好的编程接口,在推出后短短两年就迅速抢占MapReduce的市场份额,成为主流的大数据计算框架。
Spark之前,人们并未对MapReduce执行速度不满,觉得这速度其实也还行,至于编程复杂度:

  • Hive、Mahout封装了常用的MapReduce编程
  • MapReduce已很简化分布式编程了
Spark出现后,人们才不满MapReduce。原来大数据计算速度还能快这么多,编程更简单。且Spark支持Yarn和HDFS,迁移成本小,越来越多公司用Spark替MapReduce。
相比MapReduce,有更快执行速度,更简单易用的编程模型。使用Scala语言在Spark上编写WordCount程序,主代码仅三行
// 根据HDFS路径生成一个输入数据RDD
val textFile = sc.textFile("hdfs://...")
val counts = textFile.flatMap(line => line.split(" "))
.map(word => (word, 1))
.reduceByKey(_ + _)
// 将这个RDD保存到HDFS。
counts.saveAsTextFile("hdfs://...")

在输入数据RDD上执行如下操作,得到一个新RDD:
  • 将输入数据的每一行文本用空格拆成单词
  • 将每个单词进行转换,??word => (word, 1)??,生成< K, V> 的结构
  • 相同K进行统计,统计方式是对V求和,??(_ + _)??。
RDD,Resilient Distributed Datasets,弹性数据集,既是Spark面向开发者的编程模型,又是Spark自身架构的核心元素。
Spark编程模型的RDD大数据计算就是在大规模的数据集上进行一系列的数据计算处理。MapReduce针对输入数据,将计算过程分为Map、Reduce阶段,可理解成是面向过程的大数据计算。
用MapReduce编程,关键是如何将计算逻辑用Map和Reduce两个阶段实现,map、reduce的输入和输出是什么。
而Spark直接针对数据编程,将大规模数据集合抽象成一个RDD对象,然后在这个RDD上进行各种计算处理,得到一个新RDD,继续计算处理,直到得到最后的结果数据。所以Spark可以理解成是面向对象的大数据计算。关键是一个RDD对象需经过什么样的操作,转换成另一个RDD对象。
所以WordCount代码示例里,第2行代码实际上进行了3次RDD转换,每次转换都得到一个新的RDD,因为新的RDD可以继续调用RDD的转换函数,所以连写成一行。等价于如下3行:
val rdd1 = textFile.flatMap(line => line.split(" "))
val rdd2 = rdd1.map(word => (word, 1))
val rdd3 = rdd2.reduceByKey(_ + _)

RDD上定义的函数分为:
  • 转换(transformation)函数,返回值是RDD
计算map(func)、过滤filter(func)、合并数据集union(otherDataset)、根据Key聚合reduceByKey(func, [numPartitions])、连接数据集join(otherDataset, [numPartitions])、分组groupByKey([numPartitions])等


  • 执行(action)函数,不再返回RDD
Spark架构核心元素的RDD跟MapReduce一样,Spark也是对大数据进行分片计算,Spark分布式计算的数据分片、任务调度都是以RDD为单位展开的,每个RDD分片都会分配到一个执行进程去处理。
RDD上的转换操作又分成两种,一种转换操作产生的RDD不会出现新的分片,比如map、filter等,也就是说一个RDD数据分片,经过map或者filter转换操作后,结果还在当前分片。就像你用map函数对每个数据加1,得到的还是这样一组数据,只是值不同。实际上,Spark并不是按照代码写的操作顺序去生成RDD,比如??rdd2 = rdd1.map(func)??这样的代码并不会在物理上生成一个新的RDD。物理上,Spark只有在产生新的RDD分片时候,才会真的生成一个RDD,Spark的这种特性也被称作惰性计算。
另一种转换操作产生的RDD则会产生新的分片,比如??reduceByKey??,来自不同分片的相同Key必须聚合在一起进行操作,这样就会产生新的RDD分片。实际执行过程中,是否会产生新的RDD分片,并不是根据转换函数名就能判断出来的,具体我们下一期再讨论。
Spark程序中的RDD和Spark执行过程中生成的物理RDD不是一一对应,RDD在Spark是个灵活概念。
Spark生态以Spark为基础:
  • 支持SQL语句的Spark SQL
  • 流计算的Spark Streaming
  • 机器学习的MLlib
  • 图计算的GraphX
总结顶尖的产品设计大师和问题解决专家,不会去询问人们想要什么,而是分析和观察人们的做事方式,从而思考到更好的产品设计和问题解决方案。
但这种技巧需要深邃的观察力和洞察力,没深度的思考,做出的东西会沦为异想天开和自以为是。大众提出的需求虽然也无法触及问题的核心,但好歹有共识,做出的东西虽然平庸,但不至于令人厌恶。
缺乏洞见的自以为是则会违反常识,让其他人本能产生排斥感,进而产生对立情绪。这种情绪之下,设计没有改进的基础,最后往往成为悲剧。这两年在所谓互联网思维的鼓吹下,一些缺乏专业技能的人,天马行空创造需求,受到质疑后公开批评用户,也是让人惊诧。
不要直接提出你的问题和方案,不要说“你的需求是啥?”“我这有个方案你看下?”。
【Spark,一个奇迹的诞生】直向曲中求,复杂问题,越是直截了当,越得不到答案。迂回曲折提问题,一起思考问题背后规律,才能逐渐发现本质。既能达成共识,不会有违常识,又可能产生洞见,使产品和方案呈现闪光点。

    推荐阅读