RDD编程

来源:互联网 发布:淘宝抢红包微信群 编辑:程序博客网 时间:2024/06/06 10:57

1. RDD基础:

    Spark 中的RDD 就是一个不可变的分布式对象集合。每个RDD 都被分为多个分区,这些分区运行在集群中的不同节点上。

    用户可以使用两种方法创建RDD:读取一个外部数据集,或在驱动器程序里分发驱动器程序中的对象集合(比如list 和se)。

    例如:用SparkContent.textFile()来读取文本文件作为一个字符串RDD的示例:

  lines = sc.textFile("README.md")
    可以对RDD进行两种操作: 转换操作和行动操作。转换操作会生成一个新的RDD,行动操作会对RDD计算出一个结果。Spark的RDD在每次进行行动操作时重新计算。如果想
在多个行动操作中重用同一个RDD,可以使用RDD.persist() 让Spark 把这个RDD 缓存到内存当中。


2. 创建RDD:

    2.1 SparkContent.parallelize()

    SparkContent.parallelize()可以将已有集合转化为RDD,但是并不常用,因为需要把所有数据存在一台机器的内存中。

  lines = sc.parallelize(["pandas", "i like pandas"])
     2.2 SparkContext.textFile()
  lines = sc.textFile("/path/to/README.md")
 

3.  RDD操作:

    转化操作(例如map() 和filter())返回的是RDD,而行动操作(例如count() 和first())返回的是其他的数据类型

    3.1 转换操作:

    选出log.txt中的错误消息:

  inputRDD = sc.textFile("log.txt")  errorsRDD = inputRDD.filter(lambda x: "error" in x)
   我们使用另一个转化操作union() 来打印出包含error 或warning 的行数。
  errorsRDD = inputRDD.filter(lambda x: "error" in x)  warningsRDD = inputRDD.filter(lambda x: "warning" in x)  badLinesRDD = errorsRDD.union(warningsRDD)
   Spark会用谱系图来记录这些转换之间的关系,好处是Spark可以利用这些关系计算每个RDD,持久化的RDD数据部分丢失时也可以恢复,如下图所示


    3.2 行动操作:
    行动操作会强制执行那些求值必须用到的RDD的转化操作。take()函数会获取最开始的n个元素,代码如下。
   
  sc.parallelize([2, 3, 4, 5, 6]).cache().take(2)
     需要注意的是,只有当单台机器的内存中放得下所有数据时,才使用collect()函数。
   3.3 惰性求值:
    转换操作只有在进行行动操作的时候才会被执行。如sc.textfile()并没有把数据读取进来,而是在必要时才会读取。

4. 向Spark传递函数
    有lambda函数方式和传递顶层函数方式
   
  word = rdd.filter(lambda s: "error" in s)  def containsError(s):      return "error" in s  word = rdd.filter(containsError)
    当传递的对象是某个对象的成员或者包含了对某个对象中的一个字段引用时,Spark会把整个对象发到工作节点上。解决办法是把需要的字段从对象中拿出来放到一个局部变量中,如下所示
class WordFunctions(object):...def getMatchesNoReference(self, rdd):# 安全:只把需要的字段提取到局部变量中query = self.queryreturn rdd.filter(lambda x: query in x)

5. 常用转换操作
 

6. 常用行动操作



7. 持久化数据
     如前所述,Spark RDD 是惰性求值的,而有时我们希望能多次使用同一个RDD。如果简单地对RDD 调用行动操作,Spark 每次都会重算RDD 以及它的所有依赖。这在迭代算法中消耗格外大,因为迭代算法常常会多次使用同一组数据。
    
    RDD的unpersist()可以手动把持久化的RDD从缓存中移除




原创粉丝点击