Spark整理(3)

Spark整理(3)

一,算子

1.1 转换算子
  • repartition

增加或减少分区,会产生shuffle

scala代码:

package com.shsxt.spark.scala

import org.apache.spark.{SparkConf, SparkContext}

object Sp_Repartition {

  def main(args: Array[String]): Unit = {

    val conf = new SparkConf()
    conf.setMaster("local").setAppName("Repartition")

    val sc = new SparkContext(conf)

    val rdd = sc.parallelize(Array(1,2,3),4)

    val result = rdd.repartition(6)

    println(result.partitions.length)  //输出6个,在控制台可以搜索到shuffle

    result.foreach(println)

  }

}

java代码:

package com.shsxt.spark.java;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.VoidFunction;
import scala.Tuple2;

import java.util.Arrays;

public class Ja_Repartition {

    public static void main(String args[]){

        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("zip");

        JavaSparkContext sc = new JavaSparkContext(conf);

        JavaRDD<String> rdd1 = sc.parallelize(Arrays.asList("i", "love", "you"),3);

        JavaRDD<String> rdd = rdd1.repartition(5);

        System.out.println(rdd.partitions().size());

        rdd.foreach(new VoidFunction<String>() {
            @Override
            public void call(String s) throws Exception {
                System.out.println(s);
            }
        });

        sc.stop();

    }
}
  • coalesce

常用来减少分区,第二个参数是减少分区的过程中是否产生shuffle。

true为产生shuffle, false不产生shuffle. 默认是false

如果coalesce设置的分区数比原来的RDD的分区数还多的话,第二个参数设置为false不会起作用。

coalesce第二个参数如果设置为true,则效果和repartition一样。

scala代码:

package com.shsxt.spark.scala

import org.apache.spark.{SparkConf, SparkContext}


object Sp_Coalesce {

  def main(args: Array[String]): Unit = {

    val conf = new SparkConf()
    conf.setMaster("local").setAppName("zip")

    val sc = new SparkContext(conf)

    val rdd = sc.parallelize(Array(1,2,3),4)


//    val rdd1 = rdd.coalesce(2,true)  和repartition效果一致
//    val rdd2  = rdd.coalesce(6,false) 增加分区,设置false 也是会产生shuffle
      val rdd1 = rdd.coalesce(2)

    println(rdd1.partitions.length)

    rdd1.foreach(println)
  }
}
  • groupByKey

作用在K,V格式上的RDD。根据Key进行分组。返回(K,iterable)

scala代码:

package com.shsxt.spark.scala

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}


object Sp_GroupByKey {


  def main(args: Array[String]): Unit = {

    val sparkConf = new SparkConf()
    sparkConf.setMaster("local").setAppName("cache")

    val sc = new SparkContext(sparkConf)

    val rdd1: RDD[(String, String)] = sc.parallelize(Array(
      new Tuple2("a","111"),
      new Tuple2("a","222"),
      new Tuple2("b","333"),
      new Tuple2("b","444"),
      new Tuple2("c","555"),
      new Tuple2("c","666"),
      new Tuple2("d","777")
    ))

    val result: RDD[(String, Iterable[String])] = rdd1.groupByKey(2)

    println(result.partitions.length)

    result.foreach(x=>{
      val list = x._2.toList
      list.foreach(y=>{
        println(x._1+"------------"+y)
      })
    })

    sc.stop()
  }
}
  • Zip

将两个RDD中的元素(KV/非KV格式)变成KV格式的RDD,两个RDD的个数必须相同

scala代码:

package com.shsxt.spark.scala

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}


object Sp_Zip {

