zoukankan      html  css  js  c++  java
  • hadoop和spark比较

    http://blog.51cto.com/13943588/2165946

    3、hadoop和spark的都是并行计算,那么他们有什么相同和区别? 

    两者都是用mr模型来进行并行计算,hadoop的一个作业称为job,job里面分为map task和reduce task,每个task都是在自己的进程中运行的,当task结束时,进程也会结束。 

    spark用户提交的任务成为application,一个application对应一个sparkcontext,app中存在多个job,每触发一次action操作就会产生一个job。 

    这些job可以并行或串行执行,每个job中有多个stage,stage是shuffle过程中DAGSchaduler通过RDD之间的依赖关系划分job而来的,每个stage里面有多个task,组成taskset有TaskSchaduler分发到各个executor中执行,executor的生命周期是和app一样的,即使没有job运行也是存在的,所以task可以快速启动读取内存进行计算。 

    hadoop的job只有map和reduce操作,表达能力比较欠缺而且在mr过程中会重复的读写hdfs,造成大量的io操作,多个job需要自己管理关系。 

    spark的迭代计算都是在内存中进行的,API中提供了大量的RDD操作如join,groupby等,而且通过DAG图可以实现良好的容错。

    4、hadoop的TextInputFormat作用是什么,如何自定义实现

    InputFormat会在map操作之前对数据进行两方面的预处理 

    1是getSplits,返回的是InputSplit数组,对数据进行split分片,每片交给map操作一次 

    2是getRecordReader,返回的是RecordReader对象,对每个split分片进行转换为key-value键值对格式传递给map

    常用的InputFormat是TextInputFormat,使用的是LineRecordReader对每个分片进行键值对的转换,以行偏移量作为键,行内容作为值

    自定义类继承InputFormat接口,重写createRecordReader和isSplitable方法 

    在createRecordReader中可以自定义分隔符

    5、Spark  RDD宽依赖和窄依赖?

    RDD和它依赖的parent RDD(s)的关系有两种不同的类型,即窄依赖(narrow dependency)和宽依赖(wide dependency)。

    1)窄依赖指的是每一个parent RDD的Partition最多被子RDD的一个Partition使用

    2)宽依赖指的是多个子RDD的Partition会依赖同一个parent RDD的Partition

    6、spark cache和pesist的区别 

    1)cache和persist都是用于将一个RDD进行缓存的,这样在之后使用的过程中就不需要重新计算了,可以大大节省程序运行时间;

    2) cache只有一个默认的缓存级别MEMORY_ONLY ,cache调用了persist,而persist可以根据情况设置其它的缓存级别;

    3)executor执行的时候,默认60%做cache,40%做task操作,persist最根本的函数,最底层的函数

    可以看到缓存级别类StorageLevel类的主构造器包含了5个参数:

    useDisk:使用硬盘(外存)
    useMemory:使用内存
    useOffHeap:使用堆外内存,这是Java虚拟机里面的概念,堆外内存意味着把内存对象分配在Java虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是虚拟机)。这样做的结果就是能保持一个较小的堆,以减少垃圾收集对应用的影响。
    deserialized:反序列化,其逆过程序列化(Serialization)是java提供的一种机制,将对象表示成一连串的字节;而反序列化就表示将字节恢复为对象的过程。序列化是对象永久化的一种机制,可以将对象及其属性保存起来,并能在反序列化后直接恢复这个对象
    replication:备份数(在多个节点上备份)
    val MEMORY_AND_DISK_SER_2 = new StorageLevel(true, true, false, false, 2) 就表示使用这种缓存级别的RDD将存储在硬盘以及内存中,使用序列化(在硬盘中),并且在多个节点上备份2份(正常的RDD只有一份)

    7、常规的容错方式有哪几种类型?RDD通过Linage(记录数据更新)的方式为何很高效?

    1).数据检查点,会发生拷贝,浪费资源

    2).记录数据的更新,每次更新都会记录下来,比较复杂且比较消耗性能

    ——————

    1)    ​lazy记录了数据的来源,RDD是不可变的,且是lazy级别的,且rDD之间构成了链条,lazy是弹性的基石。由于RDD不可变,所以每次操作就产生新的rdd,不存在全局修改的问题,控制难度下降,所有有计算链条将复杂计算链条存储下来,计算的时候从后往前回溯900步是上一个stage的结束,要么就checkpoint

    2)    ​记录原数据,是每次修改都记录,代价很大如果修改一个集合,代价就很小,官方说rdd是粗粒度的操作,是为了效率,为了简化,每次都是操作数据集合,写或者修改操作,都是基于集合的rdd的写操作是粗粒度的,rdd的读操作既可以是粗粒度的也可以是细粒度,读可以读其中的一条条的记录。

    3)    ​简化复杂度,是高效率的一方面,写的粗粒度限制了使用场景如网络爬虫,现实世界中,大多数写是粗粒度的场景

    8、RDD有哪些缺陷?

    1)不支持细粒度的写和更新操作(如网络爬虫),spark写数据是粗粒度的所谓粗粒度,就是批量写入数据,为了提高效率。但是读数据是细粒度的也就是说可以一条条的读

    2)不支持增量迭代计算,Flink支持

    9、Spark中数据的位置是被谁管理的?

    每个数据分片都对应具体物理位置,数据的位置是被blockManager,无论数据是在磁盘,内存还是tacyan,都是由blockManager管理

    10、Spark的数据本地性有哪几种?

    答:Spark中的数据本地性有三种:a.PROCESS_LOCAL是指读取缓存在本地节点的数据b.NODE_LOCAL是指读取本地节点硬盘数据c.ANY是指读取非本地节点数据通常读取数据PROCESS_LOCAL>NODE_LOCAL>ANY,尽量使数据以PROCESS_LOCAL或NODE_LOCAL方式读取。其中PROCESS_LOCAL还和cache有关,如果RDD经常用的话将该RDD cache到内存中,注意,由于cache是lazy的,所以必须通过一个action的触发,才能真正的将该RDD cache到内存中

    11、rdd有几种操作类型?

    1)transformation,rdd由一种转为另一种rdd

    2)action,

    3)cronroller,crontroller是控制算子,cache,persist,对性能和效率的有很好的支持三种类型,不要回答只有2中操作

    12、Spark程序执行,有时候默认为什么会产生很多task,怎么修改默认task执行个数?

    1)因为输入数据有很多task,尤其是有很多小文件的时候,有多少个输入block就会有多少个task启动;

    2)spark中有partition的概念,每个partition都会对应一个task,task越多,在处理大规模数据的时候,就会越有效率。不过task并不是越多越好,如果平时测试,或者数据量没有那么大,则没有必要task数量太多。

    3)参数可以通过spark_home/conf/spark-default.conf配置文件设置:spark.sql.shuffle.partitions 50 spark.default.parallelism 10第一个是针对spark sql的task数量第二个是非spark sql程序设置生效

    13、为什么Spark Application在没有获得足够的资源,job就开始执行了,可能会导致什么什么问题发生?

    答:会导致执行该job时候集群资源不足,导致执行job结束也没有分配足够的资源,分配了部分Executor,该job就开始执行task,应该是task的调度线程和Executor资源申请是异步的;如果想等待申请完所有的资源再执行job的:需要将spark.scheduler.maxRegisteredResourcesWaitingTime设置的很大;spark.scheduler.minRegisteredResourcesRatio 设置为1,但是应该结合实际考虑否则很容易出现长时间分配不到资源,job一直不能运行的情况。

    14、join操作优化经验?

    join其实常见的就分为两类: map-side join 和  reduce-side join。当大表和小表join时,用map-side join能显著提高效率。将多份数据进行关联是数据处理过程中非常普遍的用法,不过在分布式计算系统中,这个问题往往会变的非常麻烦,因为框架提供的 join 操作一般会将所有数据根据 key 发送到所有的 reduce 分区中去,也就是 shuffle 的过程。造成大量的网络以及磁盘IO消耗,运行效率极其低下,这个过程一般被称为 reduce-side-join。如果其中有张表较小的话,我们则可以自己实现在 map 端实现数据关联,跳过大量数据进行 shuffle 的过程,运行时间得到大量缩短,根据不同数据可能会有几倍到数十倍的性能提升。

    15、介绍一下cogroup rdd实现原理,你在什么场景下用过这个rdd?

    答:cogroup的函数实现:这个实现根据两个要进行合并的两个RDD操作,生成一个CoGroupedRDD的实例,这个RDD的返回结果是把相同的key中两个RDD分别进行合并操作,最后返回的RDD的value是一个Pair的实例,这个实例包含两个Iterable的值,第一个值表示的是RDD1中相同KEY的值,第二个值表示的是RDD2中相同key的值.由于做cogroup的操作,需要通过partitioner进行重新分区的操作,因此,执行这个流程时,需要执行一次shuffle的操作(如果要进行合并的两个RDD的都已经是shuffle后的rdd,同时他们对应的partitioner相同时,就不需要执行shuffle

    RDD的弹性表现在哪几点?

    1)自动的进行内存和磁盘的存储切换;

    2)基于Lingage的高效容错;

    3)task如果失败会自动进行特定次数的重试;

    4)stage如果失败会自动进行特定次数的重试,而且只会计算失败的分片;

    5)checkpoint和persist,数据计算之后持久化缓存

    6)数据调度弹性,DAG TASK调度和资源无关

    7)数据分片的高度弹性,a.分片很多碎片可以合并成大的,b.par

    常规的容错方式有哪几种类型?

    1)checkPoint ,会发生拷贝,浪费资源

    2).记录数据的更新,每次更新都会记录下来,比较复杂且比较消耗性能

    RDD通过Linage(记录数据更新)的方式为何很高效?

    1)    ​lazy记录了数据的来源,RDD是不可变的,且是lazy级别的,且RDD之间构成了链条,lazy是弹性的基石。由于RDD不可变,所以每次操作就产生新的rdd,不存在全局修改的问题,控制难度下降,所有有计算链条将复杂计算链条存储下来,计算的时候从后往前回溯900步是上一个stage的结束,要么就checkpoint

    2)    ​记录原数据,是每次修改都记录,代价很大如果修改一个集合,代价就很小,官方说rdd是粗粒度的操作,是为了效率,为了简化,每次都是操作数据集合,写或者修改操作,都是基于集合的rdd的写操作是粗粒度的,rdd的读操作既可以是粗粒度的也可以是细粒度,读可以读其中的一条条的记录。

    3)    ​简化复杂度,是高效率的一方面,写的粗粒度限制了使用场景如网络爬虫,现实世界中,大多数写是粗粒度的场景

     Spark有哪些聚合类的算子,我们应该尽量避免什么类型的算子?

    答:在我们的开发过程中,能避免则尽可能避免使用reduceByKey、join、distinct、repartition等会进行shuffle的算子,尽量使用map类的非shuffle算子。这样的话,没有shuffle操作或者仅有较少shuffle操作的Spark作业,可以大大减少性能开销。

    Spark的shuffle过程?

    答:从下面三点去展开

    1)shuffle过程的划分

    2)shuffle的中间结果如何存储

    3)shuffle的数据如何拉取过来

    http://www.cnblogs.com/jxhd1/p/6528540.html
    RDD创建有哪几种方式?

    1).使用程序中的集合创建rdd

    2).使用本地文件系统创建rdd

    3).使用hdfs创建rdd,

    4).基于数据库db创建rdd

    5).基于Nosql创建rdd,如hbase

    6).基于s3创建rdd,

    7).基于数据流,如socket创建rdd

    如果只回答了前面三种,是不够的,只能说明你的水平还是入门级的,实践过程中有很多种创建方式。

    Spark并行度怎么设置比较合适

    答:spark并行度,每个core承载 2~4 个partition,如,32个core,那么64~128之间的并行度,也就是

    设置 64~128 个partion,并行读和数据规模无关,只和内存使用量和cpu使用

    时间有关

    Spark的数据本地性有哪几种?

    答:Spark中的数据本地性有三种:

    a.PROCESS_LOCAL 是指读取缓存在本地节点的数据

    b.NODE_LOCAL 是指读取本地节点硬盘数据

    c.ANY 是指读取非本地节点数据

    通常读取数据PROCESS_LOCAL>NODE_LOCAL>ANY,尽量使数据以PROCESS_LOCAL或NODE_LOCAL方式读取。其中PROCESS_LOCAL还和cache有关,如果RDD经常用的话将该RDD cache到内存中,注意,由于cache是lazy的,所以必须通过一个action的触发,才能真正的将该RDD cache到内存中。

    rdd有几种操作类型?

    1)transformation,rdd由一种转为另一种rdd

    2)action,

    3)cronroller,crontroller是控制算子,cache,persist,对性能和效率的有很好的支持

    三种类型,不要回答只有2中操作

    Spark如何处理不能被序列化的对象?

    将不能序列化的内容封装成object

    collect功能是什么,其底层是怎么实现的?

    答:driver通过collect把集群中各个节点的内容收集过来汇总成结果,collect返回结果是Array类型的,collect把各个节点上的数据抓过来,抓过来数据是Array型,collect对Array抓过来的结果进行合并,合并后Array中只有一个元素,是tuple类型(KV类型的)的。

    Spaek程序执行,有时候默认为什么会产生很多task,怎么修改默认task执行个数?

    答:1)因为输入数据有很多task,尤其是有很多小文件的时候,有多少个输入

    block就会有多少个task启动;2)spark中有partition的概念,每个partition都会对应一个task,task越多,在处理大规模数据的时候,就会越有效率。不过task并不是越多越好,如果平时测试,或者数据量没有那么大,则没有必要task数量太多。3)参数可以通过spark_home/conf/spark-default.conf配置文件设置:

    spark.sql.shuffle.partitions 50 spark.default.parallelism 10

    第一个是针对spark sql的task数量

    第二个是非spark sql程序设置生效

    为什么Spark Application在没有获得足够的资源,job就开始执行了,可能会导致什么什么问题发生?

    答:会导致执行该job时候集群资源不足,导致执行job结束也没有分配足够的资源,分配了部分Executor,该job就开始执行task,应该是task的调度线程和Executor资源申请是异步的;如果想等待申请完所有的资源再执行job的:需要将spark.scheduler.maxRegisteredResourcesWaitingTime设置的很大;spark.scheduler.minRegisteredResourcesRatio 设置为1,但是应该结合实际考虑

    否则很容易出现长时间分配不到资源,job一直不能运行的情况。

    Spark为什么要持久化,一般什么场景下要进行persist操作?

    为什么要进行持久化?

    spark所有复杂一点的算法都会有persist身影,spark默认数据放在内存,spark很多内容都是放在内存的,非常适合高速迭代,1000个步骤

    只有第一个输入数据,中间不产生临时数据,但分布式系统风险很高,所以容易出错,就要容错,rdd出错或者分片可以根据血统算出来,如果没有对父rdd进行persist 或者cache的化,就需要重头做。

    以下场景会使用persist

    1)某个步骤计算非常耗时,需要进行persist持久化

    2)计算链条非常长,重新恢复要算很多步骤,很好使,persist

    3)checkpoint所在的rdd要持久化persist,

    lazy级别,框架发现有checnkpoint,checkpoint时单独触发一个job,需要重算一遍,checkpoint前

    要持久化,写个rdd.cache或者rdd.persist,将结果保存起来,再写checkpoint操作,这样执行起来会非常快,不需要重新计算rdd链条了。checkpoint之前一定会进行persist。

    4)shuffle之后为什么要persist,shuffle要进性网络传输,风险很大,数据丢失重来,恢复代价很大

    5)shuffle之前进行persist,框架默认将数据持久化到磁盘,这个是框架自动做的。

    为什么要进行序列化

    序列化可以减少数据的体积,减少存储空间,高效存储和传输数据,不好的是使用的时候要反序列化,非常消耗CPU

    介绍一下join操作优化经验?

    答:join其实常见的就分为两类: map-side join 和 reduce-side join。当大表和小表join时,用map-side join能显著提高效率。将多份数据进行关联是数据处理过程中非常普遍的用法,不过在分布式计算系统中,这个问题往往会变的非常麻烦,因为框架提供的 join 操作一般会将所有数据根据 key 发送到所有的 reduce 分区中去,也就是 shuffle 的过程。造成大量的网络以及磁盘IO消耗,运行效率极其低下,这个过程一般被称为 reduce-side-join。如果其中有张表较小的话,我们则可以自己实现在 map 端实现数据关联,跳过大量数据进行 shuffle 的过程,运行时间得到大量缩短,根据不同数据可能会有几倍到数十倍的性能提升。

    备注:这个题目面试中非常非常大概率见到,务必搜索相关资料掌握,这里抛砖引玉。

    介绍一下cogroup rdd实现原理,你在什么场景下用过这个rdd?

    答:cogroup的函数实现:这个实现根据两个要进行合并的两个RDD操作,生成一个CoGroupedRDD的实例,这个RDD的返回结果是把相同的key中两个RDD分别进行合并操作,最后返回的RDD的value是一个Pair的实例,这个实例包含两个Iterable的值,第一个值表示的是RDD1中相同KEY的值,第二个值表示的是RDD2中相同key的值.由于做cogroup的操作,需要通过partitioner进行重新分区的操作,因此,执行这个流程时,需要执行一次shuffle的操作(如果要进行合并的两个RDD的都已经是shuffle后的rdd,同时他们对应的partitioner相同时,就不需要执行shuffle,),

    场景:表关联查询









    kafka工作原理? 

    producer向broker发送事件,consumer从broker消费事件。 

    事件由topic区分开,每个consumer都会属于一个group。 

    相同group中的consumer不能重复消费事件,而同一事件将会发送给每个不同group的consumer。

  • 相关阅读:
    面试题23:从上往下打印二叉树
    面试题22:栈的压入、弹出序列
    【opencv基础】imwrite函数与图像存储质量
    【c++基础】从json文件提取数据
    【图像处理基础】LBP特征
    【机器学习基础】SVM实现分类识别及参数调优(二)
    【leetcode】14-LongestCommonPrefix
    【leetcode】13-Roman2Integer
    【leetcode】9-PalindromeNumber
    【leetcode】7-ReverseInteger
  • 原文地址:https://www.cnblogs.com/wangleBlogs/p/9930061.html
Copyright © 2011-2022 走看看