1. 请描述spark RDD原理与特征

RDD为Resilient Distributed Datasets缩写,译文弹性分布式数据集。

他是spark系统中的核心数据模型之一,另外一个是DAG模型。

它是“只读”,“分区”的数据集合。其类内部有5个部分组成:

1. 一组partition    partitions_ : Array[Partition]

2.每个partition的计算函数 通过诗选compute函数达到这个目的。

3.RDD依赖关系,新的RDD可以从已有的RDD转换而来,当RDD中的分区丢失那么可以通过这个关系将这些数据从父RDD中重新计算。

4.一个分片函数partitioner,模式实现了了hashpartitioner和RangePartitioner。这个函数据定了当前RDD的分片数量,以及父RDD的shuffle输出时候的分片数量。

5.一个列表,保存了各个分区的优先位置,比如HDFS文件来说就保存了每一个分区的所在块的位置。

弹性分布式数据集的字面弹性和分布式的理解:

分布式很好理解,我们的数据是一般存储在hdfs分布式文件系统的,所以RDD也是分布式的。

弹性可以理解为两层意思:1,数据是可存储在磁盘或者内存,也可以部分分区在内存部分分区存储在磁盘。

            2,RDD的数据是可以通过父RDD进行恢复,且可以做到部分分区数据通过依赖关系进行恢复,这称之为“血统”。

RDD的产生:三种1,已有的scala的数据集合 2,外部存储系统如s3 hdfs等 3,通过父RDD的转换而来。

2.如何理解spark RDD宽依赖和窄依赖,并结合示例描述

spark从RDD依赖上来说分为窄依赖和宽依赖。

其中可以这样区分是哪种依赖:当父RDD的一个partition被子RDD的多个partitions引用到的时候则说明是宽依赖,否则为窄依赖。

宽依赖会触发shuffe,宽依赖也是一个job钟不同stage的分界线。

本篇文章主要讨论一下窄依赖的场景。

 3.基于spark-1.6.1版本,请描述spark统一内存管理机制,和各部分内存区域用途。

1.6版本之前使用的叫做StaticMemoryManager 1.6以及之后使用的内存管理机制叫做:UnifiedMemoryManager

相比于之前的内存管理机制,现在统一内存管理机制可以让storage、execution可以互相从对方借用内存,总体来说解决了如何资源充分利用的问题。

上述为统一内存模型,对相比最主要的区别在于Storage区域与Execution可以动态分配。

  • 设定基本的存储内存和执行内存区域(spark.storage.storageFraction 参数),该设定确定了双方各自拥有的空间的范围
  • 双方的空间都不足时,则存储到硬盘;若己方空间不足而对方空余时,可借用对方的空间;(存储空间不足是指不足以放下一个完整的 Block)
  • 执行内存的空间被对方占用后,可让对方将占用的部分转存到硬盘,然后"归还"借用的空间
  • 存储内存的空间被对方占用后,无法让对方"归还",因为需要考虑 Shuffle 过程中的很多因素,实现起来较为复杂[4]

4.spark中的RDD,dataframe和dataset有什么区别。

RDD,dataframe和dataset都是spark提供给开发者的三个主要API。

RDD是最底层的数据模型。属于spark-core包=模块中。

无论是dataframe还是dataset其最终都是转换为RDD来运行的。

而dataframe和dataset则数据spark-sql模块中。

dataframe则是特殊的dataset

type DataFrame = Dataset[Row]

其中dataset是强类型的,而dataframe则是无类型的。其中row即是一行带有列名及列值的数据。

dataframe与dataset  同 RDD比较,主要是解决了元数据问题。RDD不包含元数据。处理数据不够直观,代码阅读性不好。

而dataframe与dataset则不同,带有元数据,提供特定领域的转换方法。其内部通过Catalyst模块来进行执行优化,转化为RDD进行计算。

以上三种可以相互转换。

5.请描述spark运行时job,stage,task的划分原则,以及其相互间的关系。

个人理解:一个action操作形成一个job,job包含一个或者多个stage,stage包含task组成的taskset。

stage的划分点实在款依赖的RDD之间。同一个stage中都是窄依赖关系,各个分区可以并行执行。

task则是相互独立的分别作用在各个RDD分区之上的一个具体任务。

一个job下只分为shuffleMapTask和ResultTask。

其中一个job的最后stage为每一个结果的partition执行task为ResultTask

