there are concerpt of partition both in hdfs and spark, but they servers for different purpose
In hdfs
为了存储效率
let's say there is a table named 'order'
we partition it by order_month, then the file struture may like:
- order/
-
order_month=202511/
- block1 128mb
- block2 127mb(不一定满)
- block3 24mb
-
order_month=202512/
- block1 128mb
- block2 24mb
-
此时如果查询条件where order_month = '202511', 那么只需要读取'order_month=202512/'这个分区下的数据文件就可以了
分区时,需要特别注意处理数据倾斜(data skew) --min/25th/mid/75th/max
hdfs中数据是以一个个block来存储的,单个block文件最大容量,默认128MB(参数控制)
当向hdfs写入一个大文件(超过128MB),那么该大文件会被拆分为多个block文件,如200MB,分成128MB + 72MB
当向hdfs写入一个小文件(未超过128MB),那么该小文件会被单独存储
128MB通常不会完全的用满,因为不能打一行或者一列数据拆到两个文件
分区文件会被备份多份(默认3份),分散在集群节点中
In spark
为了计算效率,而且可以在运算过程中动态改动
当spark读取数据时,会将数据分拆或者合并成多个分区,分别交给多个task,以便并行执行,提高效率
分区策略:
- 单个分区最大数据量,如128MB,那么如果一个源文件200MB的话,则会被拆成2份,128+72,分别放到2个task去执行
- 并行度,解设并行度为4,
- 如果此时只有两个小文件,22MB + 3MB,那么不会合并文件
- 如果此时有5个文件,128MB, 128MB, 88MB, 22MB, 3MB,那么会合并小文件,最终分区4个分区,分别放到4个task去执行
- 单个stage的task数量由该stage的最后一个步骤决定
spark的dataframe写入文件时,一个分区生成一个文件,5个分区的话,则最终会生成5份数据文件。如果有要求只能生成一个文件,则需要执行repartition合并成1个分区
