数据仓库知识整理(三)

1.背景

      归纳整理数据仓库的基础知识,了解数据仓库的全貌和可深入学习的部分,本章节会主要梳理Hadoop&Hive&Spark的基础与部分面试题,末尾链接会梳理离线/实时数仓部分技术能力(持续更新,如果我坚持下去了的话,哈哈哈)。其中部分话术来源于网络,会在统一位置进行标注引用,感谢大家在网络上的分享!

2.数据仓库知识整理

2.1 文章引用

      https://www.cnblogs.com/jnba/p/10550394.html

      https://blog.csdn.net/wshyb0314/article/details/81475475

      https://blog.csdn.net/wx1528159409/article/details/86612211

      Hadoop权威指南(第四版)

      https://blog.csdn.net/weixin_38073885/article/details/85622775

      https://blog.csdn.net/wx1528159409/article/details/86612211

      https://blog.51cto.com/zengzhaozheng/1438204

      https://blog.csdn.net/etudyzmimi/article/details/105733565

      https://www.cnblogs.com/ggzhangxiaochao/p/9510018.html

      https://www.jianshu.com/p/b0b77b045fab

      https://www.cnblogs.com/yaojingang/p/5446310.html

      https://blog.csdn.net/oopsoom/article/details/34104115

      http://blog.sina.com.cn/s/blog_9f48885501017dua.html

      https://www.aboutyun.com//forum.php/?mod=viewthread&tid=20461

