四、RDD、DataFrame和DataSet之间的转化和异同点

1、转化原理

RDD关心数据,DataFrame包含结构信息,关心结构,DataSet包含结构和类型信息,关心类型;

  ① 将RDD转换为DataFrame,需要增加结构信息,所以调用toDF方法,需要增加结构;

  ② 将RDD转换为DataSet,需要增加结构和类型信息,所以需要转换为指定类型后,调用toDS方法;

  ③ 将DataFrame转换为DataSet时,因为已经包含结构信息,只有增加类型信息就可以,所以调用as[类型]

  ④因为DF中本身包含数据,所以转换为RDD时,直接调用rdd即可;

  ⑤因为DS中本身包含数据,所以转换为RDD时,直接调用rdd即可;

  ⑥因为DS本身包含数据结构信息,所以转换为DF时,直接调用toDF即可

 2、Rdd->Dataset->Rdd转换案例

 

case class AbtestActionLogsModel(atype: String, domain: String,
                                 platform: String, version: String, action_big_id: String,
                                 action_small_id: String, action_id: String, txid: String,
                                 memo: String, location_id: String, msg: String, uid: String, url: String,
                                 uniqueid: String, projectid: String, planid: String, logType: String, var memoParam: String, var description: String, var memoValue: String) extends Serializable {

}

object AbtestActionMemo {

  def main(args: Array[String]): Unit = {
    var idate = args(0)
    println("date is:" + idate)
    val conf = new SparkConf()
      .setAppName("AbtestActionMemo")
    val sc = new SparkContext(conf)
    val sqlContext = new SQLContext(sc)

    val actionLogs: RDD[String] = sc.textFile("abtest_action_logs/dt=" + idate + "/type=t_app_action/*")

    //将日志转换成AbtestActionLogsModel类
    val actionLogsRdd: RDD[AbtestActionLogsModel] = actionLogs.map(lineToActionClass(_))


    //通过caseClassLogRdd获取DAU<1000的projectId和itemId
    import sqlContext.implicits._
    val actionLogsDataSet = actionLogsRdd.toDS()
    actionLogsDataSet.createTempView("actionLogs")
    val validProjectFrame: DataFrame = sqlContext.sql("select projectid,planid,count(distinct(uid)) uidCount from actionLogs " +
      "where txid in ('1002','2002') " +
      "group by projectid,planid " +
      "having uidCount>5000 " +
      "order by uidCount desc")
    //找到有效的projectId
    val validProjectsSet: Set[String] = validProjectFrame.rdd.map(row => {
      row.getAs[String]("projectid")
    }).collect().toSet
    validProjectsSet.foreach(println(_))
    }
}

 

3、三者的共性

(1)RDD、DataFrame、Dataset全都是spark平台下的分布式弹性数据集,为处理超大型数据提供便利;

(2)三者都有惰性机制,在进行创建、转换,如map方法时,不会立即执行,只有在遇到Action如foreach时,三者才会开始遍历运算;

(3)三者有许多共同的函数,如filter,排序等;

4、三者的区别

区别:RDD 优点: ①编译时类型安全 ;②面向对象的编程风格 ; ③直接通过类名点的方式来操作数据; 缺点是通信or IO操作都需要序列化和反序列化的性能开销 ,比较耗费性能; GC的性能开销 ,频繁的创建和销毁对象, 势必会增加GC;

DataFrame引入了schema和off-heap堆外内存不会频繁GC,减少了内存的开销; 缺点是类型不安全;

DataSet结合了它俩的优点并且把缺点给屏蔽掉了;

DataFrame也可以叫Dataset[Row],每一行的类型是Row,需要这取每一列的值

    val validProjectsSet: Set[String] = validProjectFrame.rdd.map(row => {
      row.getAs[String]("projectid")
    }).collect().toSet

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值