6.请描述spark hash shuffle与sort shuffle之间的区别和优劣点。

主要区别就是在于对于小文件的控制上。sort shuffle相比于 hash shuffle在map端产生的小文件更少。

有效降低IO,提高性能。目前sort shuffle是默认shuffle机制了。

hash shuffle在没有consolidation情况下将产生M*R个文件。M为Mapper个数,R为reducer个数。

如下图,其每一个map最坏的情况下都将为每一个reducer产生一个独立文件。

极端情况下,当数据量比较大,M和R都很大的情况下会产生大量的小文件。无论在你写还是在读的时候都会有大量的IO消耗。

而sort shuffle则将上述hash shuffle基础上,将一个mapper下产生的不同的reducer输入文件写到一个文件中,并额外通过一个索引文件去解析她。

这样M端IO将减少,R端的读取也将减少,从而降IO提高效率。

sort shuffle的写如下图:

7.spark计算容错性如何保证。

有Lineage机制和Checkpoint机制来保证。这个两个机制是建立在RDD是只读和分区的概念之上的。

Lineage机制:RDD中分区存在父RDD的分区的依赖关系,当前RDD中的某部分分区数据丢失则可以通过这个依赖关系进行数据重新计算重构。

窄依赖的依赖关系代价较小,宽依赖则代缴较大,存在冗余计算。

Checkpoint机制:对于Lineage机制如果Lineage过长或者是存在宽依赖那么使用重算则需要的代价过大,

Checkpoint机制本质就是讲Lineage中的某个RDD写入磁盘作为检查点,后续的子RDD数据丢失则可以直接在检查点开始计算,一般把宽依赖上做Checkpoint最为合适。

8.请描述spark广播变量原理与特点。

1. 广播变量满足三个特点:

  1.不变,广播变量是不可变的。

  2. 够小,因为是放到executor的内存中的,所以不能太大。

  3. 放在executor内存中,在之上的task都可访问。

2. 原理:

首先在driver中生产广播变量,然后在应用的所有的executor都会复制这个广播变量,在这个executor之上的所有task就会公用这个变量。

如果不用广播变量那么所有的task就会和RDD(没有用广播变量前)进行交互,产生较大的网络和磁盘IO。

9.请描述spark yarn-client与yarn-cluster模式原理,并分析其特点。

yarn-client与yarn-cluster的的说法只会当spark on yarn的模式下。

主要区别在于driver(SparkContext)运行在nodemanager的AM上还是运行在本地(如提交任务的机器上)。

另外谁启动driver则谁负责调度。换句话说yarn-client的RM在申请资源启动Executor后并不负责后续的task的调度。

当本地并不需要进行交互计算或者查询的时候建议使用yarn-cluster模式。

10.请描述spark算子reduce与reduceByKey的区别。

reduce(function):数组中前两个元素做function操作后的值在和第三个元素值做function操作,以此类推。

val c = sc.parallelize(1 to 10)

c.reduce((x, y) => x + y)//结果55

解释为:

1+2 = 3

3+3=6

6+4=10

10+5=15

15+6=21

21+7=28

28+8=36

36+9=45

45+10=55

        

reduceByKey(function):是对元素为KV对的RDD中Key相同的元素的Value进行binary_function的reduce操作,

因此,Key相同的多个元素的值被reduce为一个值,然后与原RDD中的Key组成一个新的KV对。

如:

val a = sc.parallelize(List((1,2),(1,3),(1,1),(3,4),(3,6),(3,5)))

a.reduceByKey((x,y) => x + y).collect

解释为:

  key 为 1 的value相加:2+3+1 = 6  形成 (1,6)

  key为 3的value相加:4+6+5 = 15 形成(3,15)

11.spark中任务调度的调度模式有几种,分别描述实现原理

Spark中总体的任务调度如下图:

spark目前支持两种调度策略:

  SchedulingMode.FIFO 先入先出调度策略和 SchedulingMode.FAIR 公平调度策略 ,他们都是application级别的策略。

  1. SchedulingMode.FIFO :保证jobid较小的先调度,如果是同一个job,那么stage的id小的先调度。 

   

private[spark] class FIFOSchedulingAlgorithm extends SchedulingAlgorithm {
override def comparator(s1: Schedulable, s2: Schedulable): Boolean = {
val priority1 = s1.priority
val priority2 = s2.priority
var res = math.signum(priority1 - priority2)
if (res == 0) {
val stageId1 = s1.stageId
val stageId2 = s2.stageId
res = math.signum(stageId1 - stageId2)
}
res < 0
}
}

  2. SchedulingMode.FAIR 公平调度策略 :rootpool下挂在的是一组pool,叶子节点是tasksetmanager,首先是确定rootpool的子pool的调度顺序,然后在子pool内部使用相同的

