磁盘数据源-分区数据分配
spark在建立分区时,需要对每个分区的数据尽可能的平均,是根据字节来分的。但是往分区存数据的时候却是按“行”存取 spark是不支持文件操作的,文件操作都是hadoop完成的 Hadoop进行文件切分数量的计算和文件数据存储计算规则不一样 1.分区数量计算的时候,考虑的是尽可能的平均:按字节来计算 2.分区数据的存储考虑的是业务数据的完整性:按行来读取。比如hello作为一行数据,如果按照字节切分可能被切为 he,llo不完整了 读取数据的时候,还需要考虑数据的偏移量,偏移量从0开始 读取数据时,相同的偏移量不能重复读取 处理磁盘数据时,spark会对其进行分区,分区是通过字节来分的,比如说7个字节的数据,最小分区数为2,则分为3 3 1 三个分区。 而在读取数据的时候是根据偏移量,并且按行来读取的,只要读取到了一行的一个偏移量,那么就要将这一行的其他的偏移量都读取出来。
package com.zjjxy.bigdata.rdd.instance; import org.apache.spark.SparkConf; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.api.java.JavaSparkContext; public class Spark02_RDD_Disk_partition_datda { public static void main(String[] args) { SparkConf sparkConf = new SparkConf(); sparkConf.setMaster("local"); sparkConf.setAppName("spark"); sparkConf.set("spark.default.parallelism", "1"); JavaSparkContext jsc = new JavaSparkContext(sparkConf); /* totalsize =7 goalsize = totalsize/minpartnum = 7/2=3 partnum =totalsize /goalsize =7/3=2...1=2+1=3 */ final JavaRDD<String> rdd = jsc.textFile("src/main/resources/data/test.txt", 2); // TODO spark进行分区处理时,需要对每个分区的数据尽可能的平均。 // spark是不支持文件操作的,文件操作都是hadoop完成的,包括文件切片和写入切片 // Hadoop进行文件切分数量的计算和文件数据存储计算规则不一样 // 1.分区数量计算的时候,考虑的是尽可能的平均:按字节来计算 // 2.分区数据的存储考虑的是业务数据的完整性:按行来读取 // 读取数据的时候,还需要考虑数据的偏移量,偏移量从0开始 // 读取数据时,相同的偏移量不能重复读取 /* 下面是数据分区,一共有7个字符,minPartitions=2,所以分区数有3个,其中分区1,2存储3个字节,分区3存储1个字节 分区所存数据量=>计算分区的规则: [3]=>[0,3] [3]=>[3,6] [1]=>[6,1] ------------------- 数据=>偏移量: 1@@ =>012 2@@=>345 3=>6 ------------------- 读数据: 这里的[0,3]是偏移量,不是索引,所以是包含起始值的。所以读取的偏移量是0123,而偏移量3对应的数据值是2,hadoop读取数据是一行一行读取 2属于第二行,所以他会将第二行的其他数据也全部读取出来,所以读取的偏移量是012345。 [0,3]=>[1,2] [3,6]=>[3] [6,7]=> */ rdd.saveAsTextFile("out4"); jsc.close(); } }
案例:数据长度为19字节,最小分区数为3,计算有多少个分区,每个分区中的数据情况。
数据
1212 322 dfds 3s //长度为19个字节
计算分区
数据长度:19 最小分区数:3 每个分区的数据量:19/3=6 分区数:19/6=3...1 1/6>0.1 所以分区数为3+1=4
每个分区应该有的数据量
有4个分区,每个分区放6个字节,最后多出一个字节放在最后一个分区
[6]=>[0,6] [6]=>[6,12] [6]=>[12,18] [1]=>[18,19] 数据应该是这种方式存储在这些分区上,但是因为要考虑数据的完整性,必须考虑偏移量,且一读读取一行,不能重复。
数据的偏移量 1212@@=>012345 322@@=>6789 10 11 dfds@@=>12 13 14 15 16 17 3s@@=>18 19 20 21
实际读取的时候会参考到上面的分区数据,但并不完全按照,会将0,6以偏移量 的形式读取出来,且不能重复,一读读一行
[6]=>[0,6]=>[1212,322] [6]=>[6,12]=>[dfds] [6]=>[12,18]=>[3s] [1]=>[18,19]=>[] 所以最终的结果就是上面的
磁盘数据源的数据分配就是按照上面的逻辑来进行分的。注意的一点,所谓的切分并不是真正的将原始数据切开,而是读取的时候根据规则选择性的读取一部分,存储到不同的分区中。所以分区和数据是不同的,虽然叫做数据的切分。并不是数据切了几块就有几个分区,可能存在空的分区。而我们物理上的切分,就是将物体切成几块,并不存在切出空的情况。
注意:使用spark计算的时候数据不能全部放在一行,不然分区将没有任何意义