本章主要介绍Spark如何处理键值对。K-V RDDs通常用于聚集操作,使用相同的key聚集或者对不同的RDD进行聚集。部分情况下,需要将spark中的数据记录转换为键值对然后进行聚集处理。
我们也会对键值对RDD的高级特性——分区进行讨论,用户可以控制RDD在节点间的布局,确保数据在同一机器上面,减少通信开销,将极大地提高效率。数据分区的选择与单机程序数据结构的选择一样,都能对程序的性能产生极大的影响。

主要分为以下几个章节:

  • 创建PairRDD
  • Transformation on Pair RDD
  • Actions on Pair RDD
  • 数据分区partition

Motivation

spark对Pair RDD提供了一系列的特殊操作。例如reduceByKey可以对RDD按照key进行聚合;join方法可以对两个RDD按照相同元素进行分组合并。

创建 Pair RDD

有多重方法可以创建Pair RDD,也可以将其他类型的RDD转化为Pair RDD。 下面代码将字符串第一个单词作为key
scala示例:

input.map(x => (x.split(" ")(0), x))

java没有内置的元组类型,可以引入scala.Tuple2,代码如下

PairFunction<String, String, String> keyData = new PairFunction<String, String, String>() { public Tuple2<String, String> call(String x) { returnnew Tuple2(x.split(" ")[0], x);
}
};
JavaPairRDD<String, String> rdd = input.mapToPair(keyData);

Transformation on Pair RDDs

Pair RDD可以进行通用的转换操作,例如map等。由于它包含元组,我们传入的函数其参数应该为元组。

reduceByKey:与reduce类似,对RDD进行合并。对RDD中每个元素进行操作,按照相同的key,对value进行操作并合并;

foldByKey:提供初值为0,要求合并操作对0没有影响。

以上两个转换在实际执行时,会先在各个节点进行combine,然后再进行全局合并,提升性能。

示例1:求取平均值

示例2:word count

实际上word count可以使用countByValue简化计算

input.flatMap(x =>x.split(" ")).countByValue()

combineByKey:是按照Key进行合并的通用函数,可以实现大部分按单Key合并的操作,它允许用户输入与输出类型不同;可以根据情况禁用map side aggregation(map过程的合并操作),例如groupByKey的map side aggregatation并不能提高性能,一般禁用。

示例:按key求平均值

combineByKey的数据流如下图所示:

并行级别调整

RDD的分区数直接影响着spark执行的并行程度,可以指定分区数对spark的并行程度进行微调。

代码示例

有 时需要在grouping和aggregating的上下文环境之外改变RDD分区,可以通过Spark提供的repartition工具,由于涉及 shuffle操作,代价很高。当减少RDD分区时,可以使用coalesce合并,数据移动更少,性能更优。可以通过 rdd.partitions.size()确定分区数,判断是否可用coalesce。

分组

groupBy将RDD元素按照函数处理,将结果作为主键进行分组;

groupByKey按照主键进行分组;

可以使用特定的reduce函数代替groupBy+reduce,因为可以将归约后结果放入RDD,而不是归约前的数据,提高效率。

cogroup可以对多个RDD按照相同主键进行分组,是join连接处理的基础。

连接

spark支持内连接、左外连接、右外连接和交叉链接。参照数据库中join的概念进行理解。

排序

RDD排序可以保证后续的调用,数据都是有序的。

例如将String与int混合的RDD进行排序:

Pair RDD可执行的转换总结如下所示:

 
 

Action on Pair RDDs

 
数据分区
通过join查询5分钟内,访问了不是非订阅的主题的用户。
 
 
 
代码每次进行join时都会讲两个RDD主键进行hash,通过网络将相同主键数据放到同一机器,然后进行连接。
 
通常我们可以认为5分钟的event数据很少,主要是用户数据较大,shuffle代价很大。可以将其进行分区持久化
执行流程变为下图所示:
        
