2
本文摘自《Spark 快速大数据分析》

概述

  • RDD 支持两种操作:转化操作(Transformation)和行动操作(Action)。
  • 转化操作时返回一个新的 RDD 的操作,比如 map() 和 filter()。
  • 行动操作则是向驱动器程序返回结果或把结果写入外部系统的操作,会触发实际的计算,比如 count() 和first()。
  • Spark 对待转化操作和行动操作的方式很不一样,因此理解你正在进行的操作很重要的。
  • 如果对于一个特定的函数是属于转化操作还是行动操作感到困惑,你可以看看它的返回值类型:转化操作返回的是 RDD,而行动操作返回的是其他的数据类型。

RDD 转化操作

表 3-2

对一个数据为 {1, 2, 3, 3} 的 RDD 进行基本的 RDD 转化操作
表格中的 to 函数相当于 range
函数名目的示例结果
map()将函数应用于 RDD 中的每个元素,将返回值构成新的 RDDrdd.map(x -> x+1){2, 3, 4, 4}
flatMap()将函数应用于 RDD 中的每个元素,将返回的迭代器的所有内容构成新的 RDD。通常用来切分单词rdd.flatMap(x -> x.to(3)){1, 2, 3, 2, 3, 3, 3}
filter()返回一个由通过传给 filter() 的函数的元素组成的 RDDrdd.filter(x -> x != 1){2, 3, 3}
distinct()去重rdd.distinct(){1, 2, 3}
sample(withReplacement, fraction, [seed])对 RDD 采样,以及是否替换rdd.sample(false, 0.5)非确定的

表 3-3

对数据分别为 {1, 2, 3} 和 {3, 4, 5} 的 RDD 进行针对两个 RDD 的转化操作
函数名目的示例结果
union()生成一个包含两个 RDD 中所有元素的RDD rdd.union(other){1, 2, 3, 3, 4, 5}
intersection()求两个 RDD 共同的元素的 RDDrdd.intersection(other){3}
subtract()移除另一个 RDD 中的元素rdd.subtract(other){1, 2}
cartesian()于另一个 RDD 的笛卡尔积rdd.cartesian(other){(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 3), (3, 4), (3, 5)}

RDD 行动操作

  • 表 3-4:对一个数据为 {1, 2, 3, 3} 的 RDD 进行基本的 RDD 行动操作

    函数名目的示例结果
    collect()返回 RDD 中的所有元素rdd.collect(){1, 2, 3, 3}
    count()RDD 中的元素个数rdd.count()4
    countByValue()各元素再 RDD 中出现的次数rdd.countByValue(){(1, 1), (2, 1), (3, 2)}
    take(num)从 RDD 中返回 num 个元素rdd.take(2){1, 2}
    top(num)从 RDD 中返回最前面的 num 个元素rdd.top(2){3, 3}
    takeOrdered(num)(ordering)从 RDD 中按照提供的顺序返回最前面的 num 个元素rdd.takeOrdered(2)(myOrdering){3, 3}
    takeSample(withReplacement, num, [seed])从 RDD 中返回任意一些元素rdd.takeSample(false, 1)非确定的
    reduce(func)并行整合 RDD 中的数据(例如 sum)rdd.reduce((x, y) -> x + y)9
    fold(zeor)(func)和 reduce() 一样,但是需要提供初始值rdd.fold(0)((x, y) -> x + y)9
    ★ aggregate(zeroValue)(seqOp, combOp)和 reduce() 相似,但是通常返回不同类型的函数rdd.aggergate((0, 0))((x, y) -> (x._1 + y, x._2 + 1), (x, y) -> (x._1 + y._1, x._2 + y._2))(9, 4)
    foreach(func)对 RDD 中的每个元素使用给定的函数rdd.foreach(func)

Pair RDD 转化操作

表 4-1

Pair RDD 的转化操作,以键值对{(1, 2), (3, 4), (3, 6)} 为例
函数名目的示例结果
reduceByKey(func)合并具有相同键的值rdd.reduceByKey((x, y) -> x + y){(1, 2), (3, 10)}
groupByKey()对具有相同键的值进行分组rdd.groupByKey(){(1, [2]), (3, [4, 6])}
★ combineByKey(createCombiner, mergeValue, mergeCombiners, partitioner)使用不同返回类型合并具有相同键的值见例4-12 到例 4-14
mapValues(func)对 pair RDD 中的每个值应用一个函数而不改变键rdd.mapValues(x -> x + 1){(1, 3), (3, 5), (3, 7)}
flatMapValues(func)对 pair RDD 中的每个值应用一个返回迭代器的函数,然后对返回的每个元素都生成一个对应原键值对记录。通常用于符号化rdd.flatMapValues(x -> (x to 5)){(1, 2), (1, 3), (1, 4), (1, 5), (3, 4), (3, 5)}
keys()返回一个仅包含键的 RDDrdd.keys(){1, 3, 3}
values()返回一个仅包含值的 RDDrdd.values(){2, 4, 6}
sortByKey()返回一个根据键排序的 RDDrdd.sortByKey(){(1, 2), (3, 4), (3, 6)}
  • 表 4-2:针对两个 Pair RDD 的转化操作,rdd = {(1, 2), (3, 4), (3, 6)} other = {(3, 9)}

    函数名目的示例结果
    subtractByKey删掉 RDD 中键与 other RDD 中的键相同的元素rdd.substractByKey(other){(1, 2)}
    join对两个 RDD 进行内连接rdd.join(other){(3, (4, 9)), (3, (6, 9))}
    ★ rightOuterJoin对两个 RDD 进行连接操作,确保第一个 RDD 的键必须存在(右外连接)rdd.rightOuterJoin(other){(3, (Some(4), 9)), (3, (Some(6), 9))}
    ★ leftOuterJoin对两个 RDD 进行连接操作,确保第二个 RDD 的键必须存在(左外连接)rdd.leftOuterJoin(other){(1, (2, None)), (3, (4, Some(9))), (3, (6, Some(9)))}
    cogroup将两个RDD 中拥有相同键的数据分组到一起rdd.cogroup(other){(1, ([2], [])), (3, ([4, 6], [9]))}

Pair RDD 行动操作

表 4-3

Pair RDD 的行动操作,以键值对集合 {(1, 2), (3, 4), (3, 6)} 为例
函数名目的示例结果
countByKey()对每个键对应的元素分别计数rdd.countByKey(){(1, 1), (3, 2)}
collectAsMap()将结果以映射表的形式返回,以便查询rdd.collectAsMap()Map{(1, 2), (3, 6)}
lookup(key)返回给定键对应的所有值rdd.lookup(3)[4, 6]
本文出自 qbit snap

qbit
268 声望279 粉丝