10-1、Spark I/O机制

7、Spark I/O机制

7.1、序列化

Spark通过集中方式实现进程通信,包括Actor的消息模式、Java NIONettyOIO

 

序列化是将对象转换为字节流,本质上可以理解为将链表存储的非连续空间的数据存储转化为连续空间存储的数组中。这样就可以将数据进行流式传输或者块管理。

 

序列化主要有以下两个目的:

进程间通信:不同节点之间进行数据传输;

数据持久化存储到磁盘:本地节点将对象写入磁盘;

 

7.2、压缩

当大片连续区域进行数据存储并且存储区域中数据重复性高的状况下,数据适合进行压缩。数组或者对象序列化后的数据块可以考虑压缩。所以序列化后的数据可以压缩,使数据紧缩,减少空间开销。

压缩采用了两种算法:SnappyLZF,底层分别采用了两个第三方库实现,同时可以自定义其它压缩对Spark进行扩展。

Snappy提供了更高的压缩速度,LZF提供了更高的压缩比。

 

val conf=sc.getConf

conf.getBoolean(“spark.broadcast.compress”,true)

conf.set(“spark.broadcast.compress”,true)

ScSparkContext对象,confSparkConf对象。

 

在分布式中,序列化和压缩是两个重要的手段。

Spark通过序列化将链式分布的数据转化为连续分布的数据,这样就能够进行分布式的进程间数据的通信,或者在内存进行数据压缩等操作,提升Spark的应用性能。

通过压缩,能够减少数据的内存占用,以及IO和网络数据传输开销。

7.3、块管理

RDD在逻辑上是按照Partition分块的,可以将RDD看成是一个分区作为数据项的分布式数组。物理上存储的RDD是以Block为单位的,一个Partition对应一个Block,用PartitionID通过元数据的映射到物理上的Block,而这个物理上的Block可以存储在内存,也可以存储在某个节点的Spark的硬盘临时目录。

SparkI/O管理整体分为两个层次:

1)、通信层:I/O模块也是采用Master-Slave结构来实现通信层的架构,MasterSlave之间传输控制信息、状态信息。

2)、存储层:Spark的块数据需要存储在内存或者硬盘,有可能还需要传输到远端机器,这些有存储层完成。

 10-1、Spark I/O机制_第1张图片

 

 

 

可以通过以下几个维度来理解整个存储系统:

1)、管理和接口:

当其他模块要与storage模块进行交互时,storage模块提供了统一的操作类BlockManager,外部类与storage模块打交道都需要调用BlockManager相应接口来实现。

2)、通信层:

BlockManagerMasterActor:在主节点创建,从节点通过这个Actor的引用向主节点传递消息和状态。

BlockManagerSlaveActor:在从节点创建,主机点通过这个Actor的引用向从节点传递命令,控制从节点的块读取。

BlockManagerMaster:对Actor通信进行管理。

3)、数据读写层:

DiskStore:提供Block在磁盘上以文件形式读写的功能;

MemoryStore:提供Block在内存中的Block读写功能;

ConnectionManager:提供本地机器和远端节点进行网络传输Block的功能;

BlockManagerWorker:对远端数据的异步传输进行管理。

 

 

主节点和从节点之间通过Actor传递消息来传递命令和状态。

Master节点负责总体控制,Slave节点接受命令、汇报状态。(ActorrefAKKA中两个不同的Actor引用)。

BlockManager在内部封装BlockManagerMaster,并通过BlockManagerMaster进行通信。Spark在各节点创建各自的BlockManager,通过BlockManagerstorage模块进行操作。Block对象在SparkEnv创建,SparkEnv相当于线程的上下文变量,在SparkEnv也会创建很多的管理组件。

http://www.cnblogs.com/fxjwind/p/3513369.html

 

7.4、数据读写

数据写入:

 10-1、Spark I/O机制_第2张图片

 

数据写入主要分一下步骤:

1)、RDD调用compute()方法进行制定分区的写入。

2)、CacheManager中调用BlockManager判断数据是否已经写入,如果未写入则写入。

3)、BlockManager中数据与其他节点同步。

4)、BlockManager根据存储级别写入制定的存储层。

5)、BlockManager向主节点汇报存储状态。

数据读取:

RDD类中,通过compute方法调用iterator读写某个分区(Partition),作为数据读取的入口。分区是逻辑概念,在物理上是一个Block

在本地同步读取数据块,首先看能否在内存读取数据块,如果不能读取,则看能否从Tacjyon读取数据块,如果仍不能读取,则看能否从本地磁盘读取数据。如果仍不存在,再看看网络中其它节点是否有数据。

内存Block块管理是通过链表来实现的。

DiskStore中,一个Block对应一个文件。



你可能感兴趣的:(10-1Spark,IO机制)