spark笔记

深入理解Spark:核心思想与源码分析
http://www.java1234.com/a/javabook/javaweb/2016/0521/6137.html

一个job可分为1到多个stage;
一个job前面是多个Transformation,后面是一个action;
一个DAG可以是一个job,也可以是多个job,具体看有多少action算子,job数等于action算子数;
stage的划分主要集中在job前面的Transformation部分,因为后面只有一个action;
stage按照宽窄依赖划分,而不是按算子,如多个算子可以在一个stage中;
action和宽窄依赖的关系?(action一定是宽依赖?宽窄依赖只对Transformation算子而言?这个问题不涉及全局,因为action只有一个)
action之后能否再有Transformation?(不能,因为不是rdd了;如果开启新的job呢?)
action返回的一定不是RDD?(如返回一个数、一个array或无返回,但一定不是rdd)
一个job有1或多个task;
一个stage有1或多个task;(task一定属于某个stage?是的,一个stage中所有task结束后才能根据DAG执行下一个stage)
(每个Task都是在不同的数据分区上做同样的事情(即执行同样的代码段))
一个算子不是一个task;
task和rdd分区紧密联系,一个rdd有多少个partition,就会有多少个task,因为每一个task只是处理一个partition上的数据;
(task属于rdd还是属于rdd之间的连边?task取决于每个rdd各自的分区数之和,还是和父子rdd之间的连边数有关?应该不是连边)
(能不能说1个task分为1到多个stage?不能,task属于stage)
DAG-job-stage-task概念依次缩小,关系为“包含1或多个”;

以下说法正确:
DAG由RDD构成;
一个RDD分为多个分区partition;
子RDD对父RDD的依赖分为宽依赖和窄依赖;
Transformation算子分为Value数据类型和Key-Value数据类型;
在Spark中有两类task,一类是shuffleMapTask,一类是resultTask;
(第一类task的输出是shuffle所需数据,第二类task的输出是result)
Stage也分为两种:ShuffleMapStage 和 ResultStage;
(ShuffleMapStage的最后Task就是ShuffleMapTask;)
(ResultStage 是一个Job的最后一个Stage,直接生成结果或存储;)

action算子有如下:
reduce、collect、count、first、take、taksSample、takeOrdered、foreach、countByKey、savaAsObjectFile、saveAsSequenceFile、saveAsTextFile

spark1.X使用spark context;
spark2.X引入spark session;

spark core的存储主要是内存,计算由DAGScheduler、RDD、Executor负责;(每个节点有Executor,负责Map和Reduce)
SparkContext=DAGScheduler+TaskScheduler,同时隐藏了很多细节,如网络通信、分布式部署、存储、计算、缓存等;
DAGScheduler负责创建job,会在任务提交前,将job的RDD组织成DAG,并对stage进行划分(决定如何迭代和shuffle);
TaskScheduler负责申请资源、提交任务,请求集群对任务的调度;

sparksql原理:

  1. 利用SqlParser将sql解析为语法树,利用规则执行器RuleExecutor将Rule应用到语法树,生成物理计划
  2. RuleExecutor包括语法分析器Analyzer和优化器Optimizer

spark streaming原理:

  1. Dstream是spark streaming所有数据流的抽象;Dstream可以被组织为Dstream Graph;Dstream本质上是一系列RDD;

spark依赖yarn、mesos、ec2等集群管理器;这些管理器对worker分配cpu、内存等资源,属于一级分配;(不负责Executor级别的分配)

worker负责创建Executor,进一步分配资源给Executor,属于二级分配;同步资源信息给管理器;

Driver APP是用户写的代码,转换为RDD和DAG,并与管理器通信;

scala的Actor并发编程模型、Akka和spark的ActorSystem类(既用它发送分布式消息,又用它实现并发编程)
(Actor模型内部数据只能由它自己修改,相对java并发模型更轻量级)
https://www.cnblogs.com/MOBIN/p/7236893.html
https://blog.csdn.net/zhaodedong/article/details/73441303

每个map和reduce任务有唯一的标识,为mapId和reduceId;
reduce会到map节点拉取数据block,叫做shuffle;
每个shuffle过程也有唯一的标识,为shuffleId;

