Spark存储体系

来源:互联网 发布:德国开山刀网站淘宝 编辑:程序博客网 时间:2024/06/08 08:44

Spark存储体系

无论是spark的任务提交还是,任务执行,在这过程中始终离不开spark的存储体系。spark为了避免hadoop读写磁盘的IO操作成为性能瓶颈,优先将配置信息、计算结果等数据存入内存,当内存存储不下的时候,可选择性的将计算结果输出到磁盘,为了保证性能,默认都是存储到内存的,这样极大的提高了spark的计算效率。存储体系中核心模块就是bolckmanager。在blockmanager中中要是由以下几部分分组成:

  • shuffle 客户端shuffleclient;
  • BlockManagerMaster(对存于所有Exector上的BolckManager统一管理);
  • 磁盘块管理器DiskBlockManager;
  • 内存存储MemoryStore;
  • 磁盘存储DiskStore;
  • Tachyon存储TachyonStore

spark 存储体系架构

spark存储架构图如下:

这里写图片描述

  • 1表示Executor的BlockManager与Driver的BlockManager进行消息通信,例如注册BlockManager、更新Block信息、获取Block所在的BlockManager、删除Executor等。
  • 2表示对BlockManager的读操作如get、doGetLocal等和写操作doPut、puSingle等。
  • 3表示当MemoryStore的内存不足时,写入DiskStore,而DiskStore实际依赖于DiskBlockManager。
  • 4表示通过访问远端节点的Executor的BlockManager中的TransportServer提供RPC服务下上传Block。
  • 5表示远端节点的Executor的BlockManager访问本地Executor的BlockManager中的TransportServer提供的RPC服务下载Block。

shuffle服务与客户端

Block的RPC服务

当map任务与reduce处于不同的节点时,reduce任务需要从远端节点下载map任务的中间输出,因此NettyBlockRpc Server提供打开,即下载block的功能;在一些情况下,为了容错,需要将Block备份到其他节点,NettyBlockRpcServer还提供上传Block文件的Rpc服务;

构造传输上下文TransportContext

TransportContext既可以创建Netty服务,也可以创建Netty访问客户端,组成部分如下:
1)TransportConf:主要控制Netty框架提供的shuffle的I/O交互的客户端和服务端线程数量等;
2)RpcHandler:负责shuffle的I/O服务端在接收到客户端的RPC请求后,提供打开Block或者上传Block的RPC处理,此处实现为NettyBlockRpcServer;
3)是否关闭闲置连接

获取远程shuffle文件

NettyBlockTransferService的fetchBlocks方法用于获取远程的shuffle文件,实际是使用NettyBlockTransferService中创建的Netty服务。通过Netty服务获取远程Block.

上传shuffle文件

NettyBlockTransferService的uploadBlock方法用于上传shuffle文件到远程的Executor,实际也是用NettyBlockTransferService中创建的Netty服务,步骤如下:
1)创建Netty服务的客户端,客户端连接的hostname和port正是BlockManager的hostname和port
2)将Block的存储级别StorageLevel和类标签序列化
3)将Block的ByteBuffer转化为数据,便于序列化
4)将appId、execId、blockId、metadata、转化为数组的Block封装为UploadBlock,并将其序列化为字节数组
5)最终调用Netty客户端的sendRpc方法将字节数组上传,回掉函数RpcResponseCallback根据RPC的结果更改上传状态。


BlockManagerMaster

BlockManagerMaster 是Driver的DAGSchduler中的一个重要对象,其功能就是负责对各个节点的BlockManager内部管理的元数据,进行管理与维护,如block的增删等操作,都会在这里维护变化的操作。
每个worker中的BlockManager在创建后,首先要做的事情就是向Driver中的BlockManagerMaster进行注册。此时BlockManagerMaster内部就会为这个BlockManager建立一个对应的BlockManagerInfo。
每个BlockManager包含四个部分:DiskStore,MemoryStore,ConnectionManager(负责建立BlockManager到远程其他BlockManager的网络连接),BlockManagerWorker 负责对远程其他节点上BlockManager的数据的读写。

BlockStore

BlockStore是spark中的一个抽象类,在这个类中定义了一系列的存储规范,DiskStore(磁盘级别的持久化)、MemoryStore(内存级别的持久化)和TachyonStore(Tachyon内存分布式文件系统级别的持久化)。其继承类图如下:

这里写图片描述

内存存储MemoryStore

MemoryStore负责将没有序列化的java对象数组或者序列化后的ByteBuffer存储到内存中。整个MemoryStore分为两块:一块是很多MemoryEntry占据的内存currentMemory,这些MemoryEntry通常是通过entries持有的;另一块就是unrollMemoryMap通过占座的方式占用内存的current-UnrollMemory。unrollMemoryMap可以保证在向内存写入数据时不会发生溢出。
MemoryStory继承自BlockStore,并实现了getBytes,putArray,putIteratorI,getValues等方法。

磁盘存储DiskStore

DiskStore通过DiskBlockManager来实现Block和相应磁盘文件的映射关系,从而将Block存储到磁盘的文件中。DiskBlockManager根据YARN_LOCAL_DIRS或LOCAL_DIRS(yarn模式),SPARK_LOCAL_DIRS或spark.local.dir(其他模式,默认值System.getProperty(“java.io.tmpdir“))配置的本地根目录(可能有多个,以逗号分隔)来生成DiskStore存放Block的根目录(与配置的根目录对应,也有可能有多个):…/blockmgr-UUID.randomUUID.toString(yarn模式)或…/spark-UUID.randomUUID.toString/blockmgr-UUID.randomUUID.toString(其他模式)。同时DiskBlockManager会为每个根目录生成conf.getInt(“spark.diskStore.subDirectories“, 64)个子目录用来存放Block对应的文件,每个Block会根据它的name哈希到相应的子目录,然后以Block的name为文件名来生成文件存储。

Tachyon存储TachyonStore

TaychyonStore是以内存为中心的高容错的分布式文件系统,能够为集群框架提供可靠的内存级文件共享的服务。TachyonStore是一个分布式文件系统。
Tachyon也采用Master-Worker的架构,Tachyon Master支持ZooKeeper进行容错,用于管理全部文件的元数据信息,同时也监控各个Tachyon Worker的状态。每个Tachyon Worker启动一个守护进程,管理本地的Ramdisk,Ramdisk中存储了具体的文件数据,Ramdisk实际是Tachyon集群的内存部分。
Tachyon采用与sparkRdd 相类似的方法,它利用lineage信息和异步记录下来的checkpoint来恢复数据,所以Tachyon是可靠的。