2.2 Hadoop

      1.HDFS读写文件流程

      1) 写文件流程

      a.客户端创建Distributed FileSystem实例对象,Distributed FileSystem通过RPC远程过程调用向NameNode发送上传文件的请求,NameNode会检查目标文件与文件父目录是否已经存在,并在系统命名空间新建一个文件(此时该文件中还没有数据块)
      b.NameNode响应可上传则会由Distributed FileSystem向客户端返回一个FSDataOutputStream对象(封装了DFSoutPutStream对象,该对象负责DataNode与NameNode之间的通信),否则向客户端返回一个IOException(NameNode检查通过且拥有创建文件的权限则创建目标文件)
      c.客户端对文件进行分块(默认每一个block块128M),而后请求上传第一个Block块
      d.NameNode会返回可处理数据的DataNode节点列表
      e.DFSoutPutStream会将数据写入数据队列,向第一个DataNode节点请求上传数据,除上传数据外还将NameNode分配的DataNode节点列表一同发送给DataNode1,DataNode1收到请求会继续调用DataNode2,然后DataNode2调用DataNode3,构成pipeline通信管道,并将第一个Block块的数据以Packet为单位传输
      f.DFSoutPutStream维护着内部数据包队列,即确认队列,在传递过程中每一个packet会存入该应答队列,等待所有DataNode确认信息后会在队列中删除

      2) 读文件流程

      a.客户端创建Distributed FileSystem实例对象,Distributed FileSystem通过RPC远程过程调用向NameNode发送下载文件的请求,NameNode会确认文件起始块的位置
      b.NameNode响应可上传则会由Distributed FileSystem向客户端返回一个FSDataInputStream对象(封装了DFSInputStream对象,该对象负责DataNode与NameNode之间的通信)
      c.DFSInputStream会挑选一台最近的DataNode(就近原则,然后随机)服务器,请求读取数据
      d.DataNode开始传输数据给客户端
      e.客户端以packet为单位接收,先在本地缓存,然后写入目标文件

      2.YARN核心角色及运行机制

      1) ResourceManager

           ResourceManager是一个管理整个集群上资源使用的资源管理器。其基本职能包括:

                  与客户端进行交互,处理客户端请求;

                  启动与管理ApplicationMaster,并为其申请Container;

                  管理NodeManager,向NodeManager下达管理资源的命令并接收来自NodeManager的资源与节点健康情况汇报;

                  接收ApplicationMaster的资源申请并一次分配资源,及资源管理和调度

      2) ApplicationMaster

           应用程序级别的管理器,管理运行在YARN上的应用程序。其基本职能包括:

                  用户提交的每一个应用程序上均存在一个ApplicationMaster

                  向ResourceManager申请资源,并进行二次资源分配

                 与NameNode通信以启动/停止任务,并监控任务运行状态,在任务失败时重新为其申请启动资源

      3) NodeManager

           YARN中运行在集群上所有节点上且能够启动和监控容器的节点管理器。其基本职能包括:

                 启动与监控计算容器Container,并以心跳的方式向ResourceManager汇报节点资源使用情况与运行状态信息

                 接收并处理来自ApplicationMaster的针对计算容器Container的启动/停止等各种请求

      4) Container

           Container是YARN中执行特定应用程序的进程,它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等。Container是ApplicationMaster向ResourceManager申请的,由ResourceManager中的资源调度器异步分配给ApplicationMaster。Container的运行是由ApplicationMaster向资源所在的NodeManager发起。其基本职能包括:

                 运行ApplicationMaster的Container:这是由ResourceManager(向内部的资源调度器)申请和启动的,用户提交应用程序时,可指定唯一的ApplicationMaster所需的资源;
                 运行各类任务的Container:这是由ApplicationMaster向ResourceManager申请的,并由ApplicationMaster与NodeManager通信以启动。

      5) 运行机制

            1.客户端向ResourceManager提交运行一个ApplicationMaster的请求
            2.ResourceManager会找到一个能在container中运行ApplicationMaster的NodeManager
            3.ApplicationMaster向ResourceManager发送请求,申请相应数目的container
            4.ResourceManager返回ApplicationMaster的申请的containers信息。申请成功的container,由ApplicationMaster进行初始化。container的启动信息初始化后,ApplicationMaster与对应的NodeManager通信,要求NodeManager启动container。ApplicationMaster与NM保持心跳,从而对NodeManager上运行的任务进行监控和管理

      3.YARN调度器:默认调度器是容量调度器

      A.FIFO Scheduler(先进先出调度器)

           提交的应用按照提交顺序形成一个队列,是一个先进先出的队列,无论资源占用是否合理适用,均会在队列中卡顿等待。

      B.Capacity Scheduler(容量调度器) 

           多队列执行,但是每个队列内部是先进先出,也就是说同一时间队列中还是只有一个任务在执行。队列的并行度为队列的个数。

      C.Fair Scheduler(公平调度器)

           公平调度器的设计目标是为所有的应用分配公平的资源,公平调度器会为所有运行的任务动态的调整系统资源。公平调度器,就是能够共享整个集群的资源,不用预先占用资源,每一个作业都是共享的并且每个任务都有机会获取资源

      D.Fair Scheduler与Capacity Scheduler区别

            a.容量调度器通过百分比来划分集群的资源;公平调度器通过设定具体使用资源值(CPU、memory)来限定
            b.当大job在执行时,又提交一个小job,容量调度器会等大job执行完毕,才执行小job,就是按照FIFO方式来运行;公平调度器会尽快腾出“空间”给小job运行(可以通过标签来指定每个队列的调度策略(FAIR、FIFO、DRF))
            c.公平调度器支持抢占机制,容量调度器不支持

      4.mapreduce的原理及过程(图片:https://www.jianshu.com/p/ca165beb305b

           

            1).JobClient将编写好的MR程序提交job到JobTracker上,JobTracker会检查输入输出目录是否存在
            2).JobTracker根据输入计算输入分片,并初始化,即将Job放在一个队列中,让配置好的作业调度器能够调度,每一个分片一个MAP任务
            3).TaskTracker会运行一个循环机制定期发送心跳给JobTracker,也就是TaskTracker与JobTracker的沟通,前者获取操作后者发送命令
            4).接收到最后一个命令后,TaskTracker将Reduce结果写入到HDFS当中

            1) split:在进行map计算前,MR会根据输入文件计算分片split,每个分片split由一个map任务处理
            2) map:map计算完成后会由内存写入一个环形缓冲区,当该缓冲区快要溢出时会在本地文件系统创建溢写文件,并在写入磁盘前,会按照reduce任务的数据进行分区(对数据进行hash)
            4) combiner:combiner是一种可选择的操作,可以作为map的输出数据的初步reduce操作,以削减map的输出作为减少网络宽带和reduce侧的压力的优化操作
            5) shuffle:将map的输出作为reduce的数据过程就是shuffle,即map的结果会通过partitioner将数据分区后分发给reduce,一个partitioner对应一个reduce任务
            6) reduce:接收map的数据并进行后续计算

      5.hadoop的map数量和reduce数量

            https://hadoop.apache.org/docs/stable/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html#MapReduce_-_User_Interfaces

