- 行:同一行的数据存储在一起,即连续存储。SequenceFile,MapFile,Avro Datafile。采用这种方式,如果只需要访问行的一小部分数据,亦需要将整行读入内存,推迟序列化一定程度上可以缓解这个问题,但是从磁盘读取整行数据的开销却无法避免。面向行的存储适合于整行数据需要同时处理的情况。
-
列:整个文件被切割为若干列数据,每一列数据一起存储。Parquet , RCFile,ORCFile。面向列的格式使得读取数据时,可以跳过不需要的列,适合于只处于行的一小部分字段的情况。但是这种格式的读写需要更多的内存空间,因为需要缓存行在内存中(为了获取多行中的某一列)。同时不适合流式写入,因为一旦写入失败,当前文件无法恢复,而面向行的数据在写入失败时可以重新同步到最后一个同步点
** ORCFile:比RCFile更加高效的文件格式,将数据分为250m Stripe,每个Stripe都含有完成的索引,元数据
RCFile:这种类型的文件先将数据按行划分成Row Group,在Row Group内部,再将数据按列划分存储
Parquet:种通用的面向列的存储格式,基于Google的Dremel。特别擅长处理深度嵌套的数据。
对于嵌套结构,Parquet将其转换为平面的列存储,嵌套结构通过Repeat Level和Definition Level来表示(R和D),在读取数据重构整条记录的时候,使用元数据重构记录的结构
image.png
splittable
表示压缩格式是否可以被分割,也就是说是否支持随机读。压缩数据是否能被mapreduce使用,压缩数据是否能被分割就很关键了。
image.png
彻底理解spark读取hdfs系统中文件压缩算法是snappy的parquet文件
- hdfs 是分布式文件系统,对用户来说就是一个云盘
- spark使用enablehive功能执行sql,本质上也是使用的inputFormat的实现类来进行读取hdfs上的文件,snappy文件无法实现随机读取,所以不管snappy文件有多大,读取下来都是一个整的文件,然后在进行repartition(200)
- 对于数据读入阶段,例如sc.textFile,输入文件被划分为多少InputSplit就会需要多少初始Task。如果是snappy文件
part-00000-b5507949-5fd0-4467-b6d3-5d0b67a388bc-c000.snappy.parquet
有多少个文件就是多少并行度,然后再调用repartition(200) - 在Map阶段partition数目保持不变。
- 在Reduce阶段,RDD的聚合会触发shuffle操作,聚合后的RDD的partition数目跟具体操作有关,例如repartition操作会聚合成指定分区数,还有一些算子是可配置的。
建议:
- 用一些包含了压缩并且支持splittable的文件格式,比如SequenceFile,RCFile或者Avro文件。
- 提前把文件分成几个块,每个块单独压缩,这样就无需考虑splittable的问题了











网友评论