  def main(args: Array[String]): Unit = {

    val conf = new SparkConf()
    conf.setMaster("local").setAppName("zip")

    val sc = new SparkContext(conf)

    val rdd1 = sc.parallelize(Array(1,2,3))
    val rdd2 = sc.parallelize(Array("a","b","c"))

    //rdd1.zip(rdd2).foreach(println)

    val rdd3: RDD[(String, String)] = sc.parallelize(Array(
      ("1","aaa"),
      ("2","bbb")
    ))

    val rdd4 = sc.parallelize(Array(
      (1,2),
      (5,10)
    ))

    val result: RDD[((String, String), (Int, Int))] = rdd3.zip(rdd4)

    result.foreach(println)


  }

}
  • zipWithIndex

该函数将RDD中的元素和这个元素在RDD中的索引号(从0开始)组成KV格式的RDD

scala代码:

package com.shsxt.spark.scala

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}


object Sp_ZipWithIndex {

  def main(args: Array[String]): Unit = {

    val conf = new SparkConf()
    conf.setMaster("local").setAppName("zip")

    val sc = new SparkContext(conf)


    val rdd3: RDD[(String, String)] = sc.parallelize(Array(
      ("1","aaa"),
      ("2","bbb")
    ),4)


    val result: RDD[((String, String), Long)] = rdd3.zipWithIndex()

    result.foreach(println)

    sc.stop()
  }

}
1.2 触发算子
  • countByKey

作用到KV格式的RDD上,根据Key计数相同Key的数据集元素

java代码:

package com.shsxt.spark.java;


import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaSparkContext;
import scala.Tuple2;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class Ja_CountByKey {

    public static void main(String args[]){

        SparkConf sparkConf = new SparkConf();
        sparkConf.setMaster("local").setAppName("intersection");

        JavaSparkContext sc = new JavaSparkContext(sparkConf);

        List<Tuple2<String, Integer>> list = Arrays.asList(
                new Tuple2<String, Integer>("a", 111),
                new Tuple2<String, Integer>("a", 222),
                new Tuple2<String, Integer>("a", 333),
                new Tuple2<String, Integer>("b", 55),
                new Tuple2<String, Integer>("b", 66),
                new Tuple2<String, Integer>("c", 7)
        );

        JavaPairRDD<String, Integer> javaPairRDD = sc.parallelizePairs(list);

        Map<String, Object> map = javaPairRDD.countByKey();

        for(String key : map.keySet()){

            System.out.println(key+"---->value:"+map.get(key));

        }

        sc.stop();

    }
}
  • countByValue

根据数据集每个元素相同的内容来计数。返回相同内容的元素对应的条数。

java代码:

package com.shsxt.spark.java;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaSparkContext;
import scala.Tuple2;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class Ja_CountByValue {

    public static void main(String args[]){

        SparkConf sparkConf = new SparkConf();
        sparkConf.setMaster("local").setAppName("intersection");

        JavaSparkContext sc = new JavaSparkContext(sparkConf);

        List<Tuple2<String, Integer>> list = Arrays.asList(
                new Tuple2<String, Integer>("a", 222),
                new Tuple2<String, Integer>("a", 222),
                new Tuple2<String, Integer>("a", 222),
                new Tuple2<String, Integer>("b", 55),
                new Tuple2<String, Integer>("b", 55),
                new Tuple2<String, Integer>("c", 7)
        );

        JavaPairRDD<String, Integer> javaPairRDD = sc.parallelizePairs(list);

        Map<Tuple2<String, Integer>, Long> map = javaPairRDD.countByValue();

        for(Tuple2 key : map.keySet()){

            System.out.println(key+"---->value:"+map.get(key));

        }

        sc.stop();

    }
}
  • reduce

根据聚合逻辑聚合数据集中的每个元素

scala代码:

package com.shsxt.spark.scala

import org.apache.spark.{SparkConf, SparkContext}


object Sp_Reduce {

  def main(args: Array[String]): Unit = {

    val sparkConf = new SparkConf()
    sparkConf.setMaster("local").setAppName("union")

    val sc = new SparkContext(sparkConf)

    val rdd1 = sc.parallelize(Array(1,2,3))

    val i: Int = rdd1.reduce(_+_)

    println(i)

  }

}

二,相关计算案例

2.1 PV,UV