How Many Maps?
The number of maps is usually driven by the total size of the inputs, that is, the total number of blocks of the input files.
The right level of parallelism for maps seems to be around 10-100 maps per-node, although it has been set up to 300 maps for very cpu-light map tasks. Task setup takes a while, so it is best if the maps take at least a minute to execute.
Thus, if you expect 10TB of input data and have a blocksize of 128MB, you’ll end up with 82,000 maps, unless Configuration.set(MRJobConfig.NUM_MAPS, int) (which only provides a hint to the framework) is used to set it even higher.

How Many Reduces?
The right number of reduces seems to be 0.95 or 1.75 multiplied by (<no. of nodes> * <no. of maximum containers per node>).
With 0.95 all of the reduces can launch immediately and start transferring map outputs as the maps finish. With 1.75 the faster nodes will finish their first round of reduces and launch a second wave of reduces doing a much better job of load balancing.
Increasing the number of reduces increases the framework overhead, but increases load balancing and lowers the cost of failures.
The scaling factors above are slightly less than whole numbers to reserve a few reduce slots in the framework for speculative-tasks and failed tasks.

           由官方文档和网上释义可知,map的数量通常由输出的DFS块决定,比较合理的是每个map执行的时间至少超过1分钟。我们可以通过进行参数设置来改变map的数量,合理配置是最佳选择,而不是越靠近极值越好。reduce的数量应该是0.95或1.75×(节点数量×节点能够执行的最大任务数量),使用0.95作为因子时,所有reduce任务可以在map任务完成传输时同时开始运行。使用1.75作为因子时,告诉节点可以在完成第一批reduce任务时开始计算第二批reduce任务,有利于负载平衡。增加reduce数量实际上会增加开销,但是增加了负载平衡并降低了失败成本。