算法确定调度顺序。

  

private[spark] class FairSchedulingAlgorithm extends SchedulingAlgorithm {
override def comparator(s1: Schedulable, s2: Schedulable): Boolean = {
val minShare1 = s1.minShare
val minShare2 = s2.minShare
val runningTasks1 = s1.runningTasks
val runningTasks2 = s2.runningTasks
val s1Needy = runningTasks1 < minShare1
val s2Needy = runningTasks2 < minShare2
val minShareRatio1 = runningTasks1.toDouble / math.max(minShare1, 1.0)
val minShareRatio2 = runningTasks2.toDouble / math.max(minShare2, 1.0)
val taskToWeightRatio1 = runningTasks1.toDouble / s1.weight.toDouble
val taskToWeightRatio2 = runningTasks2.toDouble / s2.weight.toDouble var compare = 0
if (s1Needy && !s2Needy) {
return true
} else if (!s1Needy && s2Needy) {
return false
} else if (s1Needy && s2Needy) {
compare = minShareRatio1.compareTo(minShareRatio2)
} else {
compare = taskToWeightRatio1.compareTo(taskToWeightRatio2)
}
if (compare < 0) {
true
} else if (compare > 0) {
false
} else {
s1.name < s2.name
}
}
}

  

12.spark on yarn模式下,spark executor oom时候,请列举哪些可以解决或者调优,请具体描述。

1. 减少数据膨胀:

  a. 使用数组和基本类型来减少数据膨胀。

  b. 避免过多的小对象的嵌套

  c. 如果RAM 小于32 GB则可以在spark-env.sh中设置-XX:+UseCompressedOops参数,来将指针地址长度从8位变为4位。

2. 保持executor上的task的数据本地性。

  当数据非本地的时候将会远程从其他executor上加载数据到内存,当数据过大可能引起oom,我们可以调大spark.locality.wait

3.防止过大的partation。

  可以使用repartition对RDD重新分区。

4.GC调优

  使用G1 回收策略等

5. 使用spark.rdd.compress 指定为KryoSerializer

  可以进一步压缩在内存中的数据,并且比java自带的要更加高效。

6.适当的调整spark.memory.storageFraction

  避免过多的借还。

13.请分析以下异常发生原因,并概述spark监听器机制。

Dropping SparkListenerEvent because no remaining room in event queue. This likely means one of the SparkListeners is too slow and cannot keep up with the rate at which tasks are being started by the scheduler.

原因:

val eventAdded = eventQueue.offer(event)
if (eventAdded) {
eventLock.release()
} else {
onDropEvent(event)
droppedEventsCounter.incrementAndGet()
}
上述当发生队列容量不足的时候将会发生drop事件从而出现此日志信息。

14.举例分析spark数据倾斜现象,原因和解决方法。

15.spark streaming中Dstream是如何产生,请描述过程。

16.spark streaming与kafka集成应用时,从kafka读取数据的几种获取方式,并各有什么不同。

17.请描述spark thriftServer增量(配置参数spark.sql.thriftServer.incrementalCollect)取数机制。

18.以“select count(*) from table”语句为例子,描述spark task产生过程。

19.请说明spark-sql产生小文件的原因,请描述其调优解决方法。

20.请举例spark常用优化参数,请阐述其意义和应用场景。

