资源是可以服用的

  1. RDD是可以复用的

 

RDD是abstract

  1. 有多少种子类

  2. A Resilient Distributed Dataset (RDD)弹性分布式数据集

  3. 五种属性

    1. A list of partitions -分区列表

    2. A function for computing each split -计算每个分裂的函数

    3. A list of dependencies on other RDDs -其他RDD依赖列表

    4. Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned) - 分区根据key分区,默认是hash%分区数

    5. Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file) - 计算向数据移动

 

 

Spark wordcount源码分析

val fileRdd = sc.textFile("D:\\code\\scala\\test\\one\\data\\testdata.txt")
1.sparkContext.textFile RDD第一个子类 -> 类继承 依赖参数传空
2.HadoopRDD 解决文件数据输入
3.HadoopRDD -> getPartitions获取分区 -> 200行 getInputFormat(jobConf).getSplits(jobConf, minPartitions) 说明 切片数 = 分区数(默认)   Splits = partitions
4. compute() 包装了一个迭代器 -> getNext() -> !reader.next(key, value) -> inputFormat.getRecordReader(split.inputSplit.value, jobConf, Reporter.NULL)
5. 所以inputFormat作用: 1.获取分区 2.记录读取器(方便写一个迭代器来找)
6.目前来看HadoopRDD,不存数据(new HadoopRDD)

 

val words = fileRDD.flatMap((x:String)=>{x.split(" ")})
1.fileRDD.flatMap() 第二个子类
2.不存数据new MapPartitionsRDD
3.prev =this 代表前一个RDD(HadoopRDD)的地址
4.MapPartitionsRDD -> compute() -> f(context, split.index, firstParent[T].iterator(split, context)) -> 子类没有iterator()找父类 ->firstParent[T].iterator(split, context)或者调用父类的迭代器或者调用上一个的compute()
5.调用一个构造this(oneParent.context, List(new OneToOneDependency(oneParent))),一对一,块一一对应

 

 

val tuple2:RDD[(String, Int)] = words.map((x:String)=>{new Tuple2(x, 1)})
1. new MapPartitionsRDD不存数据
2. 照抄flatMap()方法源码解析

以上是pipeline操作(管道)

 

val res = tuple2.reduceByKey((x:Int, y:Int) => {x + y})
1.因为数据在不同的分区(切片),所以推断需要一个Shuffle,
2. reduceByKey(defaultPartitioner(self), func) -> defaultPartitioner(self) -> new HashPartitioner(defaultNumPartitions)
3. reduceByKey(defaultPartitioner(self), func) -> combineByKeyWithClassTag[V]((v: V) => v, func, func, partitioner)(combine压缩可以做优化,加快计算) ->combineByKeyWithClassTag(第一条数据值,函数2,函数3,分区器) ->
    方法入参解释: 1: 第一条数据值 2.老值 + 新值 3.处理溢血的值 老值加新值
4.new ShuffledRDD 不存数据
5.@transient打断序列化 -> 之前的方法都没有使用该注解 -> 推断之前的mapreduce 先跑一遍map在跑一遍reduce -> 现在可以把map、reduce拆开 -> 也就是map 跑完了就完了 -> 可以接着跑各种各样的reduce,没必要再跑一遍map
6.ShuffledRDD -> getDependencies() -> List(new ShuffleDependency(prev, part, serializer, keyOrdering, aggregator, mapSideCombine)) ->
前一个的自己(前一个RDD),分区器、序列化器、是否排序、聚合器(3中三个函数)、是否压缩
7.compute() -> getReader().read() -> 读Shuffle工作 -> 产生一个迭代器 -> 并没有调用上一个迭代器
8.Shuffle工作原理 --> ShuffleMapTask类 -> runTask() -> 推断 -> 上一个RDD 使用shuffleManager 调用了writer.weiter() 写入到File.txt -> 然后上一步7进行了读取

 

压缩

如果有四个(H1,1),(H1,1),(H1,1),(H2,1) 内存只能存2条数据。

第一条进来(H,1)
第二条进来 老值+新值 进行溢写
依次类推进行溢写
最终将溢写的值 老值+新值

 

Spark RDD

1.创建算子(create)
    -> textFile() 
2.转换算子(transformation)
   --> map flatMap filter
    --> reduceBykey groupByKey
3.执行算子(action)
  --> foreach collect saveasFile
4.控制算子(controller)
    --> cache checkpoint    

 


RDD dependency
NarrowDependency包括(OneToOneDependency, RangeDependency)

OneToOneDependency     1对1
RangeDependency        1对1(可以多个写多一个),数据计算的时候不会夸机器,union是在每台机器计算完成后,将结果返回给客户端
ShuffleDependency      1对多                 数据计算的时候需要夸机器   

判断是否shuffle依赖,需要看父依赖是否一对一

 










































posted on 2021-02-04 22:46  陕西小楞娃  阅读(87)  评论(0编辑  收藏  举报