• Spark学习---RDD编程


    • 学习背景

        本人现在在一家非科技公司工作,到现在入职已经5个多月了。

        我之前有过大数据工作的经验,算接触了一点皮毛,到这家公司也是抱着继续往大数据方向发展的心态而来的。

        面试我的是一位海归博士,刚开始觉得他应该是一位大数据专家,但在面试的过程中就发现不太对头,不过觉得公司应该有CTO的人物存在,于是稀里糊涂就进了这家公司。

        事实证明并没有。

        到现在做的事情基本和hadoop、spark这些都没什么关系了,我亲手搭建的cloudera平台也被领导要求撤了,因为没有用武之地,领导觉得还不如装oracle,装mysql。

        但是我不会轻易改变我的职业规划,于是暗地里自己还在恶补大数据工程开发的相关知识,这些东西不能丢,补习一段时间,准备找个时间就跑路吧。

        在这里也奉劝各位和我一样入世不深的程序员们,选公司尽量避开这些传统行业的公司,这些公司领导往往不懂技术,更有甚者还不尊重技术,这时候有个技术总监类型的人物还好,否则日子很不好过。年轻的程序员小伙伴们,你们还是多找找互联网公司吧,别把青春耽误了。

        本人也是初学者,处于大数据学习的起步阶段,平时爱好把学到的东西写下来,进行总结,我计划做一个Spark学习的系列博客,志同道合的朋友,我们可以互相交流。博客中描述不准确或者有误的地方也请各位不吝赐教,谢谢。

    • 进入正题

        我之前粗略的看过几本spark的相关书籍,大部分一上来就跟你讲工作的原理,各个组件的机制,对于初学者来说,可能看两页就看不下去了,从而放弃了对spark的学习。

        我本人也是这么认为的,所以今天我们先从RDD这一spark的核心对象说起,让大家能快速的上手操作,在以后的博客中,我们再回过头来分析原理。明白原理我们才能踏踏实实的写代码。

        本人写系列博客的出发点是为了记录自己的学习过程,然自己学的更深入,所以不能作为大家学习spark的参考,如果你是一名初学者,建议购买一些spark的书籍进行学习,如《Spark快速大数据分析》,不过在此之前,你可以看一下《快学Scala》先打一下Scala的基础,毕竟spark是用scala语言编写的,用母语写程序,味道才正宗。

    • 什么是RDD

        RDD,即弹性分布式数据集(Resilient Distributed Dataset),说白了就是分布式的元素集合。我们可以把它想象成一个分布在集群中的一个队列,对RDD进行简单的操作,我们就可以轻松的实现对整个集群的上数据进行并行的操作。

        RDD有这样几个特性:不可变的、分区的、可以包含任意类型的对象。

    • 如何创建RDD

        我们有两种方法创建RDD:1、读取外部的数据文件。2、将程序中的集合类型的数据(list、set)转化而成。

        分别举两个例子来说明:

        

    //第一种方式
    val lines = sc.textFile("test.txt")

    //第二种方式
    val lines = sc.parallelize(["a", "b", "c"])
    • 如何操作RDD

        RDD的操作分为两种:1、转化操作(transformation)。2、行动操作(action)

        转化操作会生成新的RDD,但是spark只会惰性的进行计算,直到第一次执行一个行动操作,之前的转化操作才会开始执行。

        这有点类似于我们装系统的时候,利用磁盘工具对硬盘进行分区、更改卷标号、格式化硬盘等操作,你在点击确认操作之前,所有的分区操作都不会真正的执行,直到你点击了确认按钮,软件才真正开始执行你刚刚指定的操作。

        所以大家如果用debug调试spark程序,会发现很奇怪的现象,明明程序运行到第10行了,但是再单步往下调试的时候,又跳到第6行去了,因为转化操作才刚刚开始执行。

        如果大家之前有在hadoop上写过mapreduce(以下简称MR),就会觉得这种方式是非常高效的。MR程序会全量的读入你指定的文件,哪怕你在mapper中写了一条if,丢弃了其中80%的数据,但是spark不同,在运行载入文件命令时,它不会真的把所有数据读进内存,而是看你之后对数据进行了哪些操作,换句话说,它想看看你究竟要做些什么操作,我好省省体力,不要做无用功。

        说到这里又想起个段子:女友学会了一个新菜,要你打下手,她拿着菜谱说,首先把杯子洗干净,并擦干里面的水,于是你擦了半天,终于把被子擦的一滴水都没有了,然后她接着说,第二步,在杯中倒入100ml的水。

        默认情况下,spark的RDD会在你每次对它们进行行动操作的时候重新计算,这时,如果你要反复操作同一个RDD,你应该把这个RDD缓存起来,避免重复的运算,使用persist方法将RDD进行缓存。

    //从外部读取文件,生成RDD
    val lines = sc.textFile("test.txt")
    //将RDD缓存起来,方法如果没有参数可以省略括号
    lines.persist
    //调用转化操作,读取包含'error'的行
    val errorLines = lines.filter(x => x.contains("error"))
    //调用第一个行动操作,使得之前的转化操作开始执行
    errorLines.first()

        缓存后的数据默认是以序列化的形式缓存在内存中,我们也能通过传入参数来改变缓存的位置,如存放到磁盘中。我们甚至能在末尾加上_2指定缓存的份数

        总而言之,转化操作返回新的RDD,并且具有“血统”,能保存从父RDD转化的过程,在数据丢失时,根据血统信息进行重算即可;而行动操作则返回操作的结果(数值、字符串等格式)或者是将数据存入磁盘中。

        时候不早了,今天的分享就到这里。

  • 相关阅读:
    Linux内核中的双向链表struct list_head
    Linux文件的基本操作函数
    Ubuntu下载源码并编译
    Ubuntu搭建交叉编译开发环境
    终端下更改printk打印级别
    进程内存分配
    程序的内存分配
    C语言数据类型char
    RSA算法原理(简单易懂)
    常见复杂指针声明的解析(很详细)
  • 原文地址:https://www.cnblogs.com/xyliao/p/6384612.html
Copyright © 2020-2023  润新知