统计网站 pv 和 uv

PV 是网站分析的一个术语,用以衡量网站用户访问的网页的数量。对于广告主,PV 值可预期它可以带来多少广告收入。一般来说,PV 与来访者的数量成正比,但是 PV 并不直接决定页面的真实来访者数量,如同一个来访者通过不断的刷新页面,也可以制造出非常高的 PV。

什么是PV?

PV(page view)即页面浏览量或点击量,是衡量一个网站或网页用户访问量。具体的说,PV 值就是所有访问者在 24 小时(0 点到 24 点)内看了某个网站多少个页面或某个网页多少次。PV 是指页面刷新的次数,每一次页面刷新,就算做一次 PV 流量。度量方法就是从浏览器发出一个对网络服务器的请求(Request),网络服务器接到这个请求后,会将该请求对应的一个网页(Page)发送给浏览器,从而产生了一个 PV。那么在这里只要是这个请求发送给了浏览器,无论这个页面是否完全打开(下载完成),那么都是应当计为 1 个 PV。

什么是UV?

UV(unique visitor)即独立访客数,指访问某个站点或点击某个网页的不同 IP 地址的人数。在同一天内,UV 只记录第一次进入网站的具有独立IP 的访问者,在同一天内再次访问该网站则不计数。UV 提供了一定时间内不同观众数量的统计指标,而没有反应出网站的全面活动.

准备数据,数据格式如下:
在这里插入图片描述

  • 统计网站PV

1.读取文件数据

2.取出文件中的url,映射关系为-> <url,1>

3.相同key聚合数量,按照数量排序输出即可

java代码:

package com.shsxt.spark.java;


import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.api.java.function.VoidFunction;
import scala.Tuple2;

public class Ja_PV {

    public static void main(String args[]){

        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("zip");

        JavaSparkContext sc = new JavaSparkContext(conf);

        JavaRDD<String> linesRDD = sc.textFile("./data/pvuvdata");

        JavaPairRDD<String, Integer> mapRDD = linesRDD.mapToPair(new PairFunction<String, String, Integer>() {
            @Override
            public Tuple2<String, Integer> call(String s) throws Exception {
                return new Tuple2<>(s.split("\t")[5], 1);
            }
        });

        JavaPairRDD<String, Integer> reduceRDD = mapRDD.reduceByKey(new Function2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer v1, Integer v2) throws Exception {
                return v1 + v2;
            }
        });

        reduceRDD.foreach(new VoidFunction<Tuple2<String, Integer>>() {
            @Override
            public void call(Tuple2<String, Integer> tuple2) throws Exception {
                System.out.println(tuple2);
            }
        });

        sc.stop();

    }
}

scala代码:

package com.shsxt.spark.scala

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}


object Sp_PV {

  def main(args: Array[String]): Unit = {

    val sparkConf = new SparkConf()
    sparkConf.setMaster("local").setAppName("union")
	
    val sc = new SparkContext(sparkConf)
      
	//读取数据
    val linesRDD: RDD[String] = sc.textFile("./data/pvuvdata")
	//转化数据集格式
    val mapRDD: RDD[(String, Int)] = linesRDD.map(x=>{
      Tuple2(x.split("\t")(5),1)
    })
	//聚合排序,遍历输出
    mapRDD.reduceByKey(_+_).sortBy(x=>x._2,false).foreach(println)

    sc.stop()
  }

}
  • UV

1.读取文件数据

2.取出文件中的url和ip,映射关系为-> <url,Ip>

3.根据key分组,聚合Ip,对ip去重,取数量即为UV

java代码:

package com.shsxt.spark.java;


