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) }) } }
spark复杂转换
最新推荐文章于 2024-09-15 20:18:52 发布