map、reduce、shuffle都是线程吗?

sparkUI采用监听机制,即采用异步的方式,多个具体Listener继承SparkListener;
(listenerBus实现监听器模型,是一个事件队列,达到UI界面刷新效果)
(以JobProgressListenser为例,把jobId和stageId一对多关系,存入hashmap)
(sparkUI使用了内置的Jetty?)

spark会获取hdfs的配置;

worker通过spark.executor.memory指定Executor的内存大小;

TaskScheduler有两种调度策略FAIR和FIFO,从sparkconf读取配置,为每个任务分配CPU数、调度策略等;
调度落实到SchedulerBackend具体实现上,如LocalBackend,后者依赖LocalActor与ActorSystem通信;

DAGScheduler是在TaskScheduler之前的步骤,主要维护jobId和stageId的关系、Stage状态、Job状态、RDD的分区位置等;
(也采用Akka、Actor模型以及ActorSystem实现)

Executor会向Driver发送心跳,由startDriverHeartBeater方法启动;
(心跳间隔由spark.executor.heartbeaterInterval设置,有超时、重试、休眠机制)
(心跳用于更新任务测量信息,告知BlockManagerMaster该Executor上的BlockManager依然活着)
(DriverHeartReceiver接收心跳信息,交给DAGScheduler和TaskScheduler做进一步处理)
ExecutorActor负责接收发给Executor的消息;
ExecutorSource用于测量系统;
Akka发送消息帧大小;

BlockManager即块管理器,管理整个Spark运行时的数据读写;是对外提供的统一访问block的接口;是Spark存储体系中的核心组件;
BlockManager也是分布式的;BlockManager运行在driver和Executor上面;(driver和Executor都会创建BlockManager,且互相通信)
BlockManager包括内存存储、磁盘存储、磁盘块管理器、BlockManagerMaster、shuffle客户端、广播和非广播Block清理器、Tachyon存储器;
(CacheManager是对BlockManager的缓存代理)

BlockStore抽象类制定存储规范,具体实现有MemoryStore、DiskStore、TachyonStore等;
(DiskStore采用NIO实现,如Channel等,在flume中也如此)
(MemoryStore有一个内存模型,同时为防止内存溢出,先逻辑申请,再安全展开unrollsafely)
(TachyonStore作用,由于Spark的计算引擎和存储体系在一个进程,当计算奔溃,内存中的数据也会丢失;不同任务都去hdfs加载Block数据到内存,导致重复加载,以及GC时间过长)
(Tachyon依赖zk,也有master-worker;采用与spark类似的机制如RDD不可变性,lineage血缘关系和检查点来恢复数据,不用担心存在内存中的风险)

Shuffle机制被嵌入存储体系(可见Shuffle是spark的根本需要),它在不同节点的Executor之间搬运数据(既shuffle别的节点,也提供别的节点shuffle服务);
(spark和hadoop一样,都使用Netty作为shuffle服务器)
(shuffle常见场景,reduce任务拉取map任务的中间结果)
(shuffle、Netty、Rpc三者关系?shuffle通过Rpc实现?RPC分为server和客户端)
(ShuffleMemoryManager为shuffle线程分配内存池,保证合理共享内存;当总线程为N,每个线程获得内存在1/2N与1/N之间;)

spark节点通信什么时候用RPC,什么时候Http?
spark的block就是hdfs的block???不是

spark目前支持hdfs、Amazon S3和alluxio三种分布式文件系统;

总结SparkContext重点:
SparkEnv、SparkUI、DAGScheduler、TaskScheduler、MetricsSystem等

Spark经常需要从hdfs读取文件生成RDD,然后进行计算分析。这种从hdfs读取文件生成的RDD就是HadoopRDD;

map、filter、flatMap对RDD进行转换(Transformation),join、groupBy、ReduceByKey对RDD完成数据计算(action);
(所有transformations都是lazy的;)

Spark中cache和persist区别:

  1. cache其实是调用了persist方法,缓存策略为MEMORY_ONLY;
  2. 两者都能通过unpersist来进行释放;
    https://www.2cto.com/net/201703/608793.html

