存储类介绍
spark中存储相关的类基本都在org.apache.spark.storage下面。
- MemoryStore:内存存储
- BlockId:block的唯一标识
- BlockInfoManager:记录block的元数据,同时也管理者block的锁
- BlockManager:最重要的类,是管理block的入口
- BlockManagerId:BlockManager的唯一id
- BlockManagerManagedBuffer:block的buffer,用于传输
- BlockManagerMaster:运行在driver,持有BlockManagerMasterEndpoint、BlockManagerMasterHeartbeatEndpoint
- BlockManagerMasterEndpoint:endpoint,master管理各个executor中的blockManager
- BlockManagerMasterHeartbeatEndpoint:endpoint,负责executor中的blockManager的心跳
- BlockManagerSlaveEndpoint:endpoint,executor中blockManager与driver通信
- BlockManagerSource:监控相关
- DiskBlockManager:block和实际文件对应关系
- DiskBlockObjectWriter:往磁盘写入的类
- DiskStore:磁盘存储
- StorageLevel:存储等级
MemoryEntry
MemoryEntry是内存存储的最小单位,有两个实现类分别对应序列化和非序列化:
- DeserializedMemoryEntry:Array[T] 存储数据
- SerializedMemoryEntry:ChunkedByteBuffer 存储数据
ValuesHolder
ValuesHolder用来临时存放数据,最后会生成MemoryEntry来存放数据。
它也有两个实现类,分别对应序列化和非序列化。
DeserializedValuesHolder
数据一条一条进来,先使用vector存储数据,完成后使用arrayValues存。
SerializedValuesHolder
可以选择存在堆内或者堆外。
每条数据都要经过序列化。
MemoryStore
主要方法分成三类:
- 存储数据:putBytes、putIterator、putIteratorAsValues、putIteratorAsBytes
- 读取数据:getBytes、getValues
- 删除数据:remove、evictBlocksToFreeSpace
entries
BlockId与MemoryEntry的关系。实际存储的结构。
putBytes
向memoryManager申请内存,然后生成MemoryEntry放入entries。
putIterator
- 存储iterator中的数据,iterator中的数据量不确定,所以一条一条进行存储,直到iterator中没有数据或者内存不够。
- 初始化一些必要参数,包括unroll标记,初始内存,扩容因子,unroll数据条数等
- 迭代iterator,将数据放入临时存储valueHolder中。每处理一批数据,进行扩容判断,需要扩容则进行扩容
- 迭代完毕后,因为最后存储所需的内存可能会超过申请的内存,所以再进行一个扩容判断,需要扩容则进行扩容
- 将unroll内存转store内存
- 将数据放入entries中,完成实际存储
putIteratorAsValues
使用非序列化的valuesHolder,调用putIterator方法。
putIteratorAsBytes
使用序列化的valuesHolder,调用putIterator方法。
getValues/getBytes
比较简单,从entries中取值,转成对应的数据结构。
remove
从entries中移除,再用memoryManager释放storageMemory
evictBlocksToFreeSpace
内存空间不够,清除内存中已经缓存的block。
- 遍历entries,记录可以驱除的block。(内存模式一致,不是同一个block)
- 遍历选中的block,进行驱除dropBlock
- 如果block可以存在磁盘上,就存到磁盘上,更新block信息。否则block完全删除了,移除block相关信息。