Spark核心編程:使用Java硫眨、Scala和spark-shell開(kāi)發(fā)wordcount程序

開(kāi)發(fā)wordcount程序

1朦佩、用Java開(kāi)發(fā)wordcount程序
1.1 配置maven環(huán)境
1.2 如何進(jìn)行本地測(cè)試
1.3 如何使用spark-submit提交到spark集群進(jìn)行執(zhí)行(spark-submit常用參數(shù)說(shuō)明冯遂,spark-submit其實(shí)就類(lèi)似于hadoop的hadoop jar命令)拟枚。spark-submit封裝在shell腳本里面

2颂郎、用Scala開(kāi)發(fā)wordcount程序
2.1 下載scala ide for eclipse
2.2 在Java Build Path中吼渡,添加spark依賴包(如果與scala ide for eclipse原生的scala版本發(fā)生沖突,則移除原生的scala / 重新配置scala compiler)
2.3 用export導(dǎo)出scala spark工程

3乓序、用spark-shell開(kāi)發(fā)wordcount程序
3.1 常用于簡(jiǎn)單的測(cè)試

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>cn.spark</groupId>
  <artifactId>SparkTest</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>SparkTest</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-core_2.10</artifactId>
      <version>1.3.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-sql_2.10</artifactId>
      <version>1.3.0</version>
      </dependency>
    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-hive_2.10</artifactId>
      <version>1.3.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-streaming_2.10</artifactId>
      <version>1.3.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-client</artifactId>
      <version>2.4.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-streaming-kafka_2.10</artifactId>
      <version>1.3.0</version>
    </dependency>
  </dependencies>
  
  <build>
    <sourceDirectory>src/main/java</sourceDirectory>
    <testSourceDirectory>src/main/test</testSourceDirectory>

    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <archive>
            <manifest>
              <mainClass></mainClass>
            </manifest>
          </archive>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.2.1</version>
        <executions>
          <execution>
            <goals>
              <goal>exec</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <executable>java</executable>
          <includeProjectDependencies>true</includeProjectDependencies>
          <includePluginDependencies>false</includePluginDependencies>
          <classpathScope>compile</classpathScope>
          <mainClass>cn.spark.sparktest.App</mainClass>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>

    </plugins>
  </build>
</project>

WordCountLocal.java

package cn.spark.study.core;

import java.util.Arrays;

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.FlatMapFunction;
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;

/**
 * 使用java開(kāi)發(fā)本地測(cè)試的wordcount程序
 *
 */
public class WordCountLocal {
    