cache、persist、unpersist三个操作比较特殊,他们既不是action也不是transformation。

Spark supports two types of shared variables: broadcast variables and accumulators;
broadcast variables(广播大变量):

  1. 通过高效的broadcast algorithms减少通信开销;
  2. 通常是只读的通用的大变量;
  3. 接口为SparkContext.broadcast(v),源码为org.apache.spark.broadcast.Broadcast
    accumulators(累加器):
  4. 出现在spark UI,可用来理解stage;
  5. 只能加,不能减?
  6. 接口为SparkContext.longAccumulator或SparkContext.doubleAccumulator;
  7. 累加器变量只有在action动作发生时才累加;

spark的计算图一定是无环的吗?直觉上,为啥不可能有环?GraphX全是图,怎么利用DAG??值得研究

窄依赖会被划分到同一个stage,以管道的方式迭代执行;宽依赖所依赖上游RDD不只一个(这个窄依赖也是啊!),需要跨节点传输数据;
从容灾角度,宽窄依赖恢复计算结果的方式不同;窄依赖失效只需重新计算RDD分区的父分区;宽依赖失效需要重新计算这个RDD的所有祖先丢失分区;
(窄依赖通常在一个节点内完成,注意是通常!!)
(窄依赖丢失RDD分区后,重算父RDD分区,的数据利用率100%)
(宽依赖丢失RDD分区后,产生大量冗余计算)
()

宽窄依赖又取决于什么??取决于函数或算子

窄依赖是指父RDD的每个分区只被子RDD的一个分区所使用,子RDD分区通常对应常数个父RDD分区(O(1),与数据规模无关)
宽依赖是指父RDD的每个分区都可能被多个子RDD分区所使用,子RDD分区通常对应所有的父RDD分区(O(n),与数据规模有关)
(问题来了,假如一个父RDD和两个子RDD,父RDD的每个分区只被每个子RDD的一个分区依赖,那么属于宽or窄依赖?)
(或者一般只能是父RDD多于子RDD,所以不会出现以上情况?或者就属于宽依赖?)
http://shiyanjun.cn/archives/744.html !!!
https://blog.csdn.net/houmou/article/details/52531205 好!
https://blog.csdn.net/album_gyd/article/details/76651094
https://blog.csdn.net/qq_21989939/article/details/79464023

窄依赖的函数有:map, filter, union, join(父RDD是hash-partitioned,或join with inputs co-partitioned), mapPartitions, mapValues
宽依赖的函数有:groupByKey, join(父RDD不是hash-partitioned,或join with inputs not co-partitioned), partitionBy、reduceByKey、sortByKey

Driver的DAGScheduler解析作业并生成相应的Stage,每个Stage包含的Task通过TaskScheduler分配给Executor执行。
(可见,一个stage至少一个task?或一个算子就是一个task?)

默认情况下,一个hdfs块就是一个RDD分区;

stage划分从后往前划分?从finalStage开始

http://spark.apachecn.org/paper/zh/spark-rdd.html !!!中文版论文

求《Spark核心源码分析与开发实战》王家林 电子版

非local模式是Executor进程和Driver进程不在同一个进程,甚至不在一个节点;
(local模式,只有Driver,没有Master和Worker,且Executor和Driver居然在同一个进程!P225)

local与local-cluster啥区别?本地模式和本地伪分布式模式,都只用于调试、无法容错、不能用于生产;
(local-cluster模式,Driver、Master和Worker在同一个JVM进程;可以有多个worker,每个worker多个Executor,但Executor存在于单独JVM进程;)

注意:Driver、Master和Worker都是进程,不是节点;
(SPARK_WORKER_INSTANCES是当前机器上的worker进程数量,默认是1,可以设置成多个;SPARK_WORKER_PORT是worker节点的端口号,默认是随机的)

