spark复杂转换

package com.sf.gis.scala.base.spark

import com.alibaba.fastjson.JSONObject
import org.apache.log4j.Logger
import org.apache.spark.rdd.RDD

import scala.collection.mutable.ArrayBuffer
import scala.util.Random


/**
  * Created by 01374443 on 2020/7/27.
  * 处理一些复杂的转换场景
  */
object SparkMapReduce {
  @transient lazy val logger: Logger = Logger.getLogger(this.getClass)

  /** *
    * 重分区
    *
    * @param dataRDD      数据体
    * @param repartionNum 重分分区数
    * @return
    */
  def repartion(dataRDD: RDD[JSONObject], repartionNum: Int): RDD[JSONObject] = {
    if (dataRDD.getNumPartitions != repartionNum) {
      //先判断当前分区是否已经一致
      return dataRDD.repartition(repartionNum)
    }
    dataRDD
  }

  /**
    * 随机散列数据后做聚合
    *
    * @param obj     输入数据
    * @param hashNum 散列倍数,将随机一定范围内的随机值作为散列前缀
    */
  def groupByKeyTwoStep(obj: RDD[(String, Object)], hashNum: Int): Unit = {
    // 先添加随机值散列,第一次聚合
    val hashData = obj.map(obj => {
      val hashPrefix = new Random().nextInt(hashNum)
      ((hashPrefix, obj._1), obj._2)
    }).groupByKey().map(obj => {
      (obj._1._2, obj._2.toArray)
    })
    //再去除散列进行第二次聚合
    hashData.groupByKey().map(obj => {
      val key = obj._1
      val valueIterator = obj._2.iterator
      val ret = new ArrayBuffer[Object]
      while (valueIterator.hasNext) {
        val tmpArray = valueIterator.next()
        ret.appendAll(tmpArray)
      }
      (key, ret)
    })
  }

  /**
    * 随机散列数据后做reduce
    * @param obj     输入数据
    * @param fun     聚合处理方法
    * @param hashNum 散列倍数,将随机一定范围内的随机值作为散列前缀
    */
  def reduceByKeyTwoStep(obj: RDD[(String, Object)], fun: (Object, Object) => Object, hashNum: Int): Unit = {
    // 先添加随机值散列,第一次聚合
    val hashData = obj.map(obj => {
      val hashPrefix = new Random().nextInt(hashNum)
      ((hashPrefix, obj._1), obj._2)
    }).reduceByKey((obj1,obj2)=>{
      fun(obj1,obj2)
    }).map(obj=> (obj._1._2,obj._2))
    //再去除散列进行第二次聚合
    hashData.reduceByKey((obj1,obj2)=>{
      fun(obj1,obj2)
    })
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值