前两天,群里小伙伴问了一个问题:
不是说snappy压缩不支持split嘛,为什么我改小mapred.max.split.size一倍之后,mapper数翻倍?
一直以来大家都知道snappy是不支持切分的,但是在测试时,又发现在某些情况下,貌似支持切分,这让人很疑惑... ...
关于snappy压缩,在网上大家的说法也不是很统一,有人说不支持split,有人说支持:
凡是稍微有点深度的有问题,从网上求答案,真的是太难了......
这篇从群里小伙伴的这个问题出发,分析一下有关snappy压缩的一些事情及spark 在处理这一块的源码层面分析。
先给结论
1、snappy压缩格式本身是不可切分的;
2、snappy压缩格式作用在文本类文件格式上不可切分;
3、snappy压缩格式作用在Sequence、Avro、parquet、orc等这些容器类的文件格式上,能够支持切分。但这里的切分并不是因为snappy变的可切分了,而是因为这些容器类的文件格式牛逼~~
再理解一遍啥是可切分?啥是不可切分?原因是啥?
可切分:是否可以搜索数据流的任意位置并进一步往下读取数据。
啥意思?
1、假设有一个1GB的不压缩的文本文件,如果HDFS的块大小为128M,那么该文件将被存储在8个块中,把这个文件作为输入数据的MapReduc/Spark作业,将创建8个map/task任务,其中每个数据块对应一个任务作为输入数据。
对于不压缩的文本文件来说,是可切分,因为每个block都存了完整的数据信息,读取的时候可以按照规定的方式去读:比如按行读。
2、假如一个文本文件经过snappy压缩后,文件大小为1GB。与之前一样,HDFS也是将这个文件存储成8个数据块。但是每个单独的map/task任务将无法独立于其他任务进行数据处理,官方一点的说法,原因就是压缩算法无法从任意位置进行读取。
通俗的讲解,就是因为存储在HDFS的每个块都不是完整的文件