Standalone部署模式,即spark://,具备容错能力,支持分布式,可用于实际生产;
(通过手动启动master和worker节点来创建集群,或者用官网提供的启动脚本如sbin/start-master.sh、sbin/start-slave.sh,必须先master再worker)
(类似于MapReduce 1.0所采用的模式,内部实现了容错性和资源管理)
(Standalone下,只有一个master万万不能,会出现单点故障;解决办法是HA,即master/slave,有多个master,但同时只有一个master)
(可使用zk进行选举,也可使用默认选举机制)
(什么是故障恢复持久化引擎?基于zk、基于文件系统、基于默认)
(选举和持久化引擎可一起使用,提高容错能力)
http://dongxicheng.org/framework-on-yarn/apache-spark-comparing-three-deploying-ways/)

第三方部署模式,包括yarn-cluster、yarn-client、zk://、mesos://等;
(这种方式可以与其他计算框架,比如MapReduce,公用一个集群资源,最大的好处是降低运维成本和提高资源利用率(资源按需分配))
(Spark On Mesos分为粗粒度模式和细粒度模式;后者思想是按需分配;后者缺点短作业运行延迟大;)
(Spark On YARN目前仅支持粗粒度模式?)
(yarn中,JobTracker被分为两部分,RM和AM;RM负责资料管理和调度,AM负责应用程序任务划分、调度;)
(yarn中,container是对cpu、内存的封装;用户提交的每个任务都有一个AM;不过这里的任务与spark的task对应?还是job对应?)
(AM与RM通信获取资源,与NM通信启动或停止任务、监控失败任务为其重新申请资源、重启等;)
(NM定时向RM汇报本节点资源使用情况,也接受AM的启动停止任务请求;)
(yarn部署中,worker被nodemanager代替;)
(NM是管理整个节点资源的,不仅为spark服务,也可以为别的如storm、mr等服务;worker只是管理其Executor的资源;)
(当使用yarn时,NM给worker分配资源,worker再给Executor分配资源,还是NM直接给Executor分配资源?worker被架空?)
(当使用yarn时,worker压根不存在!!!)
(NM既与AM通信,又与RM通信!)
(AM与某个任务或应用有关;RM整个yarn集群只有一个;NM每个节点有一个;)

sparksql的上下文管理器是SqlContext;
Catalog是对各种表进行操作的类或特质;
spark的语法树由TreeNode实现,TreeNode分为一元、二元和叶子节点;
词法解析器Parser包括DDLParser、SqlParser、SparkSQLParser;
DDLParser是建表语句解析器,用于创建临时表;
对SqlParser源码的阅读,可发现sparksql不支持delete、update;
转化为物理执行计划,才能被当成一般Job来执行;

excel->flume->kafka/rabbitmq->storm/spark streaming->es/hbase
flume能直接写入storm/spark streaming吗,中间不经过消息队列?
可以有两种方法:
Approach 1: Flume-style Push-based Approach(flume推送到端口,spark streaming监听端口)
Approach 2: Pull-based Approach using a Custom Sink(flume将数据发送到sink,累积起来,spark streaming通过事务机制去拉取,比第一种方法容错性更好)
http://spark.apache.org/docs/latest/streaming-flume-integration.html

spark streaming将实时数据流按照批次划分,然后交给spark引擎,得到批次划分的结果流;(将流处理转化为批处理?一个时间窗内作为一批?)
一个批单独起一个线程?相比storm一次可以只处理一条数据,大大提高了吞吐量;storm容错效率也不如spark streaming(storm容错类似传统关系型数据库);
spark streaming通过创建离散流DStream,可以通过数据源如kafka等创建,也可以通过map、reduce等操作创建;
DStream表示一系列连续的RDD,是数据流的抽象;DStream有依赖的父DStream(如flapMap前的DStream是之后DStream的父DStream),构成DStreamGraph;
DStream表示的不是一个RDD在不同时间点的版本,而是连续到来的不同RDD!!!而且每个RDD是一个时间间隔(或时间窗)内的数据
(注意RDD本身就是不可变的,所以不存在时间上的变化版本!!!最多持久化或缓存一下)
任何对DStream的操作都会转化为底层RDD的操作;
说白了,DStream就是把源源不断到来的数据,按照时间窗,封装成一个个RDD,然后作为批处理,整个过程所以叫‘离散化’;

