Spark取TopN问题

数据处理中, 经常会遇到取TopN的问题. 在Spark中,取TopN有如下的方法:

生成rdd 

读取数据源的数据并转为rdd.

val rdd = sc.textFile()

分区

将rdd划分分区,分区的个数根据实际的数据量和计算集群机器的数量以及核心数确定.

val partitionedRDD = rdd.coalesce(partitions)

kv变换

把每条数据转换为(k,v)形式, k为键,v为值且类型为数字类型.

val kv = partitionedRDD.map(line => .. (k,v))

去重

如果键值不唯一,则需要根据键值去重,并把key相同的value值进行累加.

val uniqueKeys = kv.reduceByKey((a,b) => a + b)

每个分区本地TopN

利用分布式计算的优势,在各个分区生成一个本地TopN.这里有几种方法可以选择.

方法1: mapParititions + SortedMap(TreeMap)

val partitions = uniqueKeys.mapPartitions(mp => {

    val localTopN = new TreeMap[Integer, String]()
    for (item <- mp){
        localTopN.put(item._2, item._1)
        // 只保留top N
        if (localTopN.size > N){
            // 删除频度最小的元素
            localTopN.remove(localTopN.first)
        }
    }
    Collections.singletonList(localTopN)

})

收集每个分区的TopN,取最终的TopN

val allTopN = partitions.collect()
val finalTopN = new TreeMap[Integer, String]()
for (item <- allTopN){
    finalTopN.put(item._1, item._2)
    // 只保留top N
    if (finalTopN.size > N){
        finalTopN.remove(finalTopN.first)
    }
}

方法2:Spark提供了topN的算子, 使用takeOrdered()

val topNResult = uniqueKeys.takeOrdered(N)(implicit Ordering[T])

 

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值