Skip to main content

分布式并行Spark

分布式并行 Spark

spark: 内存计算, 流/批计算

底层类似dataframe,上层暴露sql接口

例子:log mining

从hdfs里面拉下来日志, 只读处理, 进行filter

同时,提供了接口来标识“希望被尽量保留在内存上的结果”和随便回收/移到磁盘的的中间结果

spark 必须跑几个节点: client, manager, worker

RDD: resilient distributed datasets 弹性分布式数据集

计算分为stage, 惰性执行, 在最后的取值操作前都只记录计算图

  • 惰性计算:Spark采用惰性计算(lazy evaluation),只有在执行行动操作(如collectsaveAsTextFile等)时,才会触发实际的计算。这意味着在转换操作过程中,不会立即生成所有的RDD,而是等到行动操作时才进行计算。
  • lineage 机制:Spark通过lineage机制记录RDD的生成过程。当需要重新计算某个RDD时,Spark可以根据lineage信息重新构建该RDD,而不需要保留所有的中间RDD。这大大减少了内存的使用。
  • 持久化:如果需要多次使用某个RDD,可以使用persistcache方法将其持久化到内存中。这样,后续的计算可以直接使用内存中的RDD,而不需要重新计算。例如:

scala的一部分: 将各种输入转换为RDD, 然后分布式并行

基本流程:

  • 从外部数据创建一些作为输入的RDD
  • 使用类似filter之类的transformation定义新的RDD
  • 要求Spark对需要重用的任何中间RDD进行persist
  • 启用类似count之类的action进行并行计算(求值延迟到此时)

partitonBy hash分区, 类似SQL的HASH JOIN

让O(mn)->O(m+n)

Narrow dep

  • 窄依赖
  • 父RDD的每个分区只被子RDD的一个分区使用
  • map,union,...

Wide Dep

  • 宽依赖
  • 父RDD的每个分区被子RDD的多个分区使用
  • Shuffle
  • Join with inputs not co-partitioned, ...

不仅是复杂度上, 窄依赖还可以让中间结果和父在一台机器上, 比网络通信更快很多

并且还有丢失时重算的代价

尽量使用窄依赖

宽依赖/明确要求缓存的分区, 就化成stage边界, stage也是lazy的 (只有当一个stage结束的时候才回推计算整个stage操作)

好处:

  • 减少内存开销(尤其针对长stage), 减少分布式通信所需要保留的中间数据
  • 便于本机并行化(窄长stage)

有不同的storage level

spark流式处理:切成小批量batch, 增量处理