Spark中的自定义Partitioner分区器

本文介绍了一种自定义Spark分区器的方法,通过实现Partitioner抽象类,创建了一个基于主机名的分区器Scala_HostNamePartitioner。该分区器用于确保相同学院URL的点击数据被保存在同一文件中,从而优化数据处理流程。

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

import org.apache.spark.Partitioner

import scala.collection.mutable

/**
  * @author Jacky
  *         自定义分区器
  *         自定义类Scala_HostNamePartitioner继承Partitioner分区器这个抽象类
  */
class Scala_HostNamePartitioner(hostnameArray: Array[String]) extends Partitioner {
  val map = mutable.Map[String, Int]()
  //  val map=mutable.HashMap[String,Int]()

  for (i <- 0 until (hostnameArray.length)) {
    map.put(hostnameArray(i), i)
  }
  //返回分区数
  override def numPartitions: Int = {
    map.size
  }
  //返回所属分区
  override def getPartition(key: Any): Int = {
    map.getOrElse(key.toString, 0)
  }
}
======================================================================

import java.net.URL

import org.apache.log4j.{Level, Logger}
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

/**
  * @author Jacky
  *         需求:将每个学院的URL点击次数保存在同一个文件(分区)中
  */
object Scala_UserDefinedPartitioner {
  def main(args: Array[String]): Unit = {
    //设置Logger级别
    Logger.getLogger("org").setLevel(Level.WARN)
    //创建SparkConf对象
    val conf = new SparkConf().setAppName("Scala_UserDefinedPartitioner").setMaster("local")
    //创建SparkContext对象
    val sc = new SparkContext(conf)

    val logsRDD = sc.textFile("C:\\360.log")
    //(url,1)
    val urlRDD: RDD[(String, Int)] = logsRDD.map(line => {
      val log = line.split("\t")
      val url = log(1)
      (url, 1)
    })
    //(url,count),统计url的访问次数
    val urlCountRDD = urlRDD.reduceByKey(_ + _)
    //(hostname,(url,count))
    val resultRDD: RDD[(String, (String, Int))] = urlCountRDD.map(t2 => {
      //获取url
      val url = t2._1
      //从URL中获取hostname
      val hostname = new URL(url).getHost
      (hostname, t2)
    })
    //hostname的列表
    val hostnameList: Array[String] = resultRDD.map(x => x._1).distinct().collect()
    //通过partitionBy算子调用自定义分区器,并将分区结果写入C盘
    resultRDD.partitionBy(new Scala_HostNamePartitioner(hostnameList))
      .saveAsTextFile("C:\\out" + System.currentTimeMillis())

    sc.stop()
  }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值