第3章 RDD

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010819416/article/details/82811557

弹性分布式数据集(Resilient Distributed Dataset,简称RDD),分布式的元素集合。

3.1 RDD基础

  • 创建RDD:
    1)读取一个外部数据集
    2)在驱动器程序里分发驱动器程序中的对象集合(list和set)

  • RDD支持的操作类型
    1)转化操作(transformation):一个RDD生成一个新的RDD
    2)行动操作(action):计算出结果,返回到驱动器程序中,或存储到外部存储系统

Spark只有第一次在一个行动操作中用到时,才会真正计算RDD,惰性计算。

如果想在多个行动操作中重用同一个RDD,可以使用RDD.persist()让Spark把这个RDD缓存下来。

3.2 RDD
1)读取外部数据集
2)在驱动器程序中对一个集合进行并行化

把一个已有集合传给SparkContext的parallelize()简单创建RDD。

3.3 RDD操作

3.3.1 转化操作

>>> inputRDD = sc.textFile('E:\spark\log.txt')
>>> errorsRDD = inputRDD.filter(lambda x: "error" in x)
>>> errorsRDD.first()
[Stage 0:>                                                          (0 + 1) / 1]

'error:'
>>>

3.3.2 行动操作

用count()来返回计数结果
用take()来收集RDD中的一些元素
collect()用来获取整个RDD中的数据
saveAsTextFile()、saveAsSequenceFile()把RDD的数据内容保存起来。

3.3.3 惰性求值
RDD的转化操作都是惰性求值的。

3.4 向Spark传递函数

3.4.1 Python
1)lambda表达式

>>> errorsRDD.filter(lambda s: "error" in s)

2)传递顶层函数或是定义的局部函数

3.4.2 Scala

3.4.3 Java
1)使用具名类进行函数传递
2)使用匿名内部类进行函数传递
3)lambda表达式

3.5 常见的转化操作和行动操作

3.5.1 基本RDD

  1. 针对各个元素的转化操作
    map()和filter()
>>> nums = sc.parallelize([1,2,3,4])
>>> squared = nums.map(lambda x : x * x).collect()
[Stage 4:>                                                          (0 + 4) / 4]

>>> for num in squared:
...     print("%i",num)
...
%i 1
%i 4
%i 9
%i 16
>>>

flatMap(): 对每个输入元素生成多个输出元素。

>>> lines = sc.parallelize(["hello world","hi"])
>>> words = lines.map(lambda line:line.split(" ")).collect()
[Stage 5:>                                                          (0 + 4) / 4]

>>> print(words)
[['hello', 'world'], ['hi']]
>>> words2 = lines.flatMap(lambda line : line.split(" ")).collect()
[Stage 6:>                                                          (0 + 4) / 4]

>>> print(words2)
['hello', 'world', 'hi']
>>>
  1. 伪集合操作
  • distinct()
    使用RDD.distinct()转化操作来生成一个只包含不同元素的新的RDD。

  • union()
    返回一个包含两个RDD中所有元素的RDD

  • intersection()
    只返回两个RDD中都有的元素

  • subtract()
    返回只存在于第一个RDD中而不存在于第二个RDD中的所有元素组成的RDD。

  • cartesian()
    笛卡尔积

3.行动操作

  • reduce(),fold()(加初始值)
    操作两个RDD的元素类型的数据并返回一个同样类型的新元素。
>>> nums = sc.parallelize([1,2,3,4])
>>> print(nums)
ParallelCollectionRDD[0] at parallelize at PythonRDD.scala:184
>>> sum = nums.reduce(lambda x,y : x + y)
[Stage 0:>                                                          (0 + 4) / 4]

>>> print(sum)
10
>>>
  • aggregate()
    返回值类型可以和RDD类型不同。
>>> nums = sc.parallelize([1,2,3,4,5])
>>> sumCount = nums.aggregate((0,0),(lambda acc,value:(acc[0] + value,acc[1] + 1
)),(lambda acc1,acc2:(acc1[0] + acc2[0],acc1[1] + acc2[1])))
[Stage 1:>                                                          (0 + 4) / 4]

>>> print(sumCount[0]/float(sumCount[1]))
3.0
>>>

3.5.2 在不同RDD类型间转换

  1. Scala

  2. Java
    1)JavaDoubleRDD
    2)JavaPairRDD

创建特殊类型的RDD:
1)使用特殊版本的Function
2)调用RDD上别的函数(mapToDouble()代替map())

  1. Python
    所有函数都实现在基本的RDD类中。

3.6 持久化(缓存)

  • persist()
    为避免多次计算同一个RDD,可以让Spark对数据进行持久化。
    把数据以序列化的形式缓存在JVM的堆空间中。

  • unpersist()
    手动把持久化的RDD从缓存中移除

3.7 总结

猜你喜欢

转载自blog.csdn.net/u010819416/article/details/82811557
rdd