第一篇技术博客:函数式编程和 Spark - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
请不要在回答技术问题时复制粘贴 AI 生成的内容
wellwell

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

  •  
  •   wellwell Sep 12, 2021 2238 views
    This topic created in 1690 days ago, the information mentioned may be changed or developed.

    前言

    最近工作中开始用 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 执行相同操作时,输出的结果永远是一样的。

    5 replies    2021-09-13 18:13:59 +08:00
    KAQQAK
        1
    KAQQAK  
       Sep 12, 2021
    楼主有个人博客吗 可以发到个人博客上整理合集更方便把
    levelworm
        2
    levelworm  
       Sep 13, 2021 via Android
    求问 java 新手如何进化到读懂 spark 源码? java 水准大致上就是可以写基础数据结构的水平,感觉离读懂 scala 写的源码还很远。
    Xhack
        3
    Xhack  
       Sep 13, 2021
    这千万不要发展成 csdn
    DeleteZN
        4
    DeleteZN  
       Sep 13, 2021   2
    @levelworm 前大数据从业者回答一下,
    先学好一些基本的数据结构,链表、Map 等等,至少要把 java 写熟悉了,了解 JVM 是什么,干了什么事情。然后就可以去看看 scala 了,推荐本书《快学 scala 》
    同时要去看大数据发展历史的组件,顺序大约是 HDFS->MapReduce->Yarn->Hive->Spark 等等。
    学 Spark 的时候,要先学 Spark 的架构和原理,然后自己亲手去写一下试一试,不管是 spark 任务还是 streamming,还是 sparksql,还是 ml 。
    然后就可以开始简单的看点源码了,从简单的 spark 任务开始。
    levelworm
        5
    levelworm  
       Sep 13, 2021 via Android
    @DeleteZN 多谢大佬,看来路漫漫兮其修远兮。
    About     Help     Advertise     Blog     API     FAQ     Solana     5324 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 51ms UTC 09:27 PVG 17:27 LAX 02:27 JFK 05:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86