SPARK入门--RDD编程

  1. RDD简介

    spark中的rdd就是一个不可变的分布式对象集合。每个rdd都被分为多个分区,这些分区运行在集群中不同的节点上。rdd可以包含python,java,scala中任意类型的对象,甚至可以包含用户自定义对象。

    RDD支持两种类型的操作:一是转化操作,一个是行动操作,转化操作返回的是RDD, 行动操作返回的是其他类型。

  2. 创建RDD:

    创建RDD最简单的方式是吧程序中一个已有的集合传给SparkContext的paralleize()方法,这种方式在学习spark时非常有用,可以快速创建rdd,然后对其进行操作,代码如下

    启动pyspark(见上一篇)输入:

    lines = sc.parallelize(["hello girl", "it's me"])

    如上代码是用python形式在内存中创建了一个名为lines的rdd,开发时这种方式运用的并不多,因为这样把整个数据集先放到了一台机器的内存中了。

    更常用的方式是从外部存储中读取数据来创建RDD,比如从一个文本文件来创建存储字符串的rdd, 代码如下:

    lines = sc.textFile("/path/to/README.md")

    如上代码是创建了一个名为lines的rdd,其中存储的是文件README.md中的内容。

    这里的sc是SparkContext对象,在交互式操作时,shell启动时已经自动创建了SparkContext对象,也就是这里的sc,而在独立的python或java应用中,我们要手动创建SparkContext对象,如下代码演示:

    python:

    from pyspark import SparkConf, SparkContext

    conf = SparkConf().setMaster("local").setAppName("MyApp")

    sc = SparkContext(conf = conf)

    java:

    import org.apache.spark.SparkConf;

    import org.apache.spark.api.java.JavaSparkContext;

    SparkConf conf = new SparkConf().setMaster("local").setAppName("MyApp");

    JavaSparkContext sc = new JavaSparkContext(conf);

  3. RDD操作:

    3.1 转化操作:转化操作不改变原有的rdd数据,返回一个新的rdd

    比如:resultRdd = lines.filter(lambda x: "spark" in x)

    这句代码创建了一个名为resultRdd的新RDD对象,里面存储的是在lines中包含单词“spark”的所有行

    我们还可以用union来合并两个rdd形成一个新的rdd,比如:rdd1 = rdd2.union(rdd3)

    另外一个常用操作时map操作,map是对rdd里的每个元素进行规定的操作,比如:

    num = sc.parallelize([1,2,3,4])

    squared = num.map(lambda x: x*x)

    如上代码先创建了一个存储了四个整数的rdd,接着用map创建了一个存储了num里面每个数的平方的rdd,也就是[1,4,9,16]

    3.2 行动操作:行动操作会把计算结果返回给驱动程序

    比如 lines.count() 返回rdd中的元素个数,lines.first()返回rdd中的第一个元素,需要注意的是rdd是惰性求值的,也就是在行动操作之前spark不会开始操作。

  4. 向Spark传递函数:

    spark的大部分转化操作和一部分行动操作,都依赖用户传递的函数来计算。下面是python的传递方式:

    def containsError(s):

           return "error" in s

    word = rdd.filter(containErrors) 

    需要注意当你传递的对象是某个对象的成员,或者包含了对某个对象中一个字段的引用时,spark会把整个对象发到工作节点上,这会导致传递比你预期大得多的信息。可以把需要的字段从对象中提出来放到一个局部变量中,然后传递局部变量。

  5. 常见的转化操作和行动操作:

    转化操作:

    map() 将函数应用于rdd中的每个元素,将返回值构成新的rdd

    flatMap() 将函数应用于rdd中的每个元素,将返回的迭代器的所有内容构成新的rdd

    filter() 返回一个由通过传给filter()的函数的元素组成的rdd

    distinct() 去重

    union 生成一个包含两个rdd中所有元素的新的rdd

    intersection() 生成一个新的rdd存储两个rdd的交集 

    subtract() 生成一个新的rdd存储两个rdd的差集

    cartesian() 生成一个新的rdd 存储两个rdd的笛卡尔积

    行动操作:

    reduce(): 接收一个函数作为参数,这个函数接收两个相同元素类型的rdd数据并返回一个同样类型的新元素。比如用reduce求和。

    sum = nums.reduce(lambda x,y: x+y) 求出nums中所有元素的和。

    此外还有fold和aggregate,以后细说。

  6. 持久化:

     Spark RDD是惰性求值的,当我们多次使用同一个rdd的时候,spark每次都会重算该rdd以及它所有的依赖,这在迭代算法中消耗格外大,所以这时候我们需要对数据进行持久化。在python中,持久化默认级别是以序列化后的对象存储在jvm堆空间中。

    持久化的方法是persist(),比如,这样只计算一次squared,参数是持久化级别

    squared.persist(StorageLevel.DISK_ONLY)

    squared.count()

    squared.first()

转载于:https://my.oschina.net/u/2609444/blog/618839

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值