import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.api.java.function.VoidFunction;
import scala.Tuple2;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Ja_UV {

    public static void main(String args[]){

        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("zip");

        JavaSparkContext sc = new JavaSparkContext(conf);

        JavaRDD<String> linesRDD = sc.textFile("./data/pvuvdata");

        JavaPairRDD<String, String> mapRDD = linesRDD.mapToPair(new PairFunction<String, String, String>() {
            @Override
            public Tuple2<String, String> call(String s) throws Exception {
                return new Tuple2<>(s.split("\t")[5], s.split("\t")[0]);
            }
        });

        mapRDD.groupByKey().foreach(new VoidFunction<Tuple2<String, Iterable<String>>>() {
            @Override
            public void call(Tuple2<String, Iterable<String>> tuple2) throws Exception {

                Iterator<String> iterator = tuple2._2().iterator();

                Set set = new HashSet();

                while (iterator.hasNext()){
                    set.add(iterator.next());
                }

                System.out.println(tuple2._1 +"=========="+set.size());


            }
        });

    }
}

scala代码:

package com.shsxt.spark.scala

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Sp_UV {

  def main(args: Array[String]): Unit = {

    val sparkConf = new SparkConf()
    sparkConf.setMaster("local").setAppName("union")

    val sc = new SparkContext(sparkConf)

    val linesRDD: RDD[String] = sc.textFile("./data/pvuvdata")

//    val countRDD = linesRDD.map(x=>{
//      Tuple2(x.split("\t")(5),x.split("\t")(0))
//    }).distinct().map(x=>(x._1,1)).countByKey()
//
//    countRDD.foreach(println)

    val result: RDD[(String, Iterable[String])] = linesRDD.map(x => {
      val fields = x.split("\t")
      (fields(5), fields(0))
    }).groupByKey()

    result.foreach(x => {
      val key = x._1
      val iteratable = x._2

      println("key : " + key + " size : " + iteratable.toSet.size)
    })

  }

}
2.2 二次排序

对于一些数据,默认的排序后无法满足我们所需要的结果,这时候我们可以自定义排序规则来实现,这就叫二次排序(自定义key)。

数据格式:
在这里插入图片描述

自定义排序key的java类

SecondSortKey.java

package com.shsxt.spark.java;

import java.io.Serializable;

//和MapReduce的两次排序一样,自定义排序类 需要实现 序列化接口和 Comparable比较器
public class SecondSortKey implements Serializable,Comparable<SecondSortKey> {

    private Integer first;
    private Integer second;

    public SecondSortKey(Integer first,Integer second){
        this.first = first;
        this.second = second;
    }

    public int getFirst() {
        return first;
    }
    public void setFirst(int first) {
        this.first = first;
    }


    public int getSecond() {
        return second;
    }
    public void setSecond(int second) {
        this.second = second;
    }

	//最重要的是这个方法
    @Override
    public int compareTo(SecondSortKey o) {
       //第一个相同,比较第二个数字的大小
        if (this.getFirst()==o.getFirst()){

            return this.getSecond()-o.getSecond();

        }else {
            return this.getFirst()-o.getFirst();
        }

    }
}

java代码:

package com.shsxt.spark.java;


import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.api.java.function.VoidFunction;
import scala.Tuple2;

public class Ja_SecondSort {

    public static void main(String args[]){

        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("secondSort");

        JavaSparkContext sc = new JavaSparkContext(conf);

        JavaRDD<String> linesRDD = sc.textFile("./data/secondSort.txt");

        JavaPairRDD<SecondSortKey, Integer> pairRDD = linesRDD.mapToPair(new PairFunction<String, SecondSortKey, Integer>() {

            @Override
            public Tuple2<SecondSortKey, Integer> call(String s) throws Exception {
                Integer first = Integer.valueOf(s.split(" ")[0]);
                Integer second = Integer.valueOf(s.split(" ")[1]);
                //构建 KV形式的 数据集 框架运行时会自动调用 自动Key中的排序方法 compareTo
                Tuple2<SecondSortKey, Integer> tuple2 = new Tuple2<>(new SecondSortKey(first, second), 1);

                return tuple2;
            }
        });
                pairRDD.sortByKey(false).foreach(new VoidFunction<Tuple2<SecondSortKey, Integer>>() {
                    @Override
                    public void call(Tuple2<SecondSortKey, Integer> tuple2) throws Exception {
                        System.out.println(tuple2._1.getFirst()+"----"+tuple2._1.getSecond());
                    }
                });


    }
}

