RDD方法学习(map,mapPartitions,mapPartitionsWithIndex,flatMap)

RDD方法:1.转换:功能的补充和封装,将旧的RDD包装成新的RDD(flatmap,map)

                   2.行动:触发任务的调度和作业的执行(collect)

IDEA代码自动补全https://cloud.tencent.com/developer/article/1581092

scala匿名函数需要学习一下,类似过程:

   //val mapRDD: RDD[Int] = rdd.map(mapFunction)
    //val mapRDD: RDD[Int] = rdd.map((num:Int)=>{num*2})
    //val mapRDD: RDD[Int] = rdd.map((num:Int)=>num*2)
    //val mapRDD: RDD[Int] = rdd.map((num:Int)=>num*2)
    //val mapRDD: RDD[Int] = rdd.map((num)=>num*2)
    //val mapRDD: RDD[Int] = rdd.map(num=>num*2)
    val mapRDD: RDD[Int] = rdd.map(_*2)

 

RDD方法=>RDD算子(operator)

RDD转换算子:根据数据处理方式不同整体分为1.Value类型 2.双Value类型3.Key-Value类型

Value类型

1.map:将处理的数据逐(zhu)条进行映射转换,可以是类型,也可以是值的转换。

小功能:从服务器日志数据apache.log中获取用户请求URL资源路径(今天6.9记得回去下载学习资料放进U盘里)

    //读取log文件,文件行数据类型为ip地址 - - path
    //只选择path信息

    //TODO 算子-map
    val rdd=sc.textFile("data/apache.log")

    //长字符串=>短字符串
    val mapRDD: RDD[String] = rdd.map(

      line => {
        val datas = line.split(" ")
        datas(6)
      }
    )
    mapRDD.collect().foreach(println)

rdd的计算一个分区内的数据是一个个执行逻辑,只有前面一个数据全部逻辑执行完毕后才会执行下一个数据。分区内数据的执行是有序的。不同分区数据计算是无序的。

 

 

 

以上方法类似于java IO流的单字节操作,引入新的算子,类比成buffer提供缓冲区。

rdd.mapPartitions()迭代器返回迭代器,批处理的感觉。

2.mapPartitions:将待处理的数据以分区为单位发送到计算结点进行处理,这里的处理是指可以进行任意的处理,如过滤数据

可以以分区为单位进行数据转换操作,但是会将整个分区的数据加载到内存进行引用。如果处理完的数据是不会被释放,存在对象的引用。在内存较小,数据量较大的场合下,容易出现内存溢出。

取获取分区数据最大值作为一个小功能进行实现 45节

    //TODO 算子-mapPartition
    val rdd=sc.makeRDD(List(1,2,3,4),2)
    val mpRDD: RDD[Int] = rdd.mapPartitions(
      iter => {
        List(iter.max).iterator
        //iter.map(_ * 2)
      }
    )
    mpRDD.collect().foreach(println)

mapmapPartitions区别

1.数据处理角度

map:分区内一个数据一个数据的执行,类似于串行操作。

mapPartitions:以分区为单位进行批处理操作

2.功能角度

map:将数据源中数据进行转换和改变,但不会减少或增多数据

mapPartitions:需传递一个迭代器并返回一个迭代器。没有要求元素个数保持不变,所以可以增加或减少数据

3.性能角度

map:类似于串行操作,所以性能较低

mapPartitions:类似于批处理,性能较高但是会长时间占用内容,导致内存不够用,内存溢出的错误。

内存有限使用map

3.mapPartitionsWithIndex:将待处理数据以分区为单位发送到计算节点进行处理,做任何处理,在处理同时获取当前分区索引。

f:(Int, Iterator[T])=>Iteator[U]

小功能:获取第二个数据分区的数据

    val rdd=sc.makeRDD(List(1,2,3,4),2)
    val mpiRDD=rdd.mapPartitionsWithIndex(
      (index,iter)=>{
        if(index==1){
          iter
        }else{
          Nil.iterator
        }
        //iter
      })
    mpiRDD.collect().foreach(println)

获取数据分区的索引

    val rdd = sc.makeRDD(List(1, 2, 3, 4))
    val mpiRDD=rdd.mapPartitionsWithIndex(
      (index,iter)=>{
        //(0,1)(2,2)
        iter.map(
          num=>{
            (index,num)
          }
        )
      }
    )
    mpiRDD.collect().foreach(println)

4.flatMap:将处理的数据进行扁平化处理后再进行映射处理,算子也称为扁平映射(48节)

小功能:将List(List(1,2),List(4,5))进行扁平化操作

    //TODO 算子-flatmap
    val rdd: RDD[List[Int]] = sc.makeRDD(List(
      List(1, 2), List(3, 4)
    ))
    val flatRDD: RDD[Int] = rdd.flatMap(
      list => {
        list
      }
    )
    flatRDD.collect().foreach(println)

现在遇到一个大问题,scala下的split无法使用。pom.xml被我改坏了。

重新开始建立scala项目,添加pom.xml中的依赖关系。加入log4配置文件(第10节)。

https://www.cnblogs.com/-beyond/p/11557196.html

IDEA存在缓存,所以pom文件修改后读取的是缓存中pom的为了提高效率,但是type mismatch问题并没有解决

https://www.cnblogs.com/yanch01/p/12258713.html

https://www.cnblogs.com/jooy/p/9146527.html

 

index过程缓慢,暂时没有解决。

5.glom:将同一个分区的数据直接转换为相同类型的内存数组进行处理,分区不变。数据也没有发生变化。

计算所有分区最大值求和(分区内取最大值,分区内最大值求和)分区内写逻辑

6.groupBy

分组和分区没有必然联系。有底层逻辑但是没有必然关系。

分组可能会导致数据分区不一样。group会把数据打乱,重新组合,这个操作叫shuffle。极限情况下,数据可能被分在同一分组。

7.filter

 

最后通过改版本暂时解决spark-core_2.12 version 2.4.3

之前3.0.0一些函数不支持,错误的修改了pom文件。引入的包造成冲突后,又去program structure进行problem fix。被直接remove了。还没解决为什么。mark一下之后过来改。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值