word_count的scala學習

一隻勤奮愛思考的豬發表於2018-08-26
package com.zhouls.spark

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import java.lang.System


object WordCount {
  System.setProperty("hadoop.home.dir", "E:\\software\\Spark\\spark-2.3.1-bin-hadoop2.7\\spark-2.3.1-bin-hadoop2.7")
  def main(args: Array[String]): Unit = {
    /*
     * 第1步:建立spark的配置物件sparkconf,設定spark程式的執行時的配置資訊,
     * 例如說通過setMaster來設定程式要連結的spark叢集的master的URL,如果設定為local,則代表spark程式在本地執行,
     * 特別適合於機器配置條件非常差(例如只有1G記憶體)的初學者
     */
    val conf = new SparkConf()//建立SparkConf物件
    conf.setAppName("Wow,My First Spark App!")//設定應用程式的名稱,在程式執行的監控介面可以看到名稱
    conf.setMaster("local")//此時,程式在本地執行,不需要安裝spark叢集

    /*
     * 第2步:建立SparkContext物件
     * SparkContext是spark程式所有功能的唯一入口,無論是採用scala、java、pthon、R等都必須有一個SparkContext
     * SparkContext核心作用:初始化spark應用程式執行所需要的核心元件、包括DAGScheduler、TaskScheduler、SchedulerBackend
     * 同時還會負責spark程式往master註冊程式等
     * SparkContext是整個spark應用程式中最為至關重要的一個物件
     */
    val sc = new SparkContext(conf)

    /*
     * 第3步:根據具體的資料來源(HDFS、HBase、Local FS、DB、S3等)通過SparkContext來建立RDD
     * RDD的建立基本有三種方式:根據外部的資料來源(如HDFS)、根據Scala集合、由其它的RDD運算元據會被RDD劃分成
     * 一系列的Partitions,分配到每個Partition的資料屬於一個Task的處理範疇
     */
    // val lines:RDD[String] = sc.textFile("D://SoftWare//spark-1.6.2-bin-hadoop2.6//README.md", 1)//path指的是檔案路徑,minPartitions指的是最小並行度
    val lines = sc.textFile("E://software//Spark//spark-2.3.1-bin-hadoop2.7//spark-2.3.1-bin-hadoop2.7//README.md", 1)//path指的是檔案路徑,minPartitions指的是最小並行度

    /*
     * 第4步:對初始的RDD進行Transformation級別的處理,例如map、filter等高階函式等的程式設計,來進行具體的資料計算
     *  第4.1步:將每一行的字串拆分成單個的單詞
     */
    val words = lines.flatMap{ line => line.split(" ")}//對每一行的字串進行單詞拆分並把所有行的拆分結果通過flat合併成為一個

    /*
    * 4.2步:在單詞拆分的基礎上對每個單詞例項計數為1,也就是 word => (word,1)
    */
    val pairs = words.map { word => (word,1) }

    /*
     * 4.3步:在每個單詞例項計數為1基礎之上統計每個單詞在檔案中出現的總次數
     */
    val wordCounts =  pairs.reduceByKey(_+_)//對相同的key,進行value的累計(包括local和reducer級別同時reduce)
    wordCounts.foreach(wordNumberPair => println(wordNumberPair._1 + ":" + wordNumberPair._2))

    /*
     * 第5步
     */
    sc.stop();
  }

}

上述val wordCounts = pairs.reduceByKey(+)

參考:https://blog.csdn.net/zongzhiyuan/article/details/49965021
reduceByKey(+) 含義:
reduceByKey的機制,先在本地進行merge,再進行最後合併:
這裡寫圖片描述
當採用reduceByKeyt時,Spark可以在每個分割槽移動資料之前將待輸出資料與一個共用的key結合。藉助下圖可以理解在reduceByKey裡究竟發生了什麼。 注意在資料對被搬移前同一機器上同樣的key是怎樣被組合的(reduceByKey中的lamdba函式)。然後lamdba函式在每個區上被再次呼叫來將所有值reduce成一個最終結果。整個過程如下:

對比groupByKey:不建議用,他不會在本地進行合併,浪費節點空間!!
這裡寫圖片描述

相關文章