RDD 编程
- RDD基础
spark对数据的核心抽象——弹性分布式数据集(Resilient Distributed Dataset,简称RDD),RDD是分布式元素的集合。在spark中,对数据的操作有创建RDD、转化RDD、action RDD;RDD是一个不可变的分布式对象集合,每个RDD都被分为多个分区,这些分区运行在集群中的不同节点上,rdd可以包含python、java、scala中的任意类型的对象。
用户可以使用两种方法创建RDD:(1)读取一个外部数据集;(2)在驱动器程序中分发驱动器程序的对象集合(list、set),对集合进行 并行化。
scala创建RDD
val inputRDD = sc.textFile("input.txt")
val lines = sc.parallelize(List("spark","i like spark"))
2 RDD操作
RDD支持两种操作:转化操作和行动操作,转化操作是返回一个新的RDD,而行动操作是向驱动器程序返回结果或把结果写入到外部系统的操作。spark对待行动操作和转化操作的方式很不一样,转化操作返回的结果仍然是RDD,而行动操作返回的是其他数据类型。
2.1 转化操作
RDD的转化操作是返回新RDD的操作。转化出来的RDD是惰性求值的,只有在行动操作中用到这些RDD时才会被计算。
val errorsRDD = inputRDD.filter(line => line.contains("error"))
filter()操作不会改变已有的inputRDD中的数据,只会返回一个全新的RDD。通过转化操作,从已有的RDD中派生出新的RDD,spark会使用谱系图来记录这些不同的RDD之间的依赖关系。
转换操作在生成RDD的时候,生成的是多个RDD,这里的RDD生成方式并不是一次性生成多个,而是由上一级的RDD依次往下生成,我们将其称为依赖,RDD的依赖生成方式也不尽相同,在实际工作中,RDD一般由两种方式生成:宽依赖和窄依赖,如果一个RDD的子RDD只有一个父RDD,同时父RDD也只有一个子RDD时,这种生成关系称之为窄依赖,而多个RDD相互生成,称之为宽依赖。在实际应用中,窄依赖便于单一节点按次序执行,任务可控,宽依赖更多的考虑任务的交互和容错性。
2.2 行动操作
有时候我们希望对数据集,进行实际的计算,行动操作是第二种类型的RDD操作,它们会把最终求的的结果,返回到驱动器程序,或者写入外部存储系统,由于行动操作需要生成实际的输出,它们会强制执行那些求值必须用到的RDD转化操作。
val warningRDD = inputRDD.filter(line=>line.contains("waining"))
val badlineRDD = warningRDD.union(errorsRDD)
badlineRDD.take(10).foreach(println)
RDD还有一个collect()函数,可以用来获取整个RDD中的数据,小数据集可以使用。
2.3 惰性求值
RDD的转化操作是惰性求值的,这意味着在被调用行动操作之前spark不会开始计算,spark会在内部记录下所要求执行的操作的相关信息。不应该把RDD看作存放特定数据的数据集,而最好把每个RDD当作我们通过转化操作构建出来的,记录如何计算数据的指令列表,把数据读取到RDD的操作也是惰性的。因此当我们调用sc.textFile()时,数据并没有读取进来,而是在必要时候才会读取进来,和转化操作一样的是,读取数据的操作也可能多次执行。
虽然RDD转化操作是惰性求值的。但是可以随时通过运行一个行动操作来强制spark执行RDD的转化操作。例如:count()、first()。