Spark第三课

1.分区规则

1.分区规则

shuffle

1.打乱顺序

2.重新组合

1.分区的规则

默认与MapReduce的规则一致,都是按照哈希值取余进行分配.

一个分区可以多个组,一个组的数据必须一个分区

2. 分组的分区导致数据倾斜怎么解决?

  • 扩容 让分区变多
  • 修改分区规则

3.HashMap扩容为什么必须是2的倍数?

当不是2的倍数时, 好多的位置取不到

比如 为5 01234 123都取不到

必须保证,相关的位数全是1,所以必定2的倍数 2的n次方

所以位运算不是什么时候都能用的

2.转换算子

1.单值转换算子

1.filter过滤器

1.注意

过滤只是将数据进行校验,而不是修改数据. 结果为true就保留,false就丢弃

2.代码

java 复制代码
JavaSparkContext sc = new JavaSparkContext("local[*]","filter");

List<String> dataList = Arrays.asList("giao","giao2","zhangsan","lisi");
JavaRDD<String> rdd1 = sc.parallelize(dataList);
//JavaRDD<String> rddFilter1 = rdd1.filter(null);
JavaRDD<String>  rddFilter2= rdd1.filter(s->s.substring(0,1).toLowerCase().equals("g"));
//rddFilter1.collect().forEach(System.out::println);
System.out.println("----------------------------");
rddFilter2.collect().forEach(System.out::println);

2.dinstinct

1.原理

分组

通过使用分组取重,相同的话,都是一个组了,所以Key唯一

应该是先分组,然后吧K提出来就好了

2.代码

java 复制代码
JavaSparkContext sc = new JavaSparkContext("local[*]","Distinct");

List<String> dataList = Arrays.asList("giao1","gg1","gg1","gg2","gg2","gg1","gg3","gg1","gg5","gg3");
JavaRDD<String> rdd1 = sc.parallelize(dataList);
JavaRDD<String> rddDistinct = rdd1.distinct();
rddDistinct.collect().forEach(System.out::println);

3.排序

1.介绍

sortby方法需要传3个参数

参数1 排序规则

参数2 升序还是降序(false) 默认升序(true)

参数3 排序的分区数量(说明方法底层是靠shuffle实现,所以才有改变分区的能力)

2.排序规则

排序规则,是按照结果去排序

其实是用结果生成一个K值,通过K值进行排序,然后展示 V值

或者说权值, 按照权值排序

将Value变成K V

3.代码

java 复制代码
 public static void main(String[] args) {
        JavaSparkContext sc = new JavaSparkContext("local[*]","SparkSort");
        List<String> dataList = Arrays.asList("kunkun","giaogiao","GSD","JJ","chenzhen","Lixiaolong");
        JavaRDD<String> rdd1 = sc.parallelize(dataList);
        JavaRDD<String> rddSort = rdd1.sortBy(s -> {
            switch (s.substring(0, 1).toLowerCase()) {
                case "k":
                    return 5;
                case "g":
                    return 3;
                case "j":
                    return 1;
                case "c":
                    return 2;
                case "l":
                    return 4;

            }
            return null;
        }, false, 3);
        rddSort.collect().forEach(System.out::println);

    }

2.键值对转换算子

1.介绍

1.什么是键值对转换算子

如何区分是键值对方法还是单值方法呢?

通过参数来判断, 如果参数是一个值,就是单值,如果是2个,就是键值对

2.元组是不是键值对?

java 复制代码
public static void main(String[] args) {
    JavaSparkContext sc = new JavaSparkContext("local[*]","KVRDD");
    List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5);
    JavaRDD<Integer> rdd1 = sc.parallelize(dataList);
    JavaRDD<Tuple2> rddmap = rdd1.map(num -> new Tuple2(num, num));
    rddmap.collect().forEach(System.out::println);
}

答案是,不是,因为这个的返回值,是一个元组,而元组整体,是一个单值,所以,是单值

只有返回值 是RDD<K1,V1 >的时候,才是键值对类型算子

3. 使用Pair转换键值对算子

