Spark第一個程序開發 wordcount

這裏介紹了程序運行在本地模式和Standalone模式兩種方式

Scala

package com.spark.app

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

/**
  * Created by Administrator on 2016/7/24 0024.
  */
object WordCount {
  def main(args: Array[String]) {
    /**
      * 第1步;創建Spark的配置對象SparkConf,設置Spark程序運行時的配置信息
      * 例如 setAppName用來設置應用程序的名稱,在程序運行的監控界面可以看到該名稱,
      * setMaster設置程序運行在本地還是運行在集羣中,運行在本地可是使用local參數,也可以使用local[K]/local[*],
      * 可以去spark官網查看它們不同的意義。 如果要運行在集羣中,以Standalone模式運行的話,需要使用spark://HOST:PORT
      * 的形式指定master的IP和端口號,默認是7077
      */
    val conf = new SparkConf().setAppName("WordCount").setMaster("local")
//  val conf = new SparkConf().setAppName("WordCount").setMaster("spark://master:7077")  // 運行在集羣中

    /**
      * 第2步:創建SparkContext 對象
      * SparkContext是Spark程序所有功能的唯一入口
      * SparkContext核心作用: 初始化Spark應用程序運行所需要的核心組件,包括DAGScheduler、TaskScheduler、SchedulerBackend
      * 同時還會負責Spark程序往Master註冊程序
      *
      * 通過傳入SparkConf實例來定製Spark運行的具體參數和配置信息
      */
    val sc = new SparkContext(conf)

    /**
      * 第3步: 根據具體的數據來源(HDFS、 HBase、Local FS、DB、 S3等)通過SparkContext來創建RDD
      * RDD 的創建基本有三種方式: 根據外部的數據來源(例如HDFS)、根據Scala集合使用SparkContext的parallelize方法、
      * 由其他的RDD操作產生
      * 數據會被RDD劃分成爲一系列的Partitions,分配到每個Partition的數據屬於一個Task的處理範疇
      */

    val lines = sc.textFile("D:/resources/README.md")   // 讀取本地文件
//  val lines = sc.textFile("/library/wordcount/input")   // 讀取HDFS文件,並切分成不同的Partition
//  val lines = sc.textFile("hdfs://master:9000/libarary/wordcount/input")  // 或者明確指明是從HDFS上獲取數據

    /**
      * 第4步: 對初始的RDD進行Transformation級別的處理,例如 map、filter等高階函數來進行具體的數據計算
      */
    val words = lines.flatMap(_.split(" ")).filter(word => word != " ")  // 拆分單詞,並過濾掉空格,當然還可以繼續進行過濾,如去掉標點符號

    val pairs = words.map(word => (word, 1))  // 在單詞拆分的基礎上對每個單詞實例計數爲1, 也就是 word => (word, 1)

    val wordscount = pairs.reduceByKey(_ + _)  // 在每個單詞實例計數爲1的基礎之上統計每個單詞在文件中出現的總次數, 即key相同的value相加
//  val wordscount = pairs.reduceByKey((v1, v2) => v1 + v2)  // 等同於

    wordscount.collect.foreach(println)  // 打印結果,使用collect會將集羣中的數據收集到當前運行drive的機器上,需要保證單臺機器能放得下所有數據

    sc.stop()   // 釋放資源

  }
}

如果運行在集羣中,需要將程序打包成jar包,使用spark提供的spark-submit提交到集羣

spark-submit --class com.spark.app.WordCount  --master spark://master:7077  /root/Documents/SparkApps/wordcount.jar

–class: 應用入口類(例如:org.apache.spark.examples.SparkPi
))
–master: 集羣的master URL (如:spark://23.195.26.187:7077)

更多提交時設置的內容可以參考Spark官方文檔http://spark.apache.org/docs/latest/submitting-applications.html


通過sortByKey方法對單詞出現的次序進行排序:

package com.spark.app

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

/**
  * Created by Administrator on 2016/7/24 0024.
  */
object WordCountSorted {
  def main(args: Array[String]) {
    def conf = new SparkConf().setAppName("WordCountSorted").setMaster("local")
    def sc = new SparkContext(conf)

    val lines = sc.textFile("D:/resources/README.md")
    val words = lines.flatMap(_.split(" ")).filter(word => word != " ")
    val pairs = words.map(word => (word, 1))

    /**
      * 在這裏通過reduceByKey方法之後可以獲得每個單詞出現的次數
      * 第一個map將單詞和出現的次數交換,將出現的次數作爲key,使用sortByKey進行排序(false爲降序)
      * 第二個map將出現的次數和單詞交換,這樣還是恢復到以單詞作爲key
      */
    val wordcount = pairs.reduceByKey(_ + _).map(pair => (pair._2, pair._1)).sortByKey(false).map(pair => (pair._2, pair._1))
    wordcount.collect.foreach(println)

    sc.stop()
  }
}

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.*;
import scala.Tuple2;

import java.util.Arrays;

/**
 * Created by Administrator on 2016/7/24 0024.
 */
public class WordCount {
    public static void main(String[] args) {
        SparkConf conf = new SparkConf().setAppName("WordCount").setMaster("local");
        JavaSparkContext sc = new JavaSparkContext(conf);

        JavaRDD<String> lines = sc.textFile("D:/resources/README.md");
        JavaRDD<String> words = lines.flatMap(new FlatMapFunction<String, String>() {

            @Override
            public Iterable<String> call(String line) throws Exception {
                return Arrays.asList(line.split(" "));
            }
        });

        JavaPairRDD<String, Integer> pairs = words.mapToPair(new PairFunction<String, String, Integer>() {
            @Override
            public Tuple2<String, Integer> call(String word) throws Exception {
                return new Tuple2<String, Integer>(word, 1);
            }
        });

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

        for (Tuple2<String, Integer> pair : wordcount.collect()) {
            System.out.println(pair._1 + ": " + pair._2);
        }

        sc.close();
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章