scala代码:

package com.shsxt.spark.scala

import com.shsxt.spark.java.SecondSortKey
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}




object Sp_SecondSort {

  def main(args: Array[String]): Unit = {

    val conf = new SparkConf()
    conf.setMaster("local").setAppName("secondSort")

    val sc = new SparkContext(conf)

    val linesRDD = sc.textFile("./data/secondSort.txt")

//    val rdd1 = sc.parallelize(Array(1,2,3))
//
//    //rdd1.sortBy()
//    val rdd2: RDD[(Int, Int)] = rdd1.map(x=>(x,1))
//
    rdd2.sortBy()

    linesRDD.map(x=>{
      new Tuple2(new SecondSortKey(Integer.valueOf(x.split(" ")(0)),Integer.valueOf(x.split(" ")(1))),1)
    }).sortByKey(false).foreach(x=>{
      println(x._1.getFirst+"----"+x._1.getSecond)
    })

  }

}
2.3 分组取topN

数据如下:
在这里插入图片描述

1.读取数据

2.处理数据,KV形式的数据

3.按照key分组,取每组前三个分数最高的

java代码:

package com.shsxt.spark.java;


import org.apache.commons.collections.IteratorUtils;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.api.java.function.VoidFunction;
import scala.Tuple2;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class Ja_TopN {

    public static void main(String args[]){

        SparkConf sparkConf = new SparkConf();
        sparkConf.setMaster("local").setAppName("topN");

        JavaSparkContext sc = new JavaSparkContext(sparkConf);

        JavaRDD<String> linesRDD = sc.textFile("./data/scores.txt");

        JavaPairRDD<String, Integer> pairRDD = linesRDD.mapToPair(new PairFunction<String, String, Integer>() {
            @Override
            public Tuple2<String, Integer> call(String s) throws Exception {

                String s1 = s.split(" ")[0];
                Integer s2 = Integer.valueOf(s.split(" ")[1]);

                return new Tuple2<>(s1, s2);
            }
        });

        JavaPairRDD<String, Iterable<Integer>> groupRDD = pairRDD.groupByKey();
		
        
        //这种方式将数据全部放入list中,数据量大,可能造成内存OOM
//        groupRDD.foreach(new VoidFunction<Tuple2<String, Iterable<Integer>>>() {
//            @Override
//            public void call(Tuple2<String, Iterable<Integer>> it) throws Exception {
//                Iterator<Integer> iterator = it._2.iterator();
//                List list  = IteratorUtils.toList(iterator);
//                Collections.sort(list);
//
//                for (int i = 0; i < Math.min(3,list.size()); i++) {
//                    System.out.println(it._1+"----"+list.get(list.size()-i-1));
//                }
//            }
//        });


		//这种方式较好,每次对一条数据拿取,再排序
        groupRDD.foreach(new VoidFunction<Tuple2<String, Iterable<Integer>>>() {
            @Override
            public void call(Tuple2<String, Iterable<Integer>> it) throws Exception {
                String key = it._1;
                Iterator<Integer> iterator = it._2.iterator();

                Integer [] top3 = new Integer[3];

                while (iterator.hasNext()){
                    Integer score = iterator.next();

                    for (int i = 0; i <top3.length; i++) {

                        if (top3[i]==null){
                            top3[i]=score;
                            break;
                        }else if (score>top3[i]){
                            for (int j = 2; j >i ; j--) {
                                top3[j] = top3[j-1];
                            }
                            top3[i] = score;
                            break;
                        }

                    }
                }

                for(Integer score : top3){
                    if (score!=null){
                        System.out.println(key+"---value:"+score);
                    }
                }

            }
        });

    }
}

scala代码

package com.shsxt.spark.scala

