【Spark九十】Spark定义计算逻辑函数最佳实践

这里所谓的Spark定义的计算逻辑函数指的是在Spark中,任务执行的计算逻辑都是定义在Driver Program的函数中的,由于Scala定义函数的多样性,因此有必要总结下各种情况下的函数定义,对Spark将函数序列化到计算节点(Worker)的影响

 

Spark建议的三种做法+一种不推荐的做法

1.定义内部函数常量

package spark.examples.rddapi

import org.apache.spark.{SparkContext, SparkConf}

object ReduceTest_20 {

  def main(args: Array[String]) {
    val conf = new SparkConf().setMaster("local").setAppName("CoGroupTest_05")
    val sc = new SparkContext(conf);
    val z1 = sc.parallelize(List((3, "A"), (6, "B1"), (7, "Z1"), (9, "E"), (7, "F"), (9, "Y"), (77, "Z"), (31, "X")), 3)

    /**
     * Reduces the elements of this RDD using the specified commutative and
     * associative binary operator.
     */
    //r是结果不是集合,直接不是RDD
    def func(k1: (Int, String), k2: (Int, String)) = {
      (k1._1 + k2._1, k1._2 + k2._2)
    }

    //对RDD的元素类型不要求,不需要是KV类型
    val r = z1.reduce(func)
    println(r) //结果:(149,AB1Z1EFYZX),对二元组的第一个元素和第二个元素分别做累加操作
  }

}

 在上面这个例子定义了一个函数func,并且将它放到了main函数中作为一个局部变量,其实也可以把func定义为和main平级(此时func是个全局函数),这种全局函数的定义跟下面第三种定义函数的方式道理一样。

 

2. 定义函数字面量直接传递到RDD定义的高阶函数中、

package spark.examples.rddapi

import org.apache.spark.{SparkContext, SparkConf}

object ReduceTest_21 {

  def main(args: Array[String]) {
    val conf = new SparkConf().setMaster("local").setAppName("CoGroupTest_05")
    val sc = new SparkContext(conf);
    val z1 = sc.parallelize(List((3, "A"), (6, "B1"), (7, "Z1"), (9, "E"), (7, "F"), (9, "Y"), (77, "Z"), (31, "X")), 3)

    /**
     * Reduces the elements of this RDD using the specified commutative and
     * associative binary operator.
     */
    //r是结果不是集合,直接不是RDD
    //对RDD的元素类型不要求,不需要是KV类型
    val r = z1.reduce((k1: (Int, String), k2: (Int, String)) =>(k1._1 + k2._1, k1._2 + k2._2))
    println(r) //结果:(149,AB1Z1EFYZX)
  }

}

 

3. 将函数计算逻辑作为全局函数定义到Scala object中

 

Scala object函数定义:

package spark.examples.rddapi

object ReduceTestFunctions {
  def compute(k1: (Int, String), k2: (Int, String)) = {
    (k1._1 + k2._1, k1._2 + k2._2)
  }
}

  

 

Spark程序中引用Scala object函数定义

package spark.examples.rddapi

import org.apache.spark.{SparkContext, SparkConf}

object ReduceTestFunctions_20 {

  def main(args: Array[String]) {
    val conf = new SparkConf().setMaster("local").setAppName("CoGroupTest_05")
    val sc = new SparkContext(conf);
    val z1 = sc.parallelize(List((3, "A"), (6, "B1"), (7, "Z1"), (9, "E"), (7, "F"), (9, "Y"), (77, "Z"), (31, "X")), 3)

    /**
     * Reduces the elements of this RDD using the specified commutative and
     * associative binary operator.
     */
    //r是结果不是集合,直接不是RDD
    //对RDD的元素类型不要求,不需要是KV类型
    val r = z1.reduce(ReduceTestFunctions.compute(_, _))
    println(r) //结果:(149,AB1Z1EFYZX)
  }

}

 

说明:

通过在Scala object中定义函数,因为Scala object是单例的,那么在序列化时就不需要序列化这个object,仅仅把function序列化到Worker节点即可

 

4.在普通Scala类中定义函数(不推荐)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值