Spark学习笔记02:Spark下载与入门

Spark学习笔记02:Spark下载与入门

一、Spark下载与入门

1、下载Spark

http://spark.apache.org/downloads.html

Spark学习笔记02:Spark下载与入门_第1张图片

Spark学习笔记02:Spark下载与入门_第2张图片

2、安装Spark

将安装包解压缩在/home/software目录下:

[root@hadoop spark-2.2.0-bin-hadoop2.7]# pwd

/home/software/spark-2.2.0-bin-hadoop2.7

Spark学习笔记02:Spark下载与入门_第3张图片

本章我们所做的一切,Spark 都是在本地模式下运行,也就是非分布式模式,这样我们只需要用到一台机器。Spark 可以运行在许多种模式下,除了本地模式,还支持运行在Mesos 或YARN 上,也可以运行在Spark 发行版自带的独立调度器上。

在etc/profile配置环境变量:

Spark学习笔记02:Spark下载与入门_第4张图片

3、Spark中Python和Scala的shell

(1)启动Python版的shell

Spark学习笔记02:Spark下载与入门_第5张图片

(2)启动scala版的shell

Spark学习笔记02:Spark下载与入门_第6张图片

在日志的输出中注意到了这样一行信息:Spark context Web UI available at http://192.168.159.100:4040。你可以由这个地址访问Spark 用户界面,查看关于任务和集群的各种信息。

Spark学习笔记02:Spark下载与入门_第7张图片

4、在Linux上安装ipython

Spark学习笔记02:Spark下载与入门_第8张图片

(1)上传到虚拟机hadoop的/home/software目录

Spark学习笔记02:Spark下载与入门_第9张图片

(2)解压缩ipython安装包

[root@hadoop software]# tar -zxvf ipython-6.2.1.tar.gz

(3)进入解压缩之后的目录ipython-6.2.1

[root@hadoop software]# cd ipython-6.2.1

(4)执行setup.py脚本,安装ipython

[root@hadoop ipython-6.2.1]# python setup.py install

该操作将会在site-packages目录中安装ipyhon的库文件,并在scripts目录中创建一个ipython脚本。在unix系统中,该目录与python的二进制文件目录相同。如果系统中已经安装了python包,则ipython将会安装在/usr/bin目录下。

Spark学习笔记02:Spark下载与入门_第10张图片

(5)启动ipython

Spark学习笔记02:Spark下载与入门_第11张图片

5、操作RDD示例

在Spark 中,我们通过对分布式数据集的操作来表达我们的计算意图,这些计算会自动地在集群上并行进行。这样的数据集被称为弹性分布式数据集(resilient distributed dataset),简称RDD。RDD 是Spark 对分布式数据和计算的基本抽象。

任务1:统计文本文件test.txt行数

sc: Spark Context

(1)python版

>>> lines = sc.textFile('test.txt')

>>> lines.count()

3

>>> lines.first()

'hello hadoop hello spark'

(2)scala版

scala> val lines = sc.textFile("test.txt")

lines: org.apache.spark.rdd.RDD[String] = test.txt MapPartitionsRDD[1] at textFile at :24

scala> lines.count()

res0: Long = 3

scala> lines.first()

res1: String = hello hadoop hello spark

6、Spark核心概念

从上层来看,每个Spark 应用都由一个驱动器程序(driver program)来发起集群上的各种并行操作。驱动器程序包含应用的main 函数,并且定义了集群上的分布式数据集,还对这些分布式数据集应用了相关操作。在前面的例子里,实际的驱动器程序就是Spark shell本身,你只需要输入想要运行的操作就可以了。

驱动器程序通过一个SparkContext对象来访问Spark。这个对象代表对计算集群的一个连接。shell 启动时已经自动创建了一个SparkContext 对象,是一个叫作sc 的变量。

一旦有了SparkContext,你就可以用它来创建RDD,前面调用了sc.textFile() 来创建一个代表文件中各行文本的RDD。我们可以在这些行上进行各种操作,比如count()。要执行这些操作,驱动器程序一般要管理多个执行器(executor)节点。比如,如果我们在集群上运行count() 操作,那么不同的节点会统计文件的不同部分的行数。

Spark学习笔记02:Spark下载与入门_第12张图片

任务2:筛选文本文件中满足条件的行。

(1)python版

>>> lines = sc.textFile("test.txt")

>>> scalaLines = lines.filter(lambda line: "scala" in line)

>>> scalaLines.count()

1

>>> scalaLines.first()

'i learn hadoop and scala'

>>> lines = sc.textFile('test.txt')

>>> iLines = lines.filter(lambda line: line.startswith('i'))

>>> iLines.count()

2

>>> iLines.first()

'i love you hadoop and spark'

(2)scala版

scala> val lines = sc.textFile("test.txt")

lines: org.apache.spark.rdd.RDD[String] = test.txt MapPartitionsRDD[3] at textFile at :24

scala> val scalaLines = lines.filter(line => line.contains("scala"))

scalaLines: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[4] at filter at :26