这样在进行join时,只需要将5分钟event数据进行hash即可。注意partitionBy是一个Transformation操作,会产生一个新的RDD。100个分区确定了下一步并行的任务数,一般建议是集群的CPU核数。注意,若是对分区后的数据持久化persist失败(例如集群内存不足),则下次计算会重新进行分区、shuffle,与不指定分区一样,并不能提高执行效率。
        
        除了join,spark还会根据RDD分区信息对其他操作进行优化,例如sortByKey、groupByKey会利用分区信息进行优化。map操作生成的RDD会遗忘旧的分区信息。下面会介绍如何确定分区类型以及分区对spark操作的影响。
  

决定RDDs分区

    scala通过spark.Partitioner存储RDD的分区信息,java使用partitioner()方法获取该对象。
spark中诸多操作收到分区的影响,例如cogroup、groupWith、join、leftOuterJoin、rightOuterJoin、groupByKey、reduceByKey、combineByKey和lookup。分区后,可以使得部分计算本地话,减少节点间通讯。若两个RDD分区一致且都被缓存在同样机器,则不会触发网络间通讯。
 
    spark的转换操作不保证生成的RDD与原来RDD分区信息一致,但提供了mapValue和flatMapValues,这两个接口保证输出的key保持相同。cogroup、 groupWith、join、leftOuterJoin、rightOuterJoin、groupByKey、reduceByKey、 combineByKey和partitionBy、sort、mapValues、flatMapValues和filter产生的RDD会继承分区信 息,其他转换生成的RDD无分区信息。
 
代码示例:google的page rank
 

PageRank 是个迭代算法,要执行很多的连接,所以这是个 RDD 分区的好用例。 该算法包括两个数据集:一个是(pageID, linkList),其元素包含了每个页的邻居 列表;另一个是(pageID, rank),其元素是每个页的当前 rank。处理流程如下:

1. 初始化每页的 rank 为 1.0

2. 对每次迭代,页面 p 发送 rank(p)/numNeighbors(p)的贡献给它的邻居(该 页连接出去的)

3. 设置每页的 rank 为 0.15+0.85*contributionsReceived。

最后两步重复的多次迭代,算法会收敛到每个页面都有正确的 PageRank 值。实 际上,一般要运行大约 10 次迭代。

代码示例:
 
说明:通过link将每个page的邻居列表及该page的rank关联起来,然后通过flatMap操作将本page的贡献度计算出来,然后对所有的page共享度RDD进行reduce,得到本次Rank,迭代计算10次后得到最终排名。
代码特点:
  • 将link持久化,避免分区间数据交互;
  • 使用mapValues创建ranks,保留了分区信息,第一次join开销不大;
  • 最后在reduceByKey后面使用mapValues,因为reduceByKey的结果时有分区的,此时mapValues继承分区信息,提高效率;
 

自定义分区

自定义partitioner需要子类化org.apache.spark.Partitioner实现三个方法
numPartitions:返回创建的分区数
getPartition(Key: Any):返回指定Key对应的分区
equals:Java标准方法,用于判断RDD的分区是否一致
注意:若算法依靠java的hashcode方法,需要控制确保getPartition总是返回非负数
 
在equal方法中,通过scala的match判断other的类型,若是DomainNamePartitioner则判断分区数是否一致,否则返回false;
 

