需求
 
假设我们有一张各个产品线URL的访问记录表,该表仅仅有两个字段:product、url,我们需要统计各个产品线下访问次数前10的URL是哪些?
 
解决方案
 
(1)模拟访问记录数据
 
 
模拟数据记录共有1000条,其中包括10个产品线:product1、product2、…、product10,100个URL:url1、url2、…、url100,为了简化生成数据的过程,产品线和URL均使用了随机数。一条记录为一个字符串,产品线与URL使用空格进行分隔。模拟数据存储在一个名为“data”的列表中,通过parallelize的方式形成一个RDD:table,再使用inferSchema的方式注册为一张临时表“product_url”。
 
表“product_url”的示例数据如下:
 
 
(2)统计各个产品线下各个URL的访问次数
 
 
这个逻辑使用Spark SQL即可以实现,示例数据如下:
 
 
可以看出,数据多出了一个字段access,用于表示某产品线下某个URL的访问次数。
 
此外,如果我们有一个数据类型为Row的变量row,可以通过row.product、row.url、row.access或者row[0]、row[1]、row[2]访问product、url、access对应的数据。
 
(3)“分区排序取值”
 
我们的统计需求有一个明显的分界线:产品线,Top N的处理逻辑可以转变为:
 
a. 根据分界线做分区,即每一个产品线的记录进入同一个分区;
b. 每一个分区(产品线)内根据URL的访问次数(access)排序(降序);
c. 每一个分区(产品线)内取前N条数据即可。
 
a、b实际就是一个“分区排序”的过程,Spark RDD也为“分区排序”提供了非常方便的API:repartitionAndSortWithinPartitions,但是该函数需要传入的数据类型要求为(key, value),因此我们需要对(2)中的数据做一下简单的处理:
 
 
其实就是将数据类型Row映射为元组(Row, None),示例数据如下:
 
 
此外repartitionAndSortWithinPartitions还需要两个函数:partitionFunc、keyFunc,这两个函数都需要接收一个参数,该参数为(key, value)中的key。
 
partitionFunc用于根据(key, value)中的key如何选取分区,返回值要求为整型,数值即为分区号,即0表示分区0,1表示分区1,…。
 
 
这里key的数据类型即为Row。
 
因为我们模拟了10个产品线,每一个产品线的数据需要被划分到同一个分区内,因此我们也需要10个分区(分区序号为0—9),根据产品线划分分区的规则为:产品线product1的分区为0,产品线product2的分区为1,…,产品线product10的分区为9。其中key[0]为产品线名称,key[0][7]为产品线名称中的随机数,将key[0][7]转换为整数并减一即可得到对应的分区号。
 
keyFunc用于根据(key, value)中的key如何排序,“分区内排序”时即根据该函数的返回值进行排序。
 
 
其中,key[2]为访问次数access,我们就是需要在某个分区(产品线)内根据URL的访问次数做排序。
 
函数partitionFunc、keyFunc准备好之后,我们可以开始调用repartitionAndSortWithinPartitions:
 
 
需要注意的是,numPartitions值为10,该值取决于分区(产品线)的个数;ascending值为False,该值表示分区内排序时使用降序。
 
“分区排序”之后我们即可以开始“取值”,取值的过程比较简单:在每个分区内即前N(这里假设为10,即top 10)个值,将这些值“汇总”之后即可得出各个产品线下URL访问次数的Top 10。
 
考虑到我们需要“汇总”的需求,因此不能使用foreachPartition,需要通过mapPartitions实现,它需要一个函数:f,函数f的参数为一个“迭代器”,通过这个“迭代器”可以遍历分区内的所有数据。
 
 
从上面的代码可以看出,我们就是通过“迭代器”iter获取分区内的前10条数据(如果分区内的数据条数大于或等于10的话)。
 
“汇总”(collect)结果:
 
 
rows中保存着各个产品线下URL访问次数的Top 10记录。
 
(4)结果处理
 
计算完成之后,我们可以对结果进行一些处理,如:根据产品线、URL根据字典序排序并输出,代码如下:
 
 
示例数据:
 
 
总结
 
使用Spark解决Top N问题时,只需要经过“划分分区、分区内排序、分区内取值”三个过程即可完成。
 

