spark 之RDD,DF,DS

  1. Spark 的存储级别的选择,核心问题是在 memory 内存使用率和 CPU 效率之间进行权衡。建议按下面的过程进行存储级别的选择:
    • 如果您的 RDD 适合于默认存储级别 (MEMORY_ONLY), leave them that way. 这是CPU效率最高的选项,允许RDD上的操作尽可能快地运行.
    • 如果不是, 试着使用 MEMORY_ONLY_SER 和 selecting a fast serialization library 以使对象更加节省空间,但仍然能够快速访问。 (Java和Scala)
    • 不要溢出到磁盘,除非计算您的数据集的函数是昂贵的, 或者它们过滤大量的数据. 否则, 重新计算分区可能与从磁盘读取分区一样快.
    • 如果需要快速故障恢复,请使用复制的存储级别 (e.g. 如果使用Spark来服务 来自网络应用程序的请求). All 存储级别通过重新计算丢失的数据来提供完整的容错能力,但复制的数据可让您继续在 RDD 上运行任务,而无需等待重新计算一个丢失的分区
  2. Spark 会自动监视每个节点上的缓存使用情况,并使用 least-recently-used(LRU)的方式来丢弃旧数据分区。 如果您想手动删除 RDD 而不是等待它掉出缓存,使用 RDD.unpersist() 方法。
  3. 广播变量存储级别为MEMORY_AND_DISK
  4. RDD,DataFrame,DataSet区别
    • RDD
      • 优点:
        • 编译时类型安全 编译时就能检查出类型错误
        • 面向对象的编程风格 直接通过类名点的方式来操作数据
      • 缺点:
        • 序列化和反序列化的性能开销 无论是集群间的通信, 还是IO操作都需要对对象的结构和数据进行序列化和反序列化
        • GC的性能开销 频繁的创建和销毁对象, 势必会增加GC
    • DataFrameDataFrame引入了schema和off-heap
      • schema : RDD每一行的数据, 结构都是一样的. 这个结构就存储在schema中. Spark通过schame就能够读懂数据, 因此在通信和IO时就只需要序列化和反序列化数据, 而结构的部分就可以省略了.
      • off-heap : 意味着JVM堆以外的内存, 这些内存直接受操作系统管理(而不是JVM)。Spark能够以二进制的形式序列化数据(不包括结构)到off-heap中, 当要操作数据时, 就直接操作off-heap内存. 由于Spark理解schema, 所以知道该如何操作
      • 其API不是面向对象的
            val idAgeRow = spark.sparkContext.parallelize(Seq(Row(1, 70), Row(2, 29), Row(4, 21)))
               val schema = StructType(Array(StructField("id", DataTypes.IntegerType), 		 StructField("age", DataTypes.IntegerType)))
               val idAgeDF = spark.sqlContext.createDataFrame(idAgeRow, schema)
               import spark.implicits._
               //可以看出此处API不是面向对象的!
               idAgeDF.filter($"age" > 25).show()
               //即使你洗了错误的类型编译时候也不会报错!运行时报错!
               idAgeDF.filter($"age" > 'a').show()
  • RDD是分布式的Java对象的集合。DataFrame是分布式的Row对象的集合
  • DataFrame除了提供了比RDD更丰富的算子以外,更重要的特点是提升执行效率、减少数据读取以及执行计划的优化,比如filter下推、裁剪等
  • DataFrame和DataSet可以相互转化,df.as[ElementType]这样可以把DataFrame转化为DataSet,ds.toDF()这样可以把DataSet转化为DataFrame
  1. spark的RDD,DataSet,DataFrame相互转换.
       def testDataFrameToConvertDataSet(spark: SparkSession): Unit = {
         val context = spark.sparkContext
         val peopleData = context.parallelize(Seq(Row(1, 31), Row(2, 34), Row(4, 39)))
         val peopleStruct = StructType(List(StructField("id", DataTypes.IntegerType), StructField("age", DataTypes.IntegerType)))
         import spark.implicits._
         val people = spark.createDataFrame(peopleData, peopleStruct).as[People]
         people.foreach(p => println(p.id + ":" + p.age))
         //String,Integer,Long支持直接创建DataSet
         spark.createDataset(context.makeRDD(Seq[People](People(1, 23), People(2, 43), People(9, 87)))).foreach(p => println(p.age))
       }
  • 这里的隐式转换要注意,很容易丢掉,就会造成case class的序列化不会成功.
  • 注意,scala版本何spark版本的一致性,这个会很容易坑的!

转载于:https://my.oschina.net/xd03122049/blog/1591093

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值