scala> scalaLines.count()

res0: Long = 1

scala> scalaLines.first()

res1: String = i learn hadoop and scala

scala> val lines = sc.textFile("test.txt")

lines: org.apache.spark.rdd.RDD[String] = test.txt MapPartitionsRDD[8] at textFile at :24

scala> val iLines = lines.filter(line => line.charAt(0) == 'i')

iLines: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[9] at filter at :26

scala> iLines.count()

res9: Long = 2

scala> iLines.first()

res10: String = i love you hadoop and spark


同样的任务,交给Java来做。

Spark学习笔记02:Spark下载与入门_第13张图片

import java.util.ArrayList;
import java.util.List;

/**
 * Created by howard on 2018/2/1.
 */
public class FilterLinesDemo {
    public static void main(String[] args) throws Exception {
        List lines = new ArrayList<>();
        BufferedReader br = new BufferedReader(new FileReader("test.txt"));
        String nextLine = "";
        while ((nextLine = br.readLine()) != null) {
            lines.add(nextLine);
        }
        // 输出包含“scala”的行
        System.out.println("输出包含“scala”的行:");
        lines.stream().filter(line -> line.contains("scala")).forEach(System.out::println);
        // 输出以“i”打头的行
        System.out.println("输出以“i”打头的行:");
        lines.stream().filter(line -> line.startsWith("i")).forEach(System.out::println);

    }
}

Spark学习笔记02:Spark下载与入门_第14张图片

大家可以看到,三种语言的lambda表达式的写法有些差异。

Spark学习笔记02:Spark下载与入门_第15张图片

任务3:统计文件中单词个数。

(1)python版

>>> lines = sc.textFile('test.txt')

>>> words = lines.flatMap(lambda line: line.split(' '))

>>> maps = words.map(lambda word: (word, 1))

>>> counts = maps.reduceByKey(lambda x, y: x + y)

>>> counts.foreach(print)

('hello', 2)

('hadoop', 3)

('i', 2)

('spark', 2)

('love', 1)

('you', 1)

('scala', 1)

('and', 2)

('learn', 1)

(2)scala版

scala> val lines = sc.textFile("test.txt")

lines: org.apache.spark.rdd.RDD[String] = test.txt MapPartitionsRDD[1] at textFile at :24

scala> val words = lines.flatMap(_.split(" "))

words: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[2] at flatMap at :26

scala> val maps = words.map((_, 1))

maps: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[3] at map at :28

scala> val counts = maps.reduceByKey(_ + _)

counts: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[4] at reduceByKey at :30

scala> counts.foreach(println)

[Stage 0:> (0 + 0) / 2](spark,2)

(you,1)

(scala,1)

(hadoop,3)

(i,2)

(and,2)

(learn,1)

(love,1)

(hello,2)

二、构建Spark独立应用

1、Java版的单词计数应用

(1)创建Maven项目JavaSparkWordCount

Spark学习笔记02:Spark下载与入门_第16张图片

(2)在pom.xml里添加对spark的依赖



    4.0.0

    net.hw.spark
    JavaSparkWordCount
    1.0-SNAPSHOT

    
        
            org.apache.spark
            spark-core_2.11
            2.2.1
        
    

(4)创建输入目录与单词文件

Spark学习笔记02:Spark下载与入门_第17张图片

(5)创建WordCount类

Spark学习笔记02:Spark下载与入门_第18张图片

package net.hw.spark;

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

import java.io.File;
import java.util.Arrays;
import java.util.Iterator;

/**
 * Created by howard on 2018/2/1.
 */
public class WordCount {
    public static void main(String[] args) {
        String inputPath = "input";
        String outputPath = "result";

        SparkConf conf = new SparkConf().setMaster("local").setAppName("wordcount");
        JavaSparkContext sc = new JavaSparkContext(conf);

        // 读取文件
        JavaRDD input = sc.textFile(inputPath);
        // 切分单词
        JavaRDD words = input.flatMap(
                new FlatMapFunction() {
                    public Iterator call(String x) {
                        return Arrays.asList(x.split(" ")).iterator();
                    }
                });
        // 转换成键值对并计数
        JavaPairRDD counts = words.mapToPair(new PairFunction() {
            @Override
            public Tuple2 call(String x) throws Exception {
                return new Tuple2<>(x, 1);
            }
        }).reduceByKey(new Function2() {
            @Override
            public Integer call(Integer x, Integer y) throws Exception {
                return x + y;
            }
        });

        // 输出统计结果
        System.out.println(counts.collect());

        // 删除输出目录
        File dir = new File(outputPath);
        File[] files = dir.listFiles();
        if (files != null) {
            for (File file : files) {
                file.delete();
            }
        }
        dir.delete();

        // 将统计结果写入结果文件
        counts.saveAsTextFile(outputPath);
    }
}

运行结果如下:

Spark学习笔记02:Spark下载与入门_第19张图片

采用lambda表达式可以简化代码:

// 切分单词
JavaRDD words = input.flatMap(
        x -> Arrays.asList(x.split(" ")).iterator());
