分布式并行Spark
分布式并行 Spark
spark: 内存计算, 流/批计算
底层类似dataframe,上层暴露sql接口
例子:log mining
从hdfs里面拉下来日志, 只读处理, 进行filter
同时,提供了接口来标识“希望被尽量保留在内存上的结果”和随便回收/移到磁盘的的中间结果
spark 必须跑几个节点: client, manager, worker
RDD: resilient distributed datasets 弹性分布式数据集
计算分为stage, 惰性执行, 在最后的取值操作前都只记录计算图
- 惰性计算:Spark采用惰性计算(lazy evaluation),只有在执行行动操作(如
collect
、saveAsTextFile
等)时,才会触发实际的计算。这意味着在转换操作过程中,不会立即生成所有的RDD,而是等到行动操作时才进行计算。 - lineage 机制:Spark通过lineage机制记录RDD的生成过程。当需要重新计算某个RDD时,Spark可以根据lineage信息重新构建该RDD,而不需要保留所有的中间RDD。这大大减少了内存的使用。
- 持久化:如果需要多次使用某个RDD,可以使用
persist
或cache
方法将其持久化到内存中。这样,后续的计算可以直接使用内存中的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, 增量处理