最近工作中开始用 Spark 了,完全是赶鸭子上架 0 基础。想着把自己的学习经历记录下,而且写点博客也对求职有帮助,就试着写了一篇,发现写这玩意确实很难啊,写了半天写得一塌糊涂。一方面是自己才疏学浅,刚毕业大学学的的东西也忘得差不多了;一方面是不太会写,写文章没有条理。
希望大家读完给点建议,挑挑错~ 面向的读者大概是 Spark 的使用者吧。
第一篇先讲讲函数式编程在 Spark 中的应用,因为理解函数式编程对理解 Spark 的一些原理还是很有帮助的。
函数式编程有两个比较重要的点,一个是无副作用,一个是 immutable 变量。
f(x)=x + 1
,对于这个函数,只要它的入参是 n,它的输出值永远都是 n+1 。因为这个函数不依赖任何外部的状态,只依赖入参。这一特性是 Spark 的 RDD 懒加载的理论基础。编写过一些 Spark 程序的人,应该了解 Spark 有两种对 RDD/dataset 的操作。一种是 Transform 类型,包括 map,mapPartition 等;一种是 action 类型,包括 count,reduce 等。
看下这个例子:
val sampleRdd = sc.makeRDD(Array(1, 2, 3, 4), 2)
val rdd2 = sampleRdd.filter((str) => str >= 2)
val count = rdd2.count()
spark 会等到调用 count()的时候才执行 filter(),这就是懒加载,只有用户真正需要结果的时候才执行全过程。所有 transform 类型的操作都是懒加载的,而 action 类型会触发 rdd 上的所有 transform 。懒加载可以让程序集中运行,节约资源,而且在 Spark 这样的分布式程序里可以节约大量的通信调度时间。
为什么函数式编程的无副作用的对懒加载相当重要呢,我们来看下面这个例子。
val xMinBefore = (x : Int) => {
System.currentTimeMillis / 1000 - 60 * x;
}
看到这个函数,它就是有副作用的,它的运行结果不仅依赖入参,还依赖于这个世界的时间,所以你在不同时间去执行这个函数,返回的值是不同的。对于这种有副作用的函数,我们自然不能使用懒加载,我们需要在调用的时候就得到结果,才能保证结果是我们需要的。而没有副作用的函数,我们可以在任何时候执行都得到一致的结果,自然可以在任何时候调用,也就保证了在最后加载的时候,输出的数据是不会有问题的。
保证了无副作用,Spark 的容错机制 lineage 才能起作用。回到上面那个例子
val sampleRdd = sc.makeRDD(Array(1, 2, 3, 4), 2)
val rdd2 = sampleRdd.filter((str) => str >= 2)
val count = rdd2.count()
rdd2 是在 sampleRdd 的基础上进行了 filter 操作,rdd2 实际上就是保留了一个对 sampleRdd 的引用,并记录了 filter 操作。rdd2 这样就有了和 samleRdd 的 lineage 。
lineage 的应用: 在执行第三行 count()时,rdd2 就会在 sampleRdd 的基础上执行 filter 操作。当执行 filter 的时候失败了,spark 就会往上追溯到上一个成功的 rdd,也就是 sampleRdd,再执行一把。可以使用这种方式容错的前提,就是 RDD 的 immutable 特性以及无副作用,它们保证在任何时候对一个 RDD 执行相同操作时,输出的结果永远是一样的。
1
KAQQAK 2021-09-12 23:12:12 +08:00
楼主有个人博客吗 可以发到个人博客上整理合集更方便把
|
2
levelworm 2021-09-13 05:33:37 +08:00 via Android
求问 java 新手如何进化到读懂 spark 源码? java 水准大致上就是可以写基础数据结构的水平,感觉离读懂 scala 写的源码还很远。
|
3
Xhack 2021-09-13 08:32:23 +08:00
这千万不要发展成 csdn
|
4
DeleteZN 2021-09-13 09:48:39 +08:00 2
@levelworm 前大数据从业者回答一下,
先学好一些基本的数据结构,链表、Map 等等,至少要把 java 写熟悉了,了解 JVM 是什么,干了什么事情。然后就可以去看看 scala 了,推荐本书《快学 scala 》 同时要去看大数据发展历史的组件,顺序大约是 HDFS->MapReduce->Yarn->Hive->Spark 等等。 学 Spark 的时候,要先学 Spark 的架构和原理,然后自己亲手去写一下试一试,不管是 spark 任务还是 streamming,还是 sparksql,还是 ml 。 然后就可以开始简单的看点源码了,从简单的 spark 任务开始。 |