第一篇技术博客:函数式编程和 Spark

2021-09-12 16:13:41 +08:00
 wellwell

前言

最近工作中开始用 Spark 了,完全是赶鸭子上架 0 基础。想着把自己的学习经历记录下,而且写点博客也对求职有帮助,就试着写了一篇,发现写这玩意确实很难啊,写了半天写得一塌糊涂。一方面是自己才疏学浅,刚毕业大学学的的东西也忘得差不多了;一方面是不太会写,写文章没有条理。

希望大家读完给点建议,挑挑错~ 面向的读者大概是 Spark 的使用者吧。

开篇

第一篇先讲讲函数式编程在 Spark 中的应用,因为理解函数式编程对理解 Spark 的一些原理还是很有帮助的。

函数式编程简介

函数式编程有两个比较重要的点,一个是无副作用,一个是 immutable 变量。

  1. 无副作用: f(x)=x + 1,对于这个函数,只要它的入参是 n,它的输出值永远都是 n+1 。因为这个函数不依赖任何外部的状态,只依赖入参。这一特性是 Spark 的 RDD 懒加载的理论基础。
  2. immutable 变量: 这个特性指的是,所有变量都应该是不可变的,在 Spark 中,RDD 就是不可变的。它和无副作用是 Spark 容错机制 lineage 的理论基础。

Transform,action 和懒加载( Lazy Loading )

编写过一些 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;
}

看到这个函数,它就是有副作用的,它的运行结果不仅依赖入参,还依赖于这个世界的时间,所以你在不同时间去执行这个函数,返回的值是不同的。对于这种有副作用的函数,我们自然不能使用懒加载,我们需要在调用的时候就得到结果,才能保证结果是我们需要的。而没有副作用的函数,我们可以在任何时候执行都得到一致的结果,自然可以在任何时候调用,也就保证了在最后加载的时候,输出的数据是不会有问题的。

RDD 的 Lineage

保证了无副作用,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 执行相同操作时,输出的结果永远是一样的。

1700 次点击
所在节点    程序员
5 条回复
KAQQAK
2021-09-12 23:12:12 +08:00
楼主有个人博客吗 可以发到个人博客上整理合集更方便把
levelworm
2021-09-13 05:33:37 +08:00
求问 java 新手如何进化到读懂 spark 源码? java 水准大致上就是可以写基础数据结构的水平,感觉离读懂 scala 写的源码还很远。
Xhack
2021-09-13 08:32:23 +08:00
这千万不要发展成 csdn
DeleteZN
2021-09-13 09:48:39 +08:00
@levelworm 前大数据从业者回答一下,
先学好一些基本的数据结构,链表、Map 等等,至少要把 java 写熟悉了,了解 JVM 是什么,干了什么事情。然后就可以去看看 scala 了,推荐本书《快学 scala 》
同时要去看大数据发展历史的组件,顺序大约是 HDFS->MapReduce->Yarn->Hive->Spark 等等。
学 Spark 的时候,要先学 Spark 的架构和原理,然后自己亲手去写一下试一试,不管是 spark 任务还是 streamming,还是 sparksql,还是 ml 。
然后就可以开始简单的看点源码了,从简单的 spark 任务开始。
levelworm
2021-09-13 18:13:59 +08:00
@DeleteZN 多谢大佬,看来路漫漫兮其修远兮。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/801377

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX