Spark笔记

本文介绍了Spark程序的基本工作流程,包括从外部数据创建输入RDD、使用转化操作定义新的RDD、执行persist()操作以缓存中间结果,以及使用行动操作触发并行计算。还探讨了如何避免传递不可序列化的类,并提供了持久化和常用操作如collect()和distinct()的使用说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. spark程序的工作流程
    • 从外部数据创建出输入RDD
    • 使用诸如filter()这样的转化操作对RDD进行转化,已定义新的RDD
    • 告诉Spark对需要被重用的中间结果RDD执行peisist()操作
    • 使用行动操作(例如count()和first()等)来触发一次并行操作,Spark会对计算进行优化后再执行
  2. 向spark传递函数

    • 传递的函数及其引用的数据需要时可序列化的(实现了java的Serializable接口)。如果在Scala 中出现了NotSerializableException,通常问题就在于我们传递了一个不可序列化的类中的函数或字段。
    • 把需要的字段放到一个局部变量中,来避免传递包含该字段的整个对象

      class SearchFunctions(val query: String) {
          def isMatch(s: String): Boolean = {
              s.contains(query)
          }
          def getMatchesFunctionReference(rdd: RDD[String]): RDD[String] = {
              // 问题:"isMatch"表示"this.isMatch",因此我们要传递整个"this"
              rdd.map(isMatch)
          }
          def getMatchesFieldReference(rdd: RDD[String]): RDD[String] = {
              // 问题:"query"表示"this.query",因此我们要传递整个"this"
              rdd.map(x => x.split(query))
          }
          def getMatchesNoReference(rdd: RDD[String]): RDD[String] = {
              // 安全:只把我们需要的字段拿出来放入局部变量中
              val query_ = this.query
              rdd.map(x => x.split(query_))
          }
      }
      
  3. 持久化(缓存)为了避免多次计算同一个RDD即多次执行rdd的action算子,可以让Spark 对数据进行持久化。在scala默认情况下persist()会把数据以序列化的形式缓存在jvm的堆空间中。

  4. collect()获取整个RDD中的数据;但是,只有当整个数据集能在单台机器的内存中放得下时,才能使用collect(),因此collect()不能用在大规模数据集上
  5. distinct() 转化操作来生成一个只包含不同元素的新RDD。不过需要注意,distinct() 操作的开销很大,因为它需要将所有数据通过网络进行混洗(shuffle),以确保每个元素都只有一份。
  6. 分区
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值