import org.apache.spark.{SparkConf, SparkContext}


object Sp_TopN {

  def main(args: Array[String]): Unit = {

    val conf = new SparkConf()
    conf.setMaster("local").setAppName("topN")

    val sc = new SparkContext(conf)

    val lineRDD = sc.textFile("./data/scores.txt")

    val groupRDD = lineRDD.map(x=> {
      new Tuple2(x.split(" ")(0), Integer.valueOf(x.split(" ")(1)))
    }).groupByKey()

    groupRDD.foreach(x=>{
      val key = x._1
      val it: Iterator[Integer] = x._2.iterator

      val arr: Array[Integer] = new Array[Integer](3)
//      println(arr.length)
//      println("===================")

      while(it.hasNext){
        var score = it.next()
        var falg = true

        for (i<- 0 until arr.length;if falg==true){
            if (arr(i)==null){
              arr(i) = score
              falg=false
            }else if (score>arr(i)){
              var j = 2
              while(j>i){
                arr(j)=arr(j-1)
                j = j-1
              }
              arr(i)=score
              falg=false
            }
        }

      }

      arr.foreach(x=>{
        if (x!=null){
          println(key+"--------value"+x)
        }

      })



    })
  }

}

三,Spark-Submit提交参数

Options
  • master

Master_URL,可以是 spark://host:port , mesos://host:port , yarn , yarn-cluster , yarn-client , local

  • deploy-mode

Deploy_Mode,Driver程序运行的地方,client或者cluster,默认是client

  • class

CLASS_NAME 主类名称,含包名

  • jars

逗号分隔的本地JARS,Driver和exector依赖的第三方jar包

  • files

用逗号隔开的文件列表,放置在每个exector工作目录中

  • conf

spark的配置属性

  • driver-memory

Driver程序使用内存大小(例如: 1000M , 5G) ,默认1024M

  • exector-memory

每个exector内存大小(如:1000M,2G),默认1G

Spark standalone with cluster deploy mode only:

  • driver-cores

Driver程序的使用core个数(默认为1),仅限于Spark standalone模式

Spark standalone or Mesos with cluster deploy mode only

  • supervise

失败后是否重启Driver,仅限于Spark alone 或者 Mesos模式

Spark standalone and Mesos only

  • total-exector-cores

exector使用的总核数,仅限于Standalone Mesos模式

Spark standalone and yarn only

  • exector-cores

每个exector使用的core数,Spark on yarn默认为1,standalone默认为worker上所有可用的core数

Yarn only

  • driver-cores

driver使用的core,仅在cluster模式下,默认为1

  • queue

QUEUE_NAME 指定资源队列的名称 默认:default

  • num-exectors

一共启动的exector数量,默认是2个。

四,Spark shell

4.1 概念

SparkShell 是 Spark 自带的一个快速原型开发工具,也可以说是Spark 的 scala REPL(Read-Eval-Print-Loop),即交互式 shell。支持使用 scala 语言来进行 Spark 的交互式编程。

4.2 使用

启动standalone集群, ./start-all.sh

在客户端启动 spark-shell

./spark-shell --master spark://node01:7077

启动 hdfs,创建目录 spark/test,上传文件 wc.txt

启动hdfs集群: start-all.sh
创建目录: hdfs dfs -mkdir /spark
上传数据: wc.txt

运行wordCount

sc.textFile("hdfs://node01:8020/spark/wc.txt")
.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).foreach(println)

五,SparkUI

5.1 SparkUI界面介绍

可以指定提交Application的名称

./spark-shell  --master spark://node01:7077  --name myapp
5.2 配置historyServer
  • 临时配置,对本次提交的应用程序起作用
./spark-shell --master spark://node01:7077 
--name myapp1
--conf spark.eventLog.enabled=true
--conf spark.eventLog.dir=hdfs://node01:8020/spark

停止程序,在 Web Ui 中 Completed Applications 对应的ApplicationID 中能查看 history

  • 永久配置