2.3 Hive

      1.Hive架构

            1)Client:用户可用的客户端接口,如使用Hive Cli执行shell调用使用Hive,使用程序语言调用JDBC访问Hive

            2)metaStore:元数据即描述数据的数据,如存储描述表位置,数据所在目录,所属数据库等基础信息,默认是存储在自带的Derby数据库中,推荐使用MySQL存储元数据

            3)Driver:

            (1)SQL Parser:SQL解析器,将SQL字符串转换成抽象语法树AST,这一步一般都用第三方工具库完成,比如antlr;对AST进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误。
            (2)Physical Plan:编译器,将AST编译生成逻辑执行计划。
            (3)Query Optimizer:优化器,对逻辑执行计划进行优化。
            (4)Execution:执行器,把逻辑执行计划转换成可以运行的物理计划。对于Hive来说,就是MR/Spark。

      2.Hive SQL解析过程

      https://www.aboutyun.com//forum.php/?mod=viewthread&tid=20461中写的很详细,对于如下的话术直接背诵真的不如理解,大致看一遍这篇文章哈

     又发现一篇宝藏:https://www.cnblogs.com/listenfwind/p/13657844.html(最近面试被问到RBO和CBO才发现了解的并不全面。。。给自己提个醒吧。。。)

            1.Antlr是一门解析语言,由其定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树(AST Tree)

            2.遍历抽象语法树(AST Tree),抽象出查询的基本组成单元QueryBlock(QueryBlock包括三个部分:输入源,计算过程,输出,可以将QueryBlock简单理解为一个子查询),即将SQL进一步抽象与结构化,方便转化为MapReduce

            3.遍历QueryBlock,翻译为执行操作树(Operator Tree,其基本操作符包括TableScanOperator,SelectOperator,FilterOperator,JoinOperator,GroupByOperator,ReduceSinkOperator)

            4.逻辑层优化器进行执行操作树(Operator Tree)变换,合并不必要的ReduceSinkOperator,减少shuffle数据量

            5.遍历OperatorTree,翻译为MapReduce任务

            6.物理层优化器进行MapReduce任务的变换,生成最终的执行计划

      3.Hive和Hbase的区别

           1)Hive使用Hadoop来分析处理数据,而Hadoop系统是批处理系统,因此不能保证处理的低迟延问题,即Hive常用作离线数据的处理;而HBase是近实时系统,支持实时查询。

           2) Hive中的表是纯逻辑表,就只是表的定义等,即表的元数据。Hive本身不存储数据,Hive的数据存储依赖HDFS。而HBase表是物理表,适合存放非结构化的数据。

           3) Hive是基于MapReduce来处理数据的,而MapReduce处理数据是基于行的模式;HBase处理数据是基于列的而不是基于行的模式,适合海量数据的随机访问。

           4) HBase的表是疏松的存储的,因此用户可以给行定义各种不同的列;而Hive表是稠密型,即定义多少列,每一行有存储固定列数的数据。

           5)Hive提供完整的SQL实现,通常被用来做一些基于历史数据的挖掘、分析。而HBase不适用与有join,多级索引,表关系复杂的应用场景。

           6) Hive不提供row-level的更新,它适用于大量append-only数据集(如日志)的批任务处理。而基于HBase的查询,支持和row-level的更新。

      4.Hive数据倾斜

      1) 数据倾斜

            由于数据分布不均匀,造成数据大量集中,即在shuffle阶段各个节点上相同的key都会被partition分配但同一个分区内(如聚合操作或JOIN操作),而某个key对应的数据量很大则就会产生数据倾斜。并会导致任务进度的长时间99%或少数reduce未完成

      2) 场景及解决办法

      a) 空值产生的数据倾斜:保证关联字段空值不参与关联,或通过赋值的方式避免空字段的影响。

      b) 不同数据类型产生的数据倾斜:通过cast方式将数据类型格式化

      c) 大小表关联产生的数据倾斜:使用map join的方式,在map阶段进行数据表的连接。map join会把小表读入内存中,在map阶段直接拿其他表与内存中的表做关联。可以通过hive.auto.convert.join = true设置允许启动map join,hive.mapjoin.smalltable.filesize = 25000000设置默认使用map join要处理的表大小。(默认值如前所示)

      d) group by产生的数据倾斜:通过hive.map.aggr = true设置允许在map端进行预聚合操作,相当于是Combiner,hive.groupby.skewindata = true会将正常group by产生的一个MR job变为两个。

      5.Hive CTE

           https://cwiki.apache.org/confluence/display/Hive/Common+Table+Expression

           CTE(Common Table Expression)共用表表示法,即使用with...as...能将某些查询结果作为中间查询结果存储在内存中,能够达成一次查询多次使用的效果,也能简化SQL代码(可以在递归操作同表操作时提高效率),增加代码可读性。但也会占用内存一定的资源作为代价。

      6.Hive 查询引擎

      1) MR:Hive的基本计算框架是mapreduce,即通过解析SQL并将其转换为mapreduce,又因为MR在数据读写过程中存在多次落盘操作,所以速度很慢。

      2) Tez:Tez绕开了mapreduce的限制,不需要进行落盘操作,并且将map任务与reduce任务拆分,形成可灵活组合的DAG任务。

      3) Spark:分布式内存计算框架,将数据计算的过程放在了内存中,减少了磁盘读写,且能够将多个操作合并计算,所以提升了速度。

      4) 在Hive中存在一些SQL操作是不需要引擎计算的,直接获取HDFS的数据信息,如全表扫描,抽样查询,比较(等值,不等值,大小),模糊比较: LIKE,空值判断,count(*) +where

<property>
    <name>hive.fetch.task.conversion</name>
    <value>more</value>
    <description>
      Expects one of [none, minimal, more].
      Some select queries can be converted to single FETCH task minimizing latency.
      Currently the query should be single sourced not having any subquery and should not have
      any aggregations or distincts (which incurs RS), lateral views and joins.
      0. none : disable hive.fetch.task.conversion
      1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only
      2. more    : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
    </description>
  </property>

      7.Hive的map数量和reduce数量

          map数量:map的数量应该由输入的文件数量与大小决定,无论是增大还是减小map数量,都要注意要让大数据量的数据使用适量的map数量(如新增);让每个单独的map任务处理足量的数据(如减少)。

          1)如果一个任务有很多小文件(远远小于块默认大小128MB,假设不进行块大小调整),则每个小文件都会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。此时我们就应该减少map数量。

-- 每个Map最大输入大小,决定合并后的文件数
set mapred.max.split.size=256000000;

