• Spark核心—RDD初探


    本文目的

       

    最近在使用Spark进行数据清理的相关工作,初次使用Spark时,遇到了一些挑(da)战(ken)。感觉需要记录点什么,才对得起自己。下面的内容主要是关于Spark核心—RDD的相关的使用经验和原理介绍,作为个人备忘,也希望对读者有用。

       

    为什么选择Spark

       

    原因如下

    1. 代码复用:使用Scala高级语言操作Spark,灵活方便,面向对象,函数编程的语言特性可以全部拿来。Scala基本上可以无缝集成java及其相关库。最重要的是,可以封装组件,沉淀工作,提高工作效率。之前用hive + python的方式处理数据,每个处理单元是python文件,数据处理单元之间的交互是基于数据仓库的表格,十分不灵活,很难沉淀常见的工作。
    2. 机器学习:Spark可以实现迭代逻辑,可以轻松实现一些常见的机器学习算法,而且spark自带机器学习库mllib和图算法包graphyx,为后面的数据挖掘应用提供了想象空间。

       

    Spark计算性能虽然明显比Hadoop高效,但并不是我们技术选型的主要原因,因为现有基于Hadoop +hive的计算性能已经足够了。

       

       

    基石哥—RDD

       

    整个spark衍生出来的工具都是基于RDD(Resilient Distributed Datesets),如图:

    RDD是一个抽象的数据集,提供对数据并行容错的处理。初次始使用RDD时,其接口有点类似Scala的Array,提供map,filter,reduce等操作。但是,不支持随机访问。刚开始不太习惯,但是逐渐熟悉函数编程和RDD 的原理后,发现随机访问数据的场景并不常见。

       

    为什么RDD效率高

       

    Spark官方提供的数据是RDD在某些场景下,计算效率是Hadoop的20X。这个数据是否有水分,我们先不追究,但是RDD效率高的由一定机制保证的:

    1. RDD数据只读,不可修改。如果需要修改数据,必须从父RDD转换(transformation)到子RDD。所以,在容错策略中,RDD没有数据冗余,而是通过RDD父子依赖(血缘)关系进行重算实现容错。
    2. 多个RDD操作之间,数据不用落地到磁盘上,避免不必要的I/O操作。
    3. RDD中存放的数据可以是java对象,所以避免的不必要的对象序列化和反序列化。

    总而言之,RDD高效的主要因素是尽量避免不必要的操作和牺牲数据的操作精度,用来提高计算效率。

       

    闭包外部变量访问原则

     

    RDD相关操作都需要传入自定义闭包函数(closure),如果这个函数需要访问外部变量,那么需要遵循一定的规则,否则可能会出现异常。闭包函数传入到节点时,需要经过下面的步骤:

    1. 使用反射机制,找到所有需要访问的变量,并封装到对象中,然后序列化
    2. 将序列化后的对象通过网络传输到其他节点上
    3. 反序列化闭包对象
    4. 子指定节点执行闭包函数,外部变量在闭包内的修改不会被反馈到驱动程序。

    简而言之,就是通过网络,传递函数,然后执行。所以,被传递的对象必须可以序列化和反序列化,否则传递失败。单机本地执行时,仍然会执行上面四步。

     

    广播机制也可以做到这一点,但是频繁的使用广播会使代码不够简洁,而且广播设计的初衷是将较大数据缓存到节点上,避免多次数据传输,提高计算效率,而不是用于进行外部变量访问。

       

    参考资料

  • 相关阅读:
    maven学习(七)——使用maven构建java项目
    Java 实现word 中写入文字图片的解决方案
    postman中如何传数组
    char类型在传参时接收不到数据的原因
    Oracle一条数据多表连插
    Spring Cloud Config的配置中心使用非对称性加密
    Failed to read artifact descriptor for org.springframework.cloud:spring-cloud-starter-config:jar:unk
    如何上传文件到git
    Windows的DOS命令
    ideal的maven项目不小心remove module,如何找回
  • 原文地址:https://www.cnblogs.com/bourneli/p/4320878.html
Copyright © 2020-2023  润新知