Learning Spark 第四章——键值对处理的更多相关文章

  1. 《Deep learning》第四章——数值计算

    数值计算 机器学习算法通常需要大量的数值计算.这通常是指通过迭代过程更新解的估计值来解决数学问题的算法,而不是通过解析过程推导出公式来提供正确解的方法.常见的操作包括优化(找到最小化或最大化函数值的参 ...

  2. Learning Spark中文版--第四章--使用键值对(2)

    Actions Available on Pair RDDs (键值对RDD可用的action)   和transformation(转换)一样,键值对RDD也可以使用基础RDD上的action(开工 ...

  3. Learning Spark中文版--第四章--使用键值对(1)

      本章介绍了如何使用键值对RDD,Spark中很多操作都基于此数据类型.键值对RDD通常在聚合操作中使用,而且我们经常做一些初始的ETL(extract(提取),transform(转换)和load ...

  4. Spark学习之键值对操作总结

    键值对 RDD 是 Spark 中许多操作所需要的常见数据类型.键值对 RDD 通常用来进行聚合计算.我们一般要先通过一些初始 ETL(抽取.转化.装载)操作来将数据转化为键值对形式.键值对 RDD ...

  5. Spark 键值对RDD操作

    键值对的RDD操作与基本RDD操作一样,只是操作的元素由基本类型改为二元组. 概述 键值对RDD是Spark操作中最常用的RDD,它是很多程序的构成要素,因为他们提供了并行操作各个键或跨界点重新进行数 ...

  6. Spark中的键值对操作-scala

    1.PairRDD介绍     Spark为包含键值对类型的RDD提供了一些专有的操作.这些RDD被称为PairRDD.PairRDD提供了并行操作各个键或跨节点重新进行数据分组的操作接口.例如,Pa ...

  7. Spark中的键值对操作

    1.PairRDD介绍     Spark为包含键值对类型的RDD提供了一些专有的操作.这些RDD被称为PairRDD.PairRDD提供了并行操作各个键或跨节点重新进行数据分组的操作接口.例如,Pa ...

  8. 3. 键值对RDD

    键值对RDD是Spark中许多操作所需要的常见数据类型.除了在基础RDD类中定义的操作之外,Spark为包含键值对类型的RDD提供了一些专有的操作在PairRDDFunctions专门进行了定义.这些 ...

  9. 【原】Learning Spark (Python版) 学习笔记(二)----键值对、数据读取与保存、共享特性

    本来应该上周更新的,结果碰上五一,懒癌发作,就推迟了 = =.以后还是要按时完成任务.废话不多说,第四章-第六章主要讲了三个内容:键值对.数据读取与保存与Spark的两个共享特性(累加器和广播变量). ...

随机推荐

  1. FineUI(专业版)公测版发布(这速度,真TM快!)

    经过近一年的筹备.编码和测试,FineUI(专业版)公测版终于和大家见面了!现在就来体验一下专业版飞一般的速度吧:http://fineui.com/demo_pro/FineUI(专业版)首页:ht ...

  2. C#扩展方法

    扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法就相当于一个马甲,给一个现有类套上,就可以为这个类添加其他方法了. 马甲必须定义为stati ...

  3. od 查看特殊格式的文件内容

    用户通常使用od命令查看特殊格式的文件内容.通过指定该命令的不同选项可以以十进制.八进制.十六进制和ASCII码来显示文件. 语法: od [选项] 文件- 命令中各选项的含义: - A 指定地址基数 ...

  4. cosbench 压测RGW生产环境

    配置信息: 使用  2个万兆网卡的RGW主机,并用OSPF做高可用和负载均衡.  Ceph OSD集群 有21Node (万兆网卡+ 12个4T SATA机械硬盘) 测试VM配置: 使用在使用VXLA ...

  5. [CI] 使用Jenkins自动编译部署web应用

    写在前面 初步接触持续集成自动化过程,本篇主要介绍基于Jenkins实现持续集成的方式,通过案例介绍线上自动编译及部署的配置过程 持续集成 持续集成是一种软件开发实践,即团队开发成员经常集成它们的工作 ...

  6. sql 代码笔记

    1. if() 函数 推荐一个学习MySQL的网站  Study MySql

  7. iOS开发中遇到的一些优化手段(即时更新)

    1.UIButton的点击优化(防止用户吃饱了没事干猛点按钮) - (void)starButtonClickedBack:(id)sender { NSLog(@"我没有优化按钮点击&qu ...

  8. Zabbix Trapper items

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px STHeiti; color: #313131 } span.s1 { } 概述 Trappe ...

  9. 【原创】自己动手写工具----XSmartNote [Beta 2.0]

    一.前面的话 在上一篇自己动手写工具----XSmartNote中,我简单介绍了这个小玩意儿的大致界面和要实现的功能,看了一下园子里的评论,评价褒贬不一,有人说“现在那么多云笔记的工具”,“极简版ev ...

  10. iframe自适应高度

    http://wenrunchang123.iteye.com/blog/1684843