// 转换成键值对并计数
JavaPairRDD counts = words.mapToPair(x -> new Tuple2<>(x, 1))
        .reduceByKey((x, y) -> x + y);

2、Scala版的单词计数应用

(1)创建Scala项目ScalaSparkWordCount

Spark学习笔记02:Spark下载与入门_第20张图片

Spark学习笔记02:Spark下载与入门_第21张图片

Spark学习笔记02:Spark下载与入门_第22张图片

(2)创建lib目录,将spark的jar包拷贝到该目录

说明:spark-2.2.0自带的scala版本是2.11.8,跟项目配置的scala-sdk版本必须一致,否则程序运行就会报错。

Spark学习笔记02:Spark下载与入门_第23张图片

Spark学习笔记02:Spark下载与入门_第24张图片

将所有jar包作为库添加到项目:

Spark学习笔记02:Spark下载与入门_第25张图片

Spark学习笔记02:Spark下载与入门_第26张图片

(3)创建输入目录与单词文件

Spark学习笔记02:Spark下载与入门_第27张图片

(4)在src目录里创建log4j.properties

Spark学习笔记02:Spark下载与入门_第28张图片

log4j.rootLogger=WARN, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spark.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

(5)创建WordCount对象

Spark学习笔记02:Spark下载与入门_第29张图片

package net.hw.spark

import java.io.File

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

/**
  * Created by howard on 2018/2/2.
  */
object WordCount {
  def main(args: Array[String]): Unit = {
    val inputPath = "input"
    val outputPath = "result"

    val conf = new SparkConf().setMaster("local").setAppName("wordcount")
    val sc = new SparkContext(conf)

    // 读取文件
    val input = sc.textFile(inputPath)
    // 切分单词
    val words = input.flatMap(_.split(" "))
    // 转换成键值对并计数
    val counts = words.map((_, 1)).reduceByKey {  _ + _  }

    // 输出统计结果
    counts.foreach(println)

    // 删除输出目录
    val dir: File = new File(outputPath)
    if (dir.exists()) {
      for (file <- dir.listFiles()) {
        file.delete()
      }
    }
    dir.delete()

    // 将统计结果写入结果文件
    counts.saveAsTextFile(outputPath)
  }
}

运行结果如下:

Spark学习笔记02:Spark下载与入门_第30张图片

Spark学习笔记02:Spark下载与入门_第31张图片

3、Python版的单词计数应用

(1)将spark安装目录下python里的pyspark目录拷贝到Python安装目录下Lib里的site-packages目录

Spark学习笔记02:Spark下载与入门_第32张图片

Spark学习笔记02:Spark下载与入门_第33张图片

(2)创建Python项目PythonSparkWordCount

Spark学习笔记02:Spark下载与入门_第34张图片

(3)创建输入目录与单词文件

Spark学习笔记02:Spark下载与入门_第35张图片

(4)创建word_count.py文件

Spark学习笔记02:Spark下载与入门_第36张图片

import os
import shutil

from pyspark import SparkContext

inputpath = 'input'
outputpath = 'result'

sc = SparkContext('local', 'wordcount')

# 读取文件
input = sc.textFile(inputpath)
# 切分单词
words = input.flatMap(lambda line: line.split(' '))
# 转换成键值对并计数
counts = words.map(lambda word: (word, 1)).reduceByKey(lambda x, y: x + y)

# 输出结果
counts.foreach(print)

# 删除输出目录
if os.path.exists(outputpath):
    shutil.rmtree(outputpath, True)

# 将统计结果写入结果文件
counts.saveAsTextFile(outputpath)

运行结果如下:

Spark学习笔记02:Spark下载与入门_第37张图片

(5)下载并安装py4j

https://pypi.python.org/pypi/py4j/0.10.6

Spark学习笔记02:Spark下载与入门_第38张图片

Spark学习笔记02:Spark下载与入门_第39张图片

Spark学习笔记02:Spark下载与入门_第40张图片

D:\Program Files\py4j-0.10.6>python setup.py install

Installed d:\program files\python\python36\lib\site-packages\py4j-0.10.6-py3.6.egg

Processing dependencies for py4j==0.10.6

Finished processing dependencies for py4j==0.10.6

此时运行程序,结果如下:

Spark学习笔记02:Spark下载与入门_第41张图片

(6)配置环境变量SPARK_HOME

Spark学习笔记02:Spark下载与入门_第42张图片

Spark学习笔记02:Spark下载与入门_第43张图片

此时,运行程序,结果如下:

Spark学习笔记02:Spark下载与入门_第44张图片

Spark学习笔记02:Spark下载与入门_第45张图片

三、总结

在本章中,我们讲到了下载并在单机的本地模式下运行Spark,以及Spark 的使用方式,包括交互式方式和通过一个独立应用进行调用。另外我们还简单介绍了Spark 编程的核心概念:通过一个驱动器程序创建一个SparkContext 和一系列RDD,然后进行并行操作。

你可能感兴趣的:(Spark,大数据基础)