Storage负责管理Spark计算过程中产生的数据,包括Disk和Memory,其中持久化的动作都是由Storage模块完成的
Storage模块采用Master/Slave架构,Master负责整个App的Block元数据信息的管理和维护,Slave将Block更新状态上传到Master,并接收Master的命令,它们之间通过AKKA机制通信
SparkContext创建时会在Driver端的SparkEnv创建BlockManager,持有一个BlockManagerMaster,并把请求转发给BlockManagerMasterActor完成元数据管理和维护
Executor端存在一个BlockManager,也会持有一个BlockManagerMaster,不过会有对应于Driver端的一个reference,所以就能通过它来上报消息给Master
还会持有一个BlockManagerSlaveActor,Master持有SlaveActor的reference,进而下达命令。
存储级别:
RDD持久化和缓存是Spark构建迭代式算法和快速交互式查询的关键
调用persist()或者cache()标记RDD需要持久化,cache()是使用默认存储级别(memory_only)的快捷方法
RDD的partition和Storage模块的Block是一一对应关系!!
通过org.apache.spark.storage.StorageLevel定义存储级别,选择级别时考虑内存的使用量、避免落入硬盘、故障恢复能力(多副本机制)等
性能调优:
spark.local.dir
用于写中间数据(RDD Cache、Shuffle)
可以配置:
1 多个路径到多个磁盘增加整体IO带宽
2 如果存储设备的读写速度不同,可以在较快的存储设备上配置更多的目录增加被使用的比例
3 SPARK_LOCAL_DIRS(Standalone, Mesos) LOCAL_DIRS(YARN)参数会覆盖这个配置
spark.storage.memoryFraction
spark.storage.memory决定了每个Executor可用内存大小,而spark.storage.memoryFraction决定了这部分内存中有多少可以用于Memory Store管理RDD Cache的数据
spark.executor.memory默认为0.6,太大的话会把old gen区域占满,造成频繁的全量垃圾回收
如果频繁发生全量垃圾回收,可降低这个值,但这样做RDD Cache可用的内存空间减少(部分Cache数据可能需要写到磁盘上)
spark.streaming.blockInterval
设置Spark Streaming里Stream Receicer生成block的时间间隔,默认为200ms。这个时间间隔应该被StreamingBatch的时间间隔整除
spark.streaming.blockQueueSize决定了streamBlock最多能存储的容量,默认为10