Spark中的Wordcount
阅读原文时间:2023年07月10日阅读:1

目录

通过scala语言基于local编写spark的Wordcount

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

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

    // Spark配置文件对象
    val conf: SparkConf = new SparkConf()

    // 设置Spark程序的名字
    conf.setAppName("WordCount")

    // 设置运行模式为local模式 即在idea本地运行
    // local : 一个并行度
    // local[2] : 两个并行度
    // local[*] : 有多少用多少
    conf.setMaster("local")

    // Spark的上下文环境,相当于Spark的入口
    val sc: SparkContext = new SparkContext(conf)

    // 词频统计
    // 1、读取文件
    /**
      * RDD : 弹性分布式数据集(可以先当成scala中的集合去使用)
      */
    val linesRDD: RDD[String] = sc.textFile("scala/data/words.txt")

    // 2、将每一行的单词切分出来
    // flatMap: 在Spark中称为 算子
    // 算子一般情况下都会返回另外一个新的RDD
    val wordsRDD: RDD[String] = linesRDD.flatMap(kv=>kv.split(","))

    // 3、按照单词分组
    val groupRDD: RDD[(String, Iterable[String])] = wordsRDD.groupBy(kv=>kv)

    // 4、统计每个单词的数量
    val countRDD: RDD[String] = groupRDD.map(kv => {
      val key: String = kv._1
      val values: Iterable[String] = kv._2

      // words.size直接获取迭代器的大小
      // 因为相同分组的所有的单词都会到迭代器中
      // 所以迭代器的大小就是单词的数量
      val size: Int = values.size
      key + "," + size
    })

    countRDD.saveAsTextFile("spark/data/wordcount.txt")

  }

}

会报这个错

解决方案:

新建一个文件夹,放入这个文件

配置环境变量

需要导入的依赖

<dependencies>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>2.4.5</version>
        </dependency>

        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.11.12</version>
        </dependency>

        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-compiler</artifactId>
            <version>2.11.12</version>
        </dependency>

        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-reflect</artifactId>
            <version>2.11.12</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <!-- Java Compiler -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <!-- Scala Compiler -->
            <plugin>
                <groupId>org.scala-tools</groupId>
                <artifactId>maven-scala-plugin</artifactId>
                <version>2.15.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

基于yarn去调度WordCount

import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.{FileSystem, Path}
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

/**
  * 1、去除setMaster("local")
  * 2、修改文件的输入输出路径(因为提交到集群默认是从HDFS获取数据,需要改成HDFS中的路径)
  * 3、在HDFS中创建目录
  * hdfs dfs -mkdir -p /spark/data/words/
  * 4、将数据上传至HDFS
  * hdfs dfs -put words.txt /spark/data/words/
  * 5、将程序打成jar包
  * 6、将jar包上传至虚拟机,然后通过spark-submit提交任务
  * spark-submit --class WordCount2 --master yarn-client spark-1.0.jar
  * spark-submit --class WordCount2 --master yarn-cluster spark-1.0.jar
  */
object WordCount2 {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("WordCount2")
    val sc: SparkContext = new SparkContext(conf)

    val linesRDD: RDD[String] = sc.textFile("/spark/data/words")
    val wordsRDD: RDD[String] = linesRDD.flatMap(s=>s.split(","))
    val groupRDD: RDD[(String, Iterable[String])] = wordsRDD.groupBy(s=>s)
    val resRDD: RDD[String] = groupRDD.map(kv => {
      kv._1 + "," + kv._2.size

    })

    // 使用HDFS的JAVA API判断输出路径是否已经存在,存在即删除
    val conff: Configuration = new Configuration()
    // core-site.xml
    conff.set("fs.defaultFS", "hdfs://master:9000")
    val sys = FileSystem.get(conff)

    if (sys.exists(new Path("/spark/data/wordcount"))){
      sys.delete(new Path("/spark/data/wordcount"),true)
    }

    resRDD.saveAsTextFile("/spark/data/wordcount")

  }

}

打成jar包去运行

默认会有两个分区Task

可以通过sc.textFile(Path,分区个数)

on yarn的两种模式

yarn client模式:driverzai当前提交任务的节点上,可以打印任务运行的日志信息,而

yarn cluster模式:driver在AppMaster所有节点上,分布式分配,不能再提交任务的本机打印日志信息