    public static void main(String[] args) {
        // 編寫(xiě)Spark應(yīng)用程序
        // 本地執(zhí)行寺酪,是可以執(zhí)行在eclipse中的main方法中,執(zhí)行的
        
        // 第一步:創(chuàng)建SparkConf對(duì)象替劈,設(shè)置Spark應(yīng)用的配置信息
        // 使用setMaster()可以設(shè)置Spark應(yīng)用程序要連接的Spark集群的master節(jié)點(diǎn)的url
        // 但是如果設(shè)置為local則代表寄雀,在本地運(yùn)行
        SparkConf conf = new SparkConf()
                .setAppName("WordCountLocal")
                .setMaster("local");  
        
        // 第二步:創(chuàng)建JavaSparkContext對(duì)象
        // 在Spark中,SparkContext是Spark所有功能的一個(gè)入口陨献,你無(wú)論是用java盒犹、scala,甚至是python編寫(xiě)
            // 都必須要有一個(gè)SparkContext眨业,它的主要作用阿趁,包括初始化Spark應(yīng)用程序所需的一些核心組件,包括
            // 調(diào)度器(DAGSchedule坛猪、TaskScheduler)脖阵,還會(huì)去到Spark Master節(jié)點(diǎn)上進(jìn)行注冊(cè),等等
        // 一句話墅茉,SparkContext命黔,是Spark應(yīng)用中呜呐,可以說(shuō)是最最重要的一個(gè)對(duì)象
        // 但是呢,在Spark中悍募,編寫(xiě)不同類(lèi)型的Spark應(yīng)用程序蘑辑,使用的SparkContext是不同的,如果使用scala坠宴,
            // 使用的就是原生的SparkContext對(duì)象
            // 但是如果使用Java洋魂,那么就是JavaSparkContext對(duì)象
            // 如果是開(kāi)發(fā)Spark SQL程序,那么就是SQLContext喜鼓、HiveContext
            // 如果是開(kāi)發(fā)Spark Streaming程序副砍,那么就是它獨(dú)有的SparkContext
            // 以此類(lèi)推
        JavaSparkContext sc = new JavaSparkContext(conf);
    
        // 第三步:要針對(duì)輸入源(hdfs文件、本地文件庄岖,等等)豁翎,創(chuàng)建一個(gè)初始的RDD
        // 輸入源中的數(shù)據(jù)會(huì)打散,分配到RDD的每個(gè)partition中隅忿,從而形成一個(gè)初始的分布式的數(shù)據(jù)集
        // 我們這里呢心剥,因?yàn)槭潜镜販y(cè)試,所以呢背桐,就是針對(duì)本地文件
        // SparkContext中优烧,用于根據(jù)文件類(lèi)型的輸入源創(chuàng)建RDD的方法,叫做textFile()方法
        // 在Java中链峭,創(chuàng)建的普通RDD匙隔,都叫做JavaRDD
        // 在這里呢,RDD中熏版,有元素這種概念纷责,如果是hdfs或者本地文件呢,創(chuàng)建的RDD撼短,每一個(gè)元素就相當(dāng)于
        // 是文件里的一行
        JavaRDD<String> lines = sc.textFile("C://Users//Administrator//Desktop//spark.txt");
    
        // 第四步:對(duì)初始RDD進(jìn)行transformation操作再膳,也就是一些計(jì)算操作
        // 通常操作會(huì)通過(guò)創(chuàng)建function,并配合RDD的map曲横、flatMap等算子來(lái)執(zhí)行
        // function喂柒,通常,如果比較簡(jiǎn)單禾嫉,則創(chuàng)建指定Function的匿名內(nèi)部類(lèi)
        // 但是如果function比較復(fù)雜灾杰,則會(huì)單獨(dú)創(chuàng)建一個(gè)類(lèi),作為實(shí)現(xiàn)這個(gè)function接口的類(lèi)
        
        // 先將每一行拆分成單個(gè)的單詞
        // FlatMapFunction熙参,有兩個(gè)泛型參數(shù)艳吠,分別代表了輸入和輸出類(lèi)型
        // 我們這里呢,輸入肯定是String孽椰,因?yàn)槭且恍幸恍械奈谋菊衙洌敵隽莞荩鋵?shí)也是String,因?yàn)槭敲恳恍械奈谋?        // 這里先簡(jiǎn)要介紹flatMap算子的作用栏渺,其實(shí)就是呛梆,將RDD的一個(gè)元素,給拆分成一個(gè)或多個(gè)元素
        JavaRDD<String> words = lines.flatMap(new FlatMapFunction<String, String>() {
            
            private static final long serialVersionUID = 1L;
            
            @Override
            public Iterable<String> call(String line) throws Exception {
                return Arrays.asList(line.split(" "));  
            }
            
        });
        
        // 接著磕诊,需要將每一個(gè)單詞填物,映射為(單詞, 1)的這種格式
            // 因?yàn)橹挥羞@樣,后面才能根據(jù)單詞作為key霎终,來(lái)進(jìn)行每個(gè)單詞的出現(xiàn)次數(shù)的累加
        // mapToPair滞磺,其實(shí)就是將每個(gè)元素,映射為一個(gè)(v1,v2)這樣的Tuple2類(lèi)型的元素
            // 如果大家還記得scala里面講的tuple神僵,那么沒(méi)錯(cuò),這里的tuple2就是scala類(lèi)型覆劈,包含了兩個(gè)值
        // mapToPair這個(gè)算子保礼,要求的是與PairFunction配合使用,第一個(gè)泛型參數(shù)代表了輸入類(lèi)型
            // 第二個(gè)和第三個(gè)泛型參數(shù)责语,代表的輸出的Tuple2的第一個(gè)值和第二個(gè)值的類(lèi)型
        // JavaPairRDD的兩個(gè)泛型參數(shù)炮障,分別代表了tuple元素的第一個(gè)值和第二個(gè)值的類(lèi)型
        JavaPairRDD<String, Integer> pairs = words.mapToPair(
                
                new PairFunction<String, String, Integer>() {

                    private static final long serialVersionUID = 1L;
        
                    @Override
                    public Tuple2<String, Integer> call(String word) throws Exception {
                        return new Tuple2<String, Integer>(word, 1);
                    }
                    
                });
        
        // 接著,需要以單詞作為key坤候,統(tǒng)計(jì)每個(gè)單詞出現(xiàn)的次數(shù)
        // 這里要使用reduceByKey這個(gè)算子胁赢,對(duì)每個(gè)key對(duì)應(yīng)的value,都進(jìn)行reduce操作
        // 比如JavaPairRDD中有幾個(gè)元素白筹,分別為(hello, 1) (hello, 1) (hello, 1) (world, 1)
        // reduce操作智末,相當(dāng)于是把第一個(gè)值和第二個(gè)值進(jìn)行計(jì)算,然后再將結(jié)果與第三個(gè)值進(jìn)行計(jì)算
        // 比如這里的hello徒河,那么就相當(dāng)于是系馆,首先是1 + 1 = 2,然后再將2 + 1 = 3
        // 最后返回的JavaPairRDD中的元素顽照,也是tuple由蘑,但是第一個(gè)值就是每個(gè)key,第二個(gè)值就是key的value
        // reduce之后的結(jié)果代兵,相當(dāng)于就是每個(gè)單詞出現(xiàn)的次數(shù)
        JavaPairRDD<String, Integer> wordCounts = pairs.reduceByKey(
                
                new Function2<Integer, Integer, Integer>() {
                    
                    private static final long serialVersionUID = 1L;
        
                    @Override
                    public Integer call(Integer v1, Integer v2) throws Exception {
                        return v1 + v2;
                    }
                    
                });
        
        // 到這里為止尼酿,我們通過(guò)幾個(gè)Spark算子操作,已經(jīng)統(tǒng)計(jì)出了單詞的次數(shù)
        // 但是植影,之前我們使用的flatMap裳擎、mapToPair、reduceByKey這種操作思币,都叫做transformation操作
        // 一個(gè)Spark應(yīng)用中句惯,光是有transformation操作土辩,是不行的,是不會(huì)執(zhí)行的抢野,必須要有一種叫做action
        // 接著拷淘,最后,可以使用一種叫做action操作的指孤,比如說(shuō)启涯,foreach,來(lái)觸發(fā)程序的執(zhí)行
        wordCounts.foreach(new VoidFunction<Tuple2<String,Integer>>() {
            
            private static final long serialVersionUID = 1L;
            
            @Override
            public void call(Tuple2<String, Integer> wordCount) throws Exception {
                System.out.println(wordCount._1 + " appeared " + wordCount._2 + " times.");    
            }
            
        });
        
        sc.close();
    }
    
}