spark技术总结(1)的更多相关文章

  1. Spark技术内幕:Stage划分及提交源码分析

    http://blog.csdn.net/anzhsoft/article/details/39859463 当触发一个RDD的action后,以count为例,调用关系如下: org.apache. ...

  2. 成都大数据Hadoop与Spark技术培训班

    成都大数据Hadoop与Spark技术培训班   中国信息化培训中心特推出了大数据技术架构及应用实战课程培训班,通过专业的大数据Hadoop与Spark技术架构体系与业界真实案例来全面提升大数据工程师 ...

  3. Spark技术内幕: Task向Executor提交的源码解析

    在上文<Spark技术内幕:Stage划分及提交源码分析>中,我们分析了Stage的生成和提交.但是Stage的提交,只是DAGScheduler完成了对DAG的划分,生成了一个计算拓扑, ...

  4. Spark技术内幕:Master的故障恢复

    Spark技术内幕:Master基于ZooKeeper的High Availability(HA)源码实现  详细阐述了使用ZK实现的Master的HA,那么Master是如何快速故障恢复的呢? 处于 ...

  5. Apache Spark技术实战之6 --Standalone部署模式下的临时文件清理

    问题导读 1.在Standalone部署模式下,Spark运行过程中会创建哪些临时性目录及文件? 2.在Standalone部署模式下分为几种模式? 3.在client模式和cluster模式下有什么 ...

  6. 网易的Spark技术实践

    http://www.infoq.com/cn/news/2014/04/netease-spark-practice?utm_source=infoq&utm_medium=popular_ ...

  7. Spark技术内幕: Task向Executor提交的源代码解析

    在上文<Spark技术内幕:Stage划分及提交源代码分析>中,我们分析了Stage的生成和提交.可是Stage的提交,仅仅是DAGScheduler完毕了对DAG的划分,生成了一个计算拓 ...

  8. 网易大数据平台的Spark技术实践

    网易大数据平台的Spark技术实践 作者 王健宗 网易的实时计算需求 对于大多数的大数据而言,实时性是其所应具备的重要属性,信息的到达和获取应满足实时性的要求,而信息的价值需在其到达那刻展现才能利益最 ...

  9. Spark技术学院-进去能学到啥?

    Spark技术学院是什么? 主要是浪尖,前腾讯现阿里的大神一起搞的知识分享基地,旨在帮助大家由入门到精通spark,hbase,kafka大数据重要的框架,还有给入门小白指点入门方法,分享入门资料,对 ...

  10. Apache Spark技术实战之7 -- CassandraRDD高并发数据读取实现剖析

    未经本人同意,严禁转载,徽沪一郎. 概要 本文就 spark-cassandra-connector 的一些实现细节进行探讨,主要集中于如何快速将大量的数据从cassandra 中读取到本地内存或磁盘 ...

随机推荐

  1. 【转】arm-none-linux-gnueabi-gcc下载

    arm-none-linux-gnueabi-gcc是 Codesourcery 公司(目前已经被Mentor收购)基于GCC推出的的ARM交叉编译工具.可用于交叉编译ARM系统中所有环节的代码,包括 ...

  2. 【ARC069F】Flags

    Description 数轴上有 \(n\)个旗子,第\(i\)个可以插在坐标\(x_i\)或者\(y_i\). ​ 请最大化两两旗子之间的最小距离. ​ \(2 \le n \le 10^4\),\ ...

  3. UOJ #126 【NOI2013】 快餐店

    题目链接:快餐店 震惊!某ZZ选手此题调了一天竟是因为……>>点击查看 一般碰到这种基环树的题都要先想想树上怎么做.这道题如果是在树上的话……好像求一遍直径就做完了?答案就是直径长度的一半 ...

  4. 解题:洛谷4178 Tree

    题面 重(新)学点分治中...... 普通的点分治一般这几步: 1.找重心 2.从重心开始DFS,得到信息 3.统计经过重心的路径 4.分别分治几棵子树,继续这个过程 然后是常见的(制杖的我的)一些疑 ...

  5. lumen passport Call to undefined method Laravel\Lumen\Application::group()

    解决方法:https://github.com/dusterio/lumen-passport/issues/69 public function boot() { LumenPassport::ro ...

  6. config配置中心之自动刷新

    自动刷新(自动刷新是基于springcloudbus来实现的,springcloud bus是基于rabbitMQ或者Kafka来实现的) Spring Cloud Bus 将分布式的节点用轻量的消息 ...

  7. Java入门:Java中获取键盘输入值的三种方法

    Java程序开发过程中,需要从键盘获取输入值是常有的事,但Java它偏偏就没有像c语言给我们提供的scanf(),C++给我们提供的cin()获取键盘输入值的现成函数!Java没有提供这样的函数也不代 ...

  8. Python之socket(套接字)补充

    IO多路复用 I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. Linux Linux中的 select,poll,e ...

  9. 浅谈 vue实例 和 vue组件

    vue实例: import Vue from 'vue'; import app from './app'; import myRouter from './routers'; new Vue({ e ...

  10. logstash定义表达式

    例如: echo '[2018/02/02 08:34:43.032]' >> tomcat_catalina.out 过滤方式 "message" => &qu ...