Spark如何解决常见的Top N问题的更多相关文章

  1. Spark程序运行常见错误解决方法以及优化

    转载自:http://bigdata.51cto.com/art/201704/536499.htm Spark程序运行常见错误解决方法以及优化 task倾斜原因比较多,网络io,cpu,mem都有可 ...

  2. 如何解决海量数据的Top K问题

    1. 问题描述 在大规模数据处理中,常遇到的一类问题是,在海量数据中找出出现频率最高的前K个数,或者从海量数据中找出最大的前K个数,这类问题通常称为“top K”问题,如:在搜索引擎中,统计搜索最热门 ...

  3. 【Spark篇】---Spark故障解决(troubleshooting)

    一.前述 本文总结了常用的Spark的troubleshooting. 二.具体 1.shuffle file cannot find:磁盘小文件找不到. 1) connection timeout ...

  4. Spark 学习笔记 —— 常见API

    一.RDD 的创建 1)通过 RDD 的集合数据结构,创建 RDD sc.parallelize(List(1,2,3),2) 其中第二个参数代表的是整个数据,分为 2 个 partition,默认情 ...

  5. 【spark】示例:求Top值

    我们有这样的两个文件 第一个数字为行号,后边为三列数据.我们来求第二列数据的Top(N) (1)我们先读取数据,创建Rdd (2)过滤数据,取第二列数据. 我们用filter()来过滤数据 line. ...

  6. Git 项目上传至github入门实战并解决常见错误

    1.Git GUI 首先,在push到github的项目必须先建立版本(即creat  repository的名字一样),一般是先pull下来,再push(为了防止有其他人提交了代码,而你却不知道,造 ...

  7. iOS runtime实用篇解决常见Crash

    程序崩溃经历 其实在很早之前就想写这篇文章了,一直拖到现在. 程序崩溃经历1 平时开发测试的时候好好的,结果上线几天发现有崩溃的问题,其实责任大部分在我身上. 我的责任: 过分信赖文档,没进行容错处理 ...

  8. 【spark】dataframe常见操作

    spark dataframe派生于RDD类,但是提供了非常强大的数据操作功能.当然主要对类SQL的支持. 在实际工作中会遇到这样的情况,主要是会进行两个数据集的筛选.合并,重新入库. 首先加载数据集 ...

  9. CM5.x配置spark错误解决

    通过cloudera manager 5.x添加spark服务,在创建服务过程中,发现spark服务创建失败,可以通过控制台错误输出看到如下日志信息: + perl -pi -e 's#{{CMF_C ...

随机推荐

  1. mysql-distinct去重、mysql-group …

    一.MYSQL-distinct用法 在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记 ...

  2. Devexpress 使用经验 —— ASPxGridView前后台交互写法推荐

    这里的格式是仁者见仁智者见智,这篇随笔只是我在工作过程中总结出的阅读性高,对我来说效率较高的写法. ASPX: <dx:ASPxGridView ID="ASPxGridViewLin ...

  3. OC相关-02:oc和c的基本差异

    前言: 面向过程和面向对象. 简单的说,面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用. 面向对象是把构成问题事务分解成各个对象,建立对象的目的不 ...

  4. java基础(死循环退出选项)

    java程序中为了程序正常运行,需要给无限循环加入一个退出选项,保证程序的可执行性. import java.util.Scanner; public class { public static vo ...

  5. Codevs 1140 Jam的计数法 2006年NOIP全国联赛普及组

    1140 Jam的计数法 2006年NOIP全国联赛普及组 传送门 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description Jam是个喜欢标 ...

  6. 手机定位原理 - GPS/GLONASS/北斗 + WIFI + 基站

    卫星定位系统 - GPS/GLONASS/北斗: 关于GPS.GLONASS.北斗.伽利略系统的科普请自行谷歌. GPS是使用最广泛的全球定位网络,几乎是所有智能手机的标配.进几年,俄罗斯的GLONA ...

  7. Java单例模式深入详解

    原文地址:http://www.cnblogs.com/hxsyl/ 仅作为笔记收藏…… 一.问题引入 偶然想想到的如果把Java的构造方法弄成private,那里面的成员属性是不是只有通过stati ...

  8. 转 C#开发微信门户及应用(2)--微信消息的处理和应答

    微信应用如火如荼,很多公司都希望搭上信息快车,这个是一个商机,也是一个技术的方向,因此,有空研究下.学习下微信的相关开发,也就成为计划的安排事情之一了.本系列文章希望从一个循序渐进的角度上,全面介绍微 ...

  9. 【随记】还原SQL Server数据库步骤

    情景:在一台机器上备份数据库,然后在另一台机器上还原数据库,可能会出现错误提示:System.Data.SqlClient.SqlError: 备份集中的数据库备份与现有的 'XXX' 数据库不同. ...

  10. 【python】运算优先级

    来源:小甲鱼 课件