WordCount.scala

package cn.spark.study.core

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext

/**
 * @author Administrator
 */
object WordCount {
  
  def main(args: Array[String]) {
    val conf = new SparkConf()
        .setAppName("WordCount");
    val sc = new SparkContext(conf)
  
    val lines = sc.textFile("hdfs://spark1:9000/spark.txt", 1); 
    val words = lines.flatMap { line => line.split(" ") }   
    val pairs = words.map { word => (word, 1) }   
    val wordCounts = pairs.reduceByKey { _ + _ }
    
    wordCounts.foreach(wordCount => println(wordCount._1 + " appeared " + wordCount._2 + " times."))  
  }
  
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末恃轩,一起剝皮案震驚了整個(gè)濱河市结洼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌叉跛,老刑警劉巖松忍,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異筷厘,居然都是意外死亡鸣峭,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人椅您,你說(shuō)我怎么就攤上這事佩捞。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我拉岁,道長(zhǎng),這世上最難降的妖魔是什么惰爬? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任膛薛,我火速辦了婚禮,結(jié)果婚禮上补鼻,老公的妹妹穿的比我還像新娘哄啄。我一直安慰自己,他們只是感情好风范,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布咨跌。 她就那樣靜靜地躺著,像睡著了一般硼婿。 火紅的嫁衣襯著肌膚如雪锌半。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天寇漫,我揣著相機(jī)與錄音刊殉,去河邊找鬼殉摔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛记焊,可吹牛的內(nèi)容都是我干的逸月。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼遍膜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼碗硬!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起瓢颅,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤恩尾,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后挽懦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體翰意,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年信柿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了冀偶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡角塑,死狀恐怖蔫磨,靈堂內(nèi)的尸體忽然破棺而出淘讥,到底是詐尸還是另有隱情圃伶,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布蒲列,位于F島的核電站窒朋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蝗岖。R本人自食惡果不足惜侥猩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抵赢。 院中可真熱鬧欺劳,春花似錦、人聲如沸铅鲤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)邢享。三九已至鹏往,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間骇塘,已是汗流浹背伊履。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工韩容, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唐瀑。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓群凶,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親介褥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子座掘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容