从多处收集各种关于Spark分布式计算的知识点。

Spark RDD 基础知识点:

RDD(Resilient Distributed Datasets)弹性的分布式数据集,代表一个只读的、不可变、可分区、里面元素可分布式并行计算的数据集。

  • Resilient(弹性的):使分布式集群中某个task节点失败时,能够只对这单个节点进行迁移重跑,而不需要全部task任务完成重跑,提高性能。
  • Distributed(分布式):将数据基于一定规则切分为多个子集,然后基于分布式集群进行计算。
  • Datasets(数据集):并不是储存数据本身,只记录数据存储的位置,通过调用spark算子将一个RDD转为另一个RDD。
  • 血统关系(Lineage):记录RDD的元数据信息和依赖关系,基于这些信息重新计算和恢复丢失的分区数据,也就是RDD弹性的特性。

Spark缓存和checkpoint:

缓存(cache/persist):是RDD的两个API,并且cache底层调用的就是persist,区别之一就在于cache只能缓存在内存中,但是persist可以通过指定缓存方式,比如显示指定缓存在内存中、内存和磁盘并且序列化等。通过RDD的缓存,后续可以对此RDD或者是基于此RDD衍生出的其他的RDD处理中重用这些缓存的数据集

容错(checkpoint):将RDD写入磁盘做检查点(通常是checkpoint到HDFS上,同时利用了hdfs的高可用、高可靠等特征)。Spark lineage在实际的生产环境中,一个业务需求可能非常复杂,调用很多算子,产生了很多RDD,RDD之间的linage链条就会很长,一旦某个环节出现问题,容错的成本会非常高。此时,checkpoint的作用就体现出来了。使用者可以将重要的RDD checkpoint下来,出错后,只需从最近的checkpoint开始重新运算即可。

checkpoint与cache/persist对比

  • 都是lazy操作,只有action算子触发后才会真正进行缓存或checkpoint操作;
  • cache只是缓存数据,但不改变lineage。通常存于内存,丢失数据可能性更大;
  • checkpoint改变原有lineage,生成新的CheckpointRDD。通常存于hdfs,高可用且更可靠。

窄依赖和宽依赖:

  • 窄依赖:父RDD的一个分区最多只能被子RDD的一个分区依赖;可形成pipeline管道数据处理。
  • 宽依赖:父RDD的一个分区被子RDD的多个分区依赖,通常是shuffle操作。

有向无环图(Directed Acyclic Graph,DAG):

  • 以RDD为顶点,对RDD的一系列操作为边组成的有向无环图。

Spark为什么比MapReduce快:

  • spark是基于内存计算的(shuffle阶段),减少低效的磁盘交互;
  • 高效的调度算法,基于有向无环图(Directed Acyclic Graph,DAG);
  • 基于弹性分布式数据集RDD实现高效容错,部分数据丢失出错可通过计算流程的血统关系(Lineage)实现重建,而MapReduce的容错只能重新计算

Hadoop和Spark的使用场景:

  • Hadoop/MapReduce更适合数据集特别大的场景,Spark适用中小企业数据量,处理速度更快。

Hadoop和Spark的不同点:

  • Hadoop底层使用MapReduce计算架构,只有map和reduce两种操作,表达能力比较欠缺,而且在MR过程中会重复的读写hdfs,造成大量的磁盘io读写操作,所以适合高时延环境下批处理计算的应用;
  • Spark是基于内存的分布式计算架构,提供更加丰富的数据集操作类型,主要分成转化操作(transformation)和行动(action)操作,包括map、reduce、filter、flatmap、groupbykey、reducebykey、union和join等,计算模型更灵活更强大,数据分析更加快速,所以适合低时延环境下计算的应用;但Spark是基于内存计算,在特别大的数据量情况下可能出现各种问题OOM。

Spark数据倾斜:

  • spark任务通常分为多个stage,stage之间是串行执行的,而一个stage有多个task,即将数据分成多个分区并行进行计算,当某个分区数目特别大是,导致这个task计算时间很长,导致下一个stage无法执行。
  • 要解决数据倾斜,通常需要选择合适的key值,或者定义相关的partitioner,通过哈希值来拆分原key值分区,将数据分散到不同的分区去处理。

RDD算子:RDD算子分为两大类,transformation和action。

  • transformation 算子:transformation操作会针对已有的RDD创建一个新的RDD,特点是lazy特性,transformation是不会触发spark程序的执行的,它们只是记录了对RDD所做的操作,但是不会自发的执行,相关算子有:Map、MapPartitions、FlatMap、Filter、distinct、sortBy、union、reduceByKey、groupByKey、sortByKey、join。
  • action 算子:action主要是对RDD进行最后的操作,会触发一个spark job的运行,从而触发这个action之前所有的transformation的执行,相关算子有:reduce、collect、count、save、take、aggregate、countByKey。

map和mapPartition的区别:

  • map:每次对 RDD 中的每一个元素进行操作;
  • mapPartitions:每次对 RDD 中的每一个分区的迭代器进行操作;function执行次数更少,效率更高,但也存在OOM风险。

reduceByKey 和 groupByKey 的区别:

  • reduceByKey 会在 shuffle 之前对数据进行合并,在转换操作时就已经对数据进行了一次聚合操作,从而减小数据传输。
  • groupByKey 算子操作发生在动作操作端,即 Shuffle 之后,所以势必会将所有的数据通过网络进行传输,造成不必要的浪费。
⤧  上一篇 模型层面知识点 ⤧  下一篇 LightGBM特征重要度和可视化