java 复制代码
public static void main(String[] args) {
    JavaSparkContext sc  = new JavaSparkContext("local[*]","RddPair");
    List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5);
    JavaRDD<Integer> rdd = sc.parallelize(dataList);
    JavaPairRDD<Integer, Integer> rddPair = rdd.mapToPair(num -> new Tuple2<>(num, num));
    rddPair.collect().forEach(System.out::println);

}

4.直接在获取时转换键值对

这里使用的是parallelizePairs方法 获取的是JavaPairRDD

java 复制代码
public static void main(String[] args) {
    JavaSparkContext sc = new JavaSparkContext("local[*]","KVRDD");
    JavaPairRDD<String, Integer> rddPair = sc.parallelizePairs(Arrays.asList(
            new Tuple2<>("a", 1),
            new Tuple2<>("a", 2),
            new Tuple2<>("b", 1),
            new Tuple2<>("b", 1),
            new Tuple2<>("c", 2),
            new Tuple2<>("c", 1)
    ));
    rddPair.collect().forEach(System.out::println);

}

5.分组来获取键值对

javascript 复制代码
```java
public static void main(String[] args) {
    JavaSparkContext sc  = new JavaSparkContext("local[*]","RddPair");
    List<String> dataList = Arrays.asList("aa","bb","aa","bb","cc");
    JavaRDD<String> rdd = sc.parallelize(dataList);
    JavaPairRDD<Object, Iterable<String>> rddGroup = rdd.groupBy(s->s);
    rddGroup.collect().forEach(System.out::println);
}

2.mapValue方法

1.介绍

直接对value进行操作,不需要管K

当然,也有mapKey方法可以无视Value操作Key

2.代码演示

java 复制代码
  public static void main(String[] args) {
        JavaSparkContext sc = new JavaSparkContext("local[*]","KVRDD");
        JavaPairRDD<String, Integer> rddPair = sc.parallelizePairs(Arrays.asList(
                new Tuple2<>("a", 1),
                new Tuple2<>("a", 2),
                new Tuple2<>("b", 1),
                new Tuple2<>("b", 1),
                new Tuple2<>("c", 2),
                new Tuple2<>("c", 1)
        ));
        JavaPairRDD<String, Integer> mapV = rddPair.mapValues(num -> num * 2);
        mapV.collect().forEach(System.out::println);

    }

3.WordCount实现

iter.spliterator().estimateSize());

spliterator

Spliterator(Split Iterator)是Java 8引入的一个新接口,用于支持并行遍历和操作数据。它是Iterator的扩展,可以用于在并行流(Parallel Stream)中对数据进行划分和遍历,从而实现更高效的并行处理

spliterator()方法是在Iterable接口中定义的一个默认方法,用于生成一个Spliterator对象,以支持数据的并行遍历。它的具体作用是将Iterable中的数据转换为一个可以在并行流中使用的Spliterator对象。

estimateSize

estimateSize()方法是Java中Spliterator接口的一个方法,用于估算Spliterator所包含的元素数量的大小。Spliterator是用于支持并行遍历和操作数据的接口,而estimateSize()方法提供了一个估计值,用于在处理数据时预测Spliterator包含的元素数量。

java 复制代码
public static void main(String[] args) {
    JavaSparkContext sc  = new JavaSparkContext("local[*]","RddPair");
    List<String> dataList = Arrays.asList("aa","bb","aa","bb","cc");
    JavaRDD<String> rdd = sc.parallelize(dataList);
    JavaPairRDD<Object, Iterable<String>> rddGroup = rdd.groupBy(s->s);
    JavaPairRDD<Object, Long> wordCount = rddGroup.mapValues(iter -> iter.spliterator().estimateSize());
    wordCount.collect().forEach(System.out::println);
}

3.groupby 与groupByKey

1 .代码

java 复制代码
public static void main(String[] args) {
    JavaSparkContext sc = new JavaSparkContext("local[*]","G1");
    JavaPairRDD<String, Integer> rddPair;
    rddPair = sc.parallelizePairs(Arrays.asList(
            new Tuple2<>("a", 1),
            new Tuple2<>("a", 2),
            new Tuple2<>("b", 1),
            new Tuple2<>("b", 1),
            new Tuple2<>("c", 2),
            new Tuple2<>("c", 1)
    ));
    JavaPairRDD<String, Iterable<Integer>> rddGroupByKey = rddPair.groupByKey();
    JavaPairRDD<String, Iterable<Tuple2<String, Integer>>> rddGroupBy = rddPair.groupBy(t -> t._1);
    rddGroupByKey.collect().forEach(System.out::println);

}

2.分析区别

  • 1.参数
    GroupBy是自选规则 而GroupByKey是将PairRDD的Key当做分组规则
  • 2.结果
    GroupBy是将作为单值去分组,即使RDD是Pair, 而GroupByKey 则是将K V分开 ,将V作为组成员

3.注意

GroupByKey是不能进行随意使用的,底层用的含有shuffle,如果计算平均值,就不能通过GroupByKey直接进行计算.

4.reduce与reduceByKey

1.介绍

多个变量进行同样的运算规则

Stream是1.8新特性,

计算的本质 两两结合

reduce

2. 代码

java 复制代码
  public static void main(String[] args) {
        JavaSparkContext sc = new JavaSparkContext("local[*]","Reduce");
        JavaPairRDD<String, Integer> rddPair;
        rddPair = sc.parallelizePairs(Arrays.asList(
                new Tuple2<>("a", 1),
                new Tuple2<>("a", 2),
                new Tuple2<>("b", 1),
                new Tuple2<>("b", 1),
                new Tuple2<>("c", 2),
                new Tuple2<>("c", 1)
        ));
        
        rddPair.reduceByKey(Integer::sum).collect().forEach(System.out::println);
    }

3.理解

相同Key值的V进行运算,所以底层是有分组的,所以底层是一定有Shuffle,一定有改变分区的能力,改变分区数量和分区规则.

4.与groupByKey区别

reduceByKey

将相同key的数量中1的V进行两两聚合

reduceByKey 相同的key两两聚合,在shuffle落盘之前对分区内数据进行聚合,这样会减少落盘数据量,并不会影响最终结果(预聚合) 这就是combine

有钱先整IBM小型机

Shuffle优化

1.花钱

2.调大缓冲区(溢出次数减少)

sortByKey

想比较必须实现可比较的接口

默认排序规则为升序,

通过K对键值对进行排序

行动算子

通过调用RDD方法让Spark的功能行动起来

map 是在new

转换算子 得到的是RDD

注意 转换跑不起来 行动能跑起来 这句话是错误的

当使用sort时,也是能跑起来的,但是还是转换算子

第一行运行占用内存,第一个for 运算需要内存,但是第一行占用了大量内存,所以第一行浪费了,这就需要懒加载,所以第一行的执行时机是在第二个for运行前使用的.

注意map collect 不是懒加载,只是没人调用他的job(RDD算子内部的代码)

RDD算子外部的代码都是在Driver端

相关推荐
用户3610588626121 小时前
Spark 核心之任务调度角色划分以及资源调度角色划分详解
大数据·spark
用户36105886261221 小时前
Spark 核心之 Stage 并行度划分及优化详解
spark
用户3610588626121 天前
Spark 核心之 Stage 切分划分与计算模式详解
spark
用户3610588626122 天前
Spark 核心之 RDD 窄依赖与宽依赖详解
spark
用户3610588626122 天前
Spark 核心之 Stage 和 Task 原理剖析
spark
java1234_小锋2 天前
【免费】基于Spark实时医疗健康数据监测与疾病预测系统(Java版本+可视化大屏+Kafka+SpringBoot+Vue3) 锋哥原创出品,必属精品
大数据·spark·kafka·实时医疗健康数据监测·实时疾病预测系统
腾讯云大数据2 天前
腾讯云智能数据湖计算AI DLC发布会回顾:Spark+Ray一体化,面向Agent重构数据底座
人工智能·spark·腾讯云
用户3610588626123 天前
Spark 核心之 Application 和 Job 原理剖析
spark
阿里云大数据AI技术4 天前
EMR Serverless Spark AI Function 的双维降本实践
人工智能·sql·spark