在客户端节点,进入conf目录下 spark-default.conf中 最后加入:

//开启记录事件日志的功能
spark.eventLog.enabled  true
//设置事件日志存储的目录
spark.eventLog.dir  hdfs://node01:8020/spark
//设置 HistoryServer 加载事件日志的位置
spark.history.fs.logDirectory hdfs://node01:8020/spark
  • 启动HistoryServer
sbin目录下  ./start-history-server.sh 

访问 HistoryServer:node01:18080,之后所有提交的应用程序运行状况都会被记录。

六,Master HA

6.1 Master的高可用原理

Standalone 集群只有一个 Master,如果 Master 挂了就无法提交应用程序,需要给 Master 进行高可用配置,Master 的高可用可以使用**fileSystem(文件系统)**和 zookeeper(分布式协调服务)

  • fileSystem

fileSystem 只有存储功能,可以存储 Master 的元数据信息,用fileSystem 搭建的 Master 高可用,在 Master 失败时,需要我们手动启动另外的备用 Master,这种方式不推荐使用。

  • zookeeper

zookeeper 有选举和存储功能,可以存储 Master 的元素据信息,使用zookeeper 搭建的 Master 高可用,当 Master 挂掉时,备用的 Master会自动切换,推荐使用这种方式搭建 Master 的 HA。
在这里插入图片描述

6.2 Master高可用搭建
  • 在Spark Master节点上配置主Master,配置spark-env.sh
    在这里插入图片描述

  • 发送到其他worker节点上

scp spark-env.sh node02:`pwd`
  • 找一台节点(非主Master节点)配置备用Master,修改spark-env.sh 配置节点的MasterIP
    在这里插入图片描述

我这边是node02,节点的ip为 192.168.150.102

  • 启动集群之间启动zookeeper集群
zkServer.sh start
  • 启动spark standalone集群,启动备用Master(在备用节点输入命令)
主节点sbin目录下: ./start-all.sh
备用节点sbin目录下:  ./start-master.sh 
  • 查看WEB页面的从主状态

  • 注意

1.主备切换过程中不能提交Application

2.主备切换过程中不影响已经在集群中运行的Application。因为Spark是组粒度申请资源

  • 测试HA

kill掉主的Master,观察备用Master是否切换状态到Active状态(切换速度比HDFS的HA慢)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hadoop和Spark是大数据处理领域中最流行的两个框架。以下是它们的知识点整理汇总: Hadoop: 1. Hadoop是一个开源的分布式计算框架,用于存储和处理大规模数据集。 2. Hadoop包括两个核心组件:HDFS(Hadoop分布式文件系统)和MapReduce(分布式计算框架)。 3. HDFS是一个分布式文件系统,用于存储大规模数据集。它将数据分成块并存储在不同的节点上,以实现数据的高可靠性和可扩展性。 4. MapReduce是一种分布式计算框架,用于处理大规模数据集。它将数据分成小块并在不同的节点上并行处理,以实现高效的数据处理。 5. Hadoop还包括其他组件,如YARN(资源管理器)和HBase(分布式NoSQL数据库)。 Spark: 1. Spark是一个快速、通用、可扩展的分布式计算框架,用于处理大规模数据集。 2. Spark的核心组件是Spark Core,它提供了分布式任务调度、内存计算和数据处理功能。 3. Spark还包括其他组件,如Spark SQL(用于结构化数据处理)、Spark Streaming(用于实时数据处理)和MLlib(用于机器学习)。 4. Spark使用RDD(弹性分布式数据集)作为其基本数据结构,它是一个可分区、可并行计算和可恢复的数据集合。 5. Spark支持多种编程语言,如Scala、Java、Python和R。 总结: Hadoop和Spark都是用于处理大规模数据集的分布式计算框架,它们有不同的核心组件和特点。Hadoop主要用于存储和处理大规模数据集,而Spark则更加注重数据处理的速度和效率。在实际应用中,可以根据具体需求选择合适的框架。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值