Spark学习(2) RDD编程

什么是RDD

RDD(Resilient Distributed Dataset)叫做分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变、可分区、弹性、里面的元素可并行计算的集合
RDD允许用户在执行多个查询时显式地将工作集缓存在内存中,后续的查询能够重用工作集,这极大地提升了查询速度
RDD支持两种操作:转化操作和行动操作
Spark采用惰性计算模式,RDD只有第一次在一个行动操作中用到时,才会真正计算

属性: 一组分区(Partition) 一个计算每个分区的函数 RDD之间的依赖关系 一个Partitioner
一个列表 移动数据不如移动计算
  • 每个节点可以起一个或多个Executor。
  • 每个Executor由若干core组成,每个Executor的每个core一次只能执行一个Task。
  • 每个Task执行的结果就是生成了下一个RDD的一个partiton。

特点:

分区:RDD逻辑上是分区的,每个分区的数据是抽象存在的

只读:RDD是只读的,要想改变RDD中的数据,只能在现有的RDD基础上创建新的RDD

依赖:RDDs通过操作算子进行转换,转换得到的新RDD包含了从其他RDDs衍生所必需的信息,RDDs之间维护着这种血缘关系,也称之为依赖

缓存:如果在应用程序中多次使用同一个RDD,可以将该RDD缓存起来,这样就加速后期的重用

checkPoint:RDD支持checkpoint将数据保存到持久化的存储中,这样就可以切断之前的血缘关系

RDD TransFormation

创建  makeRDD
删 filter  distinct 
改 map flatMap mapPartitions(每个分区执行一次 , 传入Iterator, 传出Iterator) 分区 coalesce repartition (切记是否需要suffer) partitionBy(自定义分区 , 根据业务减少数据倾斜)
排序 sortBy (sortByKey 完全可以简单的由sortBy实现, 第二个参数设置倒序 , 第三个参数设置分区数量 , suffer过程会重分区) 宽依赖
集合 union(并集 ,不去重) intersection(交集,去重) subtract (交集减并集) cartesian(笛卡尔积 , 形成map , 自以为无意义)
键值对 join((K,V)(K,W)形成(K,(v,w))) reduceByKey(根据key聚合计算value) groupBykey(感觉reduceByKey更好用) mapValues(对value进行转换) keys values (取出key 和 value)

Action

reduce(func)
collect()
count()
take(n) first(使用take(1)更好)
takeOrdered(n)
saveAsTextFile(path)
saveAsSequenceFile(path) 
saveAsObjectFile(path) 
countByKey()
foreach(func)

RDD持久化

RDD.persist 设置缓存
RDD.unpersist 清空缓存
建议使用这俩 , cache也行

RDD检查点机制
sc.setCheckpointDir("hdfs://CentOS1:9000/checkpoint")
    rdd.checkpoint()
    rdd.collect
检查点机制可以不依赖 依赖链, 缓存需要依赖

宽窄依赖

窄依赖,由于partition依赖关系的确定性,partition的转换处理就可以在同一个线程里完成,窄依赖就被spark划分到同一个stage中,而对于宽依赖,只能等父RDD shuffle处理完成后,下一个stage才能开始接下来的计算

spark划分stage:
  从后往前推,遇到宽依赖就断开,划分为一个stage;遇到窄依赖就将这个RDD加入该stage中。 ShuffleMapTask和ResultTask DAG的最后一个阶段会为每个结果的partition生成一个ResultTask,即每个Stage里面的Task的数量是由该Stage中最后一个RDD的Partition的数量所决定的,余所有阶段都会生成ShuffleMapTask;之所以称之为ShuffleMapTask是因为它需要将自己的计算结果通过shuffle到下一个stage中

广播变量和累加器

val broadcast = sc.broadcast(1 to 15)
sc.makeRDD(broadcast.value)
不使用广播变量会每一个task分配一个 , 占用空间 , 使用广播变量会每一个executor 存储一个 , 节省空间  , 变量只读 , 不可写

累加器

在项目中 , 经常遇到项目调试 , 监控 , 记录一些特征值的情况 , 需要使用累加器来解决
如果直接定义变量的话 , 每个task都会持有一份该变量 , 占空间 , 

 val a=sc.accumulator(0)
 sc.makeRDD(broadcast.value).map(x=>{a.add(1);x}).collect
 a.value
 
我凝视这恒星,等待这那场风暴,我已经准备好了
原文地址:https://www.cnblogs.com/cheng5350/p/11891830.html