-- 一个节点上split的至少的大小 ,决定了多个DataNode上的文件是否需要合并
set mapred.min.split.size.per.node=100000000;

-- 一个交换机下split的至少的大小,决定了多个交换机上的文件是否需要合并
set mapred.min.split.size.per.rack=100000000;

-- 执行Map前进行小文件合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 

          2)如果一个任务的大小为接近128MB,那么正常会使用一个map进行数据处理,但是如果这个文件的字段信息数量很大,在map端处理的逻辑较为复杂的情况下,也是非常耗时的。此时我们就应该增加map数量。

可以通过将文件进行拆分的方式增加map的数量。

          reduce数量:reduce的数量由map的输出文件大小决定,并且reduce的个数会影响任务执行效率,不指定reduce个数的前提下,hive会计算出一个reduce的个数。

          1)reduce个数调整方式

调整hive.exec.reducers.bytes.per.reducer参数的值
set hive.exec.reducers.bytes.per.reducer=500000000; (500M)
         
调整reduce个数
set mapred.reduce.tasks = 15;

          2)reduce的个数在进行全局操作的时候只有一个reduce,并且无法被增加,如笛卡尔积,order by,没有group by的汇总操作。

      8.Hive的排序

          1)order by:order by会对输入做全局排序,因此只有一个reduce,但是也会因此导致当输入规模较大时,消耗较长的计算时间。
          2)sort by:sort by不是全局排序,结果有多个且只能保证reduce内排序。使用sort by要确保reduce task > 1。
          3)distribute by:distribute by是控制在map端如何拆分数据给reduce端的。hive会根据distribute by后面列,对应reduce的个数进行分发,默认是采用hash算法,类似于MR中的partition。sort by为每个reduce产生一个排序文件。并且distribute by经常和sort by配合使用。
          4)cluster by:cluster by除了具有distribute by的功能外还兼具sort by的功能。即如果分区字段与排序字段一致的情况下,可以简写使用cluster by替换distribute by与sort by的组合,但是排序只能是升序排序,不能指定排序规则为ASC或者DESC。

      9.Hive的内部表和外部表

          1)内部表:Hive在创建的时候默认是内部表,内部表由Hive自身管理,内部表不共享数据,删除内部表的时候会删除内部表的数据和相应的元数据信息。
          2)外部表:外部表由HDFS管理,删除外部表只会删除元数据信息,不会删除存储在HDFS上的数据信息。