InputDStream是DStream的子类,也是所有输入流的超类;
ReceiverInputDStream继承InputDStream,并实现了输入流接收器的getReceiver方法;(所有其他InputDStream继承它)
spark的输入流是插件式的,可以自定义InputDStream;
所有ReceiverInputDStream子类都会被加到DStreamGraph;
DStream的接口方法和RDD的非常类似,也是map、reduceByKey、flatMap、filter等;
多个不同的输入流经过join、map等操作,变成另一个流,整个构成一个DStreamGraph;(类似DAG,只不过每个节点从单个RDD变为DStream,也就是多个RDD的序列)
流处理的执行过程比一般的批处理要长!
spark streaming的local模式的cpu数不得小于2,因为接受输入流的任务一直在Executor内,需要占一个核;另外一个是不断创建Job,以及执行runJob(按顺序提交)
(一般的批处理的local模式则不需要!)

什么是令牌桶机制?
当Receiver开始接收数据,将数据存入currentBuffer之时,需要获取许可(令牌);
如果获取到许可就将数据存入buffer, 否则将被阻塞,进而阻塞Receiver从数据源拉取数据。
什么是反压机制?
反压机制(back-pressure),通过动态控制数据接收速率来适配集群数据处理能力;配置项spark.streaming.backpressure.enabled
https://www.jianshu.com/p/f88f41c323d2)
https://www.cnblogs.com/itboys/p/6486089.html)

如何理解spark streaming能和mllib、graphx完美融合?

检查点分为两种:Metadata checkpointing和Data checkpointing
Metadata checkpointing主要针对driver节点的失效恢复,元数据包括配置、DStream operations、incomplete batches等;
Data checkpointing就是将RDD持久化,特别是当下一时刻RDD依赖前一时刻RDD,或叫stateful transformation,为了避免恢复时间无止境的增加,通过检查点切断依赖链;
(这个和tf训练时的检查点类似,如第1100步的结果依赖第1000步;)
(如果没有这种依赖关系,即每一时刻的RDD互相独立,也就不需要检查点;)
(一般的DAG批处理不需要checkpoint,因为有内部容错机制,即通过血缘关系,重新计算RDD)
(检查点会影响性能和吞吐量,因此interval需要认真选取;一般选择interval为5-10倍时间窗间隔;)
(注意,Accumulators and Broadcast variables无法从检查点恢复;)

官网详细介绍:
http://spark.apache.org/docs/latest/streaming-programming-guide.html

时间窗就是batchDuration,spark每隔batchDuration时间提交一次Job;
有必要设置合理的批处理时间;如果Job处理时间超过batchDuration,那么后面的作业无法按时提交,越来越多的作业被拖延,导致整个Streaming作业被阻塞,也就无法实时处理数据(一般不小于500ms);
(可以先设为10s,如果发现作业很快被提交完成,再去减小这个值,直到Streaming作业刚好能及时处理上一个批处理的数据,就是我们要的最优值)
https://www.cnblogs.com/gaopeng527/p/4961701.html

滑动窗口(WindowedDStream)是更高层的时间区间,它可以涵盖多个RDD,即将该窗口内的RDD合并为一个RDD
(有两个参数,一是涵盖多少个RDD即窗口长度,二是每次滑动多少间隔,且这两个参数都必须是batchDuration的整数倍)
(具体api有:reduceByKeyAndWindow、countByKeyAndWindow、reduceByWindow、countByWindow、countByValueAndWindow等)

(一个时间窗就是一个RDD;一个滑动窗口内有多个RDD)

StreamingContext是主要入口,最终处理交给SparkContext,除了SparkContext还封装了Checkpoint和Duration;
Receiver是数据接收器规范抽象类,主要有onStart和onStop需要实现;

spark介绍(含spark streaming)
https://www.cnblogs.com/liuliliuli2017/p/6809094.html

spark streaming和storm对比
https://www.cnblogs.com/shishanyuan/p/4747735.html

streaming-k-means:
http://spark.apache.org/docs/latest/mllib-clustering.html#streaming-k-means
streaming-linear-regression:
http://spark.apache.org/docs/latest/mllib-linear-methods.html#streaming-linear-regression

