Spark学习——RDD操作

本文详细介绍了Spark中的RDD操作,包括创建、转化和行动操作,如parallelize、union、map、filter、reduce等。同时,重点讲解了RDD的持久化机制,如cache和persist方法,以及不同级别的持久化策略,强调了缓存对于大规模数据处理的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RDD操作

  • 创建RDD
    • 两种创建方式
      • parallelize() 方法
      lines = sc.parallelize(["pandas", "i like pandas"])
      
      • 外部读取数据创建RDD
      lines = sc.textFile("/path/to/README.md")
      
  • RDD操作
    • 转化操作

      • 返回新的RDD

      • 针对各个元素的转换操作

        • 实现map()转化操作
        nums = sc.parallelize([1, 2, 3, 4])
        squared = nums.map(lambda x: x * x).collect()
        for num in squared:
            print "%i " % (num)
        
        • 实现flatMap()转化操作
        lines = sc.parallelize(["hello world", "hi"])
        words = lines.flatMap(lambda line: line.split(" "))
        words.first() # 返回"hello"
        # platMap实现由一个输入元素生成多个输出元素
        
        lines = sc.parallelize(["hello world", "hi"])
        words = lines.map(lambda line: line.split(" "))
        words.first() # 返回"['hello', 'word']"
        
        • 实现filter()转化操作
        inputRDD = sc.text.File("log.txt")
        errorsRDD = inputRDD.filter(lambda x:"error" in x)
        

        -实现union()转化操作

        errorsRDD = inputRDD.filter(lambda x: "error" in x)
        warningsRDD = inputRDD.filter(lambda x: "warning" in x)
        badLinesRDD = errorsRDD.union(wariningsRDD)
        
      • 伪集合操作

        • 实现union()操作 返回两个RDD中所有元素

        与数学中的union()操作不同的是,如果输入的RDD中有重复数据,Spark的union()操作也会包含这些重复数据(如有必要,我们可以通过distinct() 实现相同的效果)。

        • 实现distinct()操作 去除两个RDD中重复的元素
        • 实现inersection()操作 只返回两个RDD重并都有的元素
        • 实现subtract()操作 返回一个由只存在于第一个RDD中而不存在于第二个RDD 中的所有元素组成的RDD
        • 实现cartesian()操作 计算两个RDD的笛卡儿积
    • 行动操作

      • reduce()操作 接收一个函数作为参数,这个函数要操作两个RDD的元素类型的数据并返回一个同样类型的新元素。
          sum = rdd.reduce(lambda x,y : x+y)
      
      • fold(zero)()操作
          sum = rdd.fold(1,(lambda x,y : x+y))
      
      • aggregate()操作
      rdd = sc.parallelize([1, 2, 3])
      sumCount = rdd1.aggregate((0,0),(lambda acc, value: (acc[0] +                                   value, acc[1]+1)),
                                      (lambda acc1, acc2:(acc1[0] + acc2[0], acc1[1] + acc2[1])))
      print( sumCount[0] / float(sumCount[1]))
      
      
      • take(n)操作
      • top()操作 会使用数据的默认顺序
      • foreach()操作 对RDD 中的每个元素使用给定的函数
      • 利用count()进行计数
      print "Input had " + badLinsRDD.count() + " concerning lines"
      print "Here are 10 examples:"
      for line in badLinesRDD.take(10):
          print line
      
      • collect()函数

      RDD 还有一个collect() 函数,可以用来获取整个RDD 中的数据。如果你的程序把RDD筛选到一个很小的规模,并且你想在本地处理这些数据时,就可以使用它。记住,只有当你的整个数据集能在单台机器的内存中放得下时,才能使用collect(),因此,collect() 不能用在大规模数据集上。向驱动器返回结果。触发实际计算。

向Spark传递函数

word = rdd.filter(lambda s : "error" in s)

def containsError(s):
    return "error" in s

word = rdd.filter(containsError)

持久化(缓存)

  • 优势:
    • 避免对此重计算,造成格外大的开销;
    • 如果一个有持久化数据的节点发生故障,Spark会在需要用到缓存的数据时重算丢失的数据分区。
  • cache() 是persist()的简化方式,调用persist的无参版本,也就是调用persist(StorageLevel.MEMORY_ONLY),cache只有一个默认的缓存级别MEMORY_ONLY,即将数据持久化到内存中。
  • persist() 可以通过传递一个 StorageLevel 对象来设置缓存的存储级别。
  • 持久化级别
持久化级别说明
MEMORY_ONLY将RDD以非序列化的Java对象存储在JVM中。如果没有足够的内存存储RDD,则某些分区将不会被缓存,每次需要时都会重新计算。这是默认级别。
MEMORY_AND_DISK将RDD以非序列化的Java对象存储在JVM中。如果数据在内存中放不下,则溢写到磁盘上.需要时则会从磁盘上读取
MEMORY_ONLY_\SER (Java and Scala)将RDD以序列化的Java对象(每个分区一个字节数组)的方式存储.这通常比非序列化对象(deserialized objects)更具空间效率,特别是在使用快速序列化的情况下,但是这种方式读取数据会消耗更多的CPU。
MEMORY_AND_DISK_SER (Java and Scala)与MEMORY_ONLY_SER类似,但如果数据在内存中放不下,则溢写到磁盘上,而不是每次需要重新计算它们。
DISK_ONLY将RDD分区存储在磁盘上。
MEMORY_ONLY_2, MEMORY_AND_DISK_2等与上面的储存级别相同,只不过将持久化数据存为两份,备份每个分区存储在两个集群节点上。

 

内容来自《Spark快速大数据分析》

"持久化级别"引自:https://blog.youkuaiyun.com/sunnyyoona/article/details/73348202

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值