2.4 Spark

      1.Spark比Hadoop快的原因

      Hadoop由于在数据读写时需要进行多次磁盘IO操作,而Spark是将数据在内存中进行存储与运算,全部运算结束后存储。故当存在多个任务数据通信问题时,Spark由于基于内存进行数据通信会比基于磁盘进行数据通信的Hadoop快。Spark允许我们利用缓存技术和LRU算法缓存数据的,即当shuffle发生的时候,数据同样是需要写入磁盘的。Spark并不是基于内存的技术,而是使用了缓存机制的技术。不过Spark只有在shuffle的时候将数据写入磁盘,而Hadoop中多个MR作业之间的数据交互都要依赖于磁盘交互,故会存在速度对比。

      Hadoop的每一个作业称为一个Job,Job里面分为Map Task和Reduce Task阶段,每个Task都在自己的进程中运行,当Task结束时,进程也会随之结束;

      Spark用户提交的任务称为application,一个application中存在多个job,每触发一次action算子的操作就会产生一个job。每个job中有多个stage,stage是由产生shuffle过程中宽依赖关系进行划分的,每个stage里面又有多个task,组成taskset,由TaskScheduler分发到各个executor中执行。并且executor的生命周期是和application一样的,所以task可以快速启动读取内存进行计算。

     Spark适合单次分析数据量不是很大的场景,Hadoop则适用于较大数据量的场景。


      2.Spark的宽依赖和窄依赖

           在DAG调度中需要对计算过程划分Stage,而划分的依据就是就是RDD之间的依赖关系。针对不同的转换函数,RDD之间的依赖关系分为窄依赖(narrow dependency)和宽依赖(wide dependency,也称为shuffle dependency)。两者的区别在于每一个分区承接多少个上游依赖的分区数量,若每一个子RDD的分区都只承接使用上游父RDD的一个分区,那么就是窄依赖;若每一个子RDD的分区都可能承接父RDD的多个分区,那么就是宽依赖。由宽依赖的名称可知,被判定为宽依赖则会产生shuffle,那么如sortBy,reduceByKey,join等的上下游RDD之间的关系都可以被称为宽依赖关系。

      3.Spark的算子分类https://blog.csdn.net/weixin_38750084/article/details/83145432

      1) 转换算子:transformation算子,是一种懒执行的算子,即转换算子会记录元数据信息,当计算任务触发执行算子时,才会真正开始计算。

      map,flatMap,filter,distinct,cache,persist,

      2) 执行算子:action算子,是一种即时计算的算子。

      3) 控制算子:cronroller算子,是一种支撑持久化的算子(cache、persist、checkpoint),实际上也是懒执行。

      4.Spark RDD

      RDD(Resiliennt Distributed Datasets)抽象弹性分布式数据集,是一个并行的抽象的逻辑上的数据结构,可以将数据存储在磁盘与内存中,并能够控制数据分区。RDD可以将中间计算的数据结果存储在内存中,即在后续使用中可以直接从内存进行数据读取,提高计算速度。RDD的数据默认存储在内存中,但是当内存资源不足时,spark会自动将RDD数据写入磁盘。RDD的特点如下:

      1) 分区列表( a list of partitions):Spark RDD是被分区的,每一个分区都会被一个task处理,并且RDD的并行度是从父RDD传给子RDD的。

      2) 每一个分区都有一个计算函数( a function for computing each split):每一个RDD都会实现compute函数,对具体分片进行分布式并行计算。

      3) 依赖于其他RDD(a list of dependencies on other RDDs):RDD是在每次转化过程中都会生成新的RDD,能够在部分分区数据丢失时通过依赖关系重新计算丢失分区数据而不是对RDD所有分区都进行重新计算。而宽依赖后的RDD会依赖前面所有RDD的数据分片。

      4) KV数据结构的RDD分区器(a Partitioner for Key-Value RDDS):每一个kv形式的RDD都存在partitioner属性用以决定RDD如何分区,也决定了RDD shuffle输出时的分区数量。

      5) 每个分区都有一个优先位置列表(a list of preferred locations to compute each split on):按照“移动数据不如移动计算”的里面,Spark在执行任务的调度时会将计算任务分配到其所要处理数据块的存储位置。

      5.Spark 持久化

      使用cache与persist可以将数据进行持久化到内存中的操作,cache是无参的persist操作,persist提供不同的StorageLevel参数使用。如果需要从内存中清楚缓存,可以使用unpersist方法。

      6.Spark集群角色(主要分为两类,Master和Worker)

      1) Cluster Manager:是存在于Master进程中的集群管理器,主要是用以对应用程序申请的资源进行管理,可以根据集群部署形式的不同划分模式等。

      2)Worker:主要用于执行任务提交的工作节点。Worker节点会向Cluster Manager汇报自身的CPU,内存及资源使用情况和相关的executor计算单元的状态等信息,并创建真正执行计算的计算单元executor。Master会将任务分配给Worker节点上的executor并执行。

      3)Executor:真正创建的计算任务单元,是运行在Worker上的一个进程。能够将数据保存在内存或磁盘中存储并将结果返回给Driver。

      4)Application:Spark API编程的应用程序,包括实现Driver功能的代码和每一个Executor上要执行的代码块,一个application由多个job组成。

      4)Driver:驱动器节点,是运行Application中main函数并创建SparkContext的进程,Application可以通过Driver和Cluster Manager及executor通讯,Driver还负责作业调度解析,包括该DAGScheduler和TaskScheduler。

      4)SparkContext:Spark所有功能的主要入口,最重要的一个对象,核心作用是初始化Spark应用程序所需的组件等。

      7.Spark作业运行流程

      1)SparkContext向cluster Manager申请CPU,内存等计算资源

      2)Cluster Manager分配应用程序执行所需要的资源,在Worker节点创建executor

      3)SparkContext将程序代码和task任务发送到executor上进行执行,待任务执行完成后,SparkContext会收集结果到Driver端

      8.Spark和Hadoop的shuffle

但是

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无语梦醒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值