spark mllib介绍
http://spark.apache.org/docs/latest/ml-guide.html

  1. 分布式矩阵有4种:RowMatrix、IndexedRowMatrix、CoordinateMatrix、BlockMatrix;
  2. 局部向量分为稀疏向量和密集向量;
  3. spark1.2增加了新的包spark.ml,提供更高层的api,是DataFrame-based;(之前的spark.mllib是RDD-based,未来会被废弃甚至移除)
    spark使用的codahale metrics(ambari也是用的它?)
    官网https://metrics.dropwizard.io/4.0.0/
    源码https://github.com/dropwizard/metrics
    手册https://metrics.dropwizard.io/3.1.0/manual/

spark streaming和sparksql的关系:

  1. 目前没有使用sparksql执行spark streaming的(即以sql的形式执行流计算)
  2. 目前有在sparksql之上实现spark streaming的,即Structured Streaming;
    (Structured Streaming is a scalable and fault-tolerant stream processing engine built on the Spark SQL engine.)
    (The key idea in Structured Streaming is to treat a live data stream as a table that is being continuously appended.)
    (Structured Streaming 有三种模式:Complete Mode、Append Mode、Update Mode)
  3. http://spark.apache.org/docs/latest/structured-streaming-programming-guide.html
    https://blog.csdn.net/lovechendongxing/article/details/81748237(Structured Streaming解决了Spark Streaming的硬伤)
    (解决了Spark Streaming存在的代码升级,DAG图变化引起的任务失败,无法断点续传的问题)
    (Spark streaming的API是给码农用的低阶API;Structured streaming是给人设计的API,简单易用)

RDD、DataFrames和Datasets区别:
http://spark.apache.org/docs/latest/sql-programming-guide.html

  1. Dataset is a new interface added in Spark 1.6,同时基于Spark SQL的优化引擎;
  2. A Dataset can be constructed from JVM objects and then manipulated using functional transformations (map, flatMap, filter, etc.).
  3. A DataFrame is a Dataset organized into named columns.It is conceptually equivalent to a table in a relational database
    (DF清楚地知道该数据集中包含哪些列、以及列名和类型;)
    (Dataset可以认为是DataFrame的一个特例,主要区别是Dataset每一个record存储的是一个强类型值而不是一个Row)
    (DataFrame和DataSet可以相互转化,df.as[ElementType]和ds.toDF())
  4. 从RDD到DS有两种方法:第一种基于反射推断出RDD的schema;第二种利用编程接口,如toDS()
  5. 从RDD到DF也有两种:自动的和toDF()
  6. DataFrame比RDD提供更丰富的算子,提升了执行效率,减少数据读取以及执行计划的优化;
    https://www.jianshu.com/p/c0181667daa0)
  7. RDD不支持sparksql操作
  8. RDD一般和spark mlib同时使用;DataFrame与Dataset一般与spark ml同时使用;
    https://www.cnblogs.com/starwater/p/6841807.html)

RDD分区属于worker公有还是某个executor私有?应该是公有,由worker决定调用哪个executor对它进行计算

map和flatmap的区别:
https://www.iwwenbo.com/spark-map-flatmap/
map返回结果:Array(Array(word, in, text), Array(hello, spark), Array(the, third, line))
flatmap返回结果:Array(word, in, text, hello, spark, the, third, line)
(即flatmap比map多了一步flatten操作;扁平化意思就是降维,如把二维数组变为一维;有点类似python中append和extend的效果区别;)

基于hash的shuffle和基于sort的shuffle对比:

  1. 基于hash避免不必要的排序开销,但生成文件过多,对文件系统造成压力;
  2. 基于sort几乎任何测试都比基于hash的性能好;
  3. 配置项spark.shuffle.manager,类为HashShuffleManager和SortShuffleManager;

spark只能处理结构化数据,像网页这种半结构化数据,都要去掉html元素,变为结构化数据,才能被处理(如对应到hive的表字段);
而非结构化数据就更不能处理了,比如元数据、二进制文件(连人都无法理解);还有一点,有些数据需要人进行编写规则,才能让spark处理;
(图片和视频都是非结构化数据?图片不是像素矩阵吗?不能直接和表字段对应的都不是结构化数据;但是图片和视频都是可以处理的)


打赏一下作者:

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值