Spark基础

安装

Spark下载地址:http://spark.apache.org/downloads.html, 解压后即可使用。
在这里插入图片描述
创建测试文件并输出内容:
在这里插入图片描述
输入val lines=sc.textFile("/home/lucy/hellospark") 加载文件内容,输入lines.count()进行统计行数:
在这里插入图片描述

Scala之HelloWorld

环境:idea + maven + scala

创建一个空的maven工程(可参照参考资料1),在src/main目录下创建scala目录,并设置为Sources Root。然后添加Scala环境:
File->Project Structure->Libraries,新增Scala SDK库(如果是多模块的maven项目,则在需要的模块中添加)。
在scala目录下新建scala class文件,类型选择Object:

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("hello world!")
  }
}

运行后即可输出hello world。

第一个Spark程序

对官方提供的例子WordCount进行稍许修改,如下:

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

object WordCount {
  def main(args: Array[String]): Unit = {
    /**
      * 创建Spark的配置对象SparkConf,设置Spark程序的运行时的配置信息
      * 例如说通过setMaster来设置程序要连接的Spark集群的Master的URL
      * 如果设置为local,则代表Spark程序本地运行
      */
    val conf = new SparkConf()
    conf.setAppName("MySimpleApp") // 设置应用名称,在程序运行的监控界面可以看到名称
    conf.setMaster("local") // 此时程序在本地运行,无需安装集群

    /**
      * SparkContext是Spark程序所有功能的唯一入口
      * 作用:初始化Spark应用程序运行所需要的核心组件,同时负责Spark程序往Master注册程序
      * SparkContext是整个Spark应用程序中最为重要的一个对象
      */
    val sc = new SparkContext(conf) // 创建SparkContext对象,通过传入SparkConf实例来定制Spark运行的具体参数

    /**
      * 根据具体的数据来源(HDFS,HBase,Local FS,DB等),通过SparkContext来创建RDD
      * RDD的创建基本有三种方式,根据外部的数据来源,根据Scala集合,由其他的RDD操作产生
      * 数据会被RDD划分为一系列的Partitions,分配到每个Partition的数据属于一个Task的处理范畴
      */

    // 读取本地文件,并设置partition为1
    var lines = sc.textFile("/home/文档/test_data", 1)

    /**
      * 对初始化的RDD进行Transformation级别的处理,例如map,filter等高阶函数等的编程。
      * 1.将每一行的字符串拆分成单个单词
      * 2.在单词拆分的基础上对每个单词的实例计数为1,也就是word=>(word,1)
      * 3.在每个单词实例计数为1的基础之上统计每个单词在文件出现的次数
      */

    // 对每一行的字符串进行单词的拆分并把所有行的拆分结果通过flat合并成一个大的单词集合
    val words = lines.flatMap{
      line => line.split("  ") //words同样是RDD类型
    }
    val pairs = words.map{
      word => (word, 1)
    }
    val wordCounts = pairs.reduceByKey(_+_) // 对相同的key,进行value的累加

    wordCounts.foreach(wordNumberPair => println(wordNumberPair._1 + " : " + wordNumberPair._2))
    sc.stop() // 注意一定要将SparkContext的对象停止,因为SparkContext运行时会创建很多的对象
  }
}

事实上在本地运行这个sample可能会报错。
第一个错误是: ClassNotFoundException: org.apache.spark.SparkConf
原因是依赖包org.apache.spark的作用域,去掉provided限制即可:

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_${scala.version}</artifactId>
    <version>${spark.version}</version>
</dependency>

第二个错误是:

Exception in thread "main" java.lang.NoSuchMethodException: akka.remote.RemoteActorRefProvider

原因是:本地安装的scala中带的actor版本和spark中akka的actor版本有差异。解决办法是在File->Project Structure->modules中调整scala的sdk顺序,放到spark后即可,如下图所示:
在这里插入图片描述

其他可能遇到的错误:tried to access method com.google.common.base.Stopwatch.()V from class org.apache.hadoop.mapred.FileInputFormat
解决思路:hadoop包版本问题

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>2.7.2</version>
</dependency>
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>2.7.2</version>
</dependency>
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-mapreduce-client-core</artifactId>
    <version>2.7.2</version>
</dependency>

Spark基础函数用法

重要概念

RDD是Spark的计算模型,全称为弹性的分布式数据集合(Resilient Distributed DataSet)。RDD的创建基本有三种方式:从外部存储系统中引用一个数据集;并行化一个已存在的集合;由其他的RDD操作产生。

一个完整的RDD运行任务被分为两部分:Transformation(转换)和Action(执行)。
Transformation用于创建RDD,此部分提供了大量的操作方法,如map、filter、groupBy、join等,以便利用这些操作生成新的RDD。
Action是数据执行部分,通过count、reduce、collect等方法真正执行数据的计算部分。
RDD中所有的操作都是Lazy模式的,运行在编译中不会立即计算最终结果,而是记住所有的操作步骤和方法,只有显式地遇到启动命令时才执行计算。

Transformation操作

filter
filter操作对RDD进行过滤,生成一个新的RDD,原RDD不会改变。

Union或++
union操作(或++操作)用于合并两个RDD。

map
map操作将函数作用到RDD中的每个元素上,生成一个新的RDD返回。

下面有一个例子:

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

  val sc = new SparkContext("local", "My Opts")
  // 根据集合产生RDD	
  val myfirstrdd = sc.parallelize(List("a", "b", "c"))
  val ardd = myfirstrdd.filter(_ != "a").map(x => {(x, 1)})
  // 设置持久化策略
  ardd.persist(StorageLevel.DISK_ONLY)

  // 保存
  ardd.saveAsTextFile("output")
}

执行main函数,将在当前工作目录下生成output文件夹,含两个文件part-00000和_SUCCESS(执行成功标识,内容为空)。part-00000内容是:

(b,1)
(c,1)

flatMap
flatMap会先执行map操作,再将所有对象合并为一个对象,返回值是一个Sequence。flatMap将输入执行func操作时,对象必须是可迭代的。

下面看一个例子:

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

  val sc = new SparkContext("local", "My Opts")

  val myfirstrdd = sc.parallelize(List("Hello world", "Hello master"))
  val ardd = myfirstrdd.filter(_ != null).map(
    line => {
      val data = line.split(" ")
      (data(0), data(1))
    }
  )

  val result = ardd.collect()
  println(result.toList)

  ardd.persist(StorageLevel.DISK_ONLY)
  // 保存
  ardd.saveAsTextFile("output")

}

输出结果:List((Hello,world), (Hello,master)),生成的文件为:

(Hello,world)
(Hello,master)

如果使用flatMap,则如下所示:

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

  val sc = new SparkContext("local", "My Opts")

  val myfirstrdd = sc.parallelize(List("Hello world", "Hello master"))
  val ardd = myfirstrdd.filter(_ != null).flatMap(
    line => {
      line.split(" ")
    }
  )

  val result = ardd.collect()
  println(result.toList)
  ardd.persist(StorageLevel.DISK_ONLY)
  // 保存
  ardd.saveAsTextFile("output")
}

输出结果:List(Hello, world, Hello, master),生成的文件为:

Hello
world
Hello
master

Action操作

count
count操作求RDD大小。如上文的例子中经过map和flatMap转换后的RDD,对其执行count(),结果分别是2和4。

countByValue
返回RDD每个元素的个数。对上文例子中经过flatMap转换后的RDD执行countByValue():

val result = ardd.countByValue()
println(result)

结果是:

Map(Hello -> 2, master -> 1, world -> 1)

reduce
reduce操作用于结果合并计算。
仍然对上文中经过flatMap转换后的RDD进行操作:

val result = ardd.reduce(
  (x, y) => {x + "," + y}
)
println(result)

结果为:Hello,world,Hello,master

reduceByKey
reduceByKey根据key进行结果合并。
对于上文中经过flatMap转换后的RDD继续操作:

val secondRdd = ardd.map(line => {
  (line, 1)
}).reduceByKey((x, y) => x + y)

println(secondRdd.collect().toList)

结果为:List((Hello,2), (master,1), (world,1))

程序打包与运行

开发完成之后,就可以将程序打成jar包并在spark中运行了。具体步骤是(IDE是idea):
(1) File->Project Structure->Artifacts,点击+按钮,添加JAR,如下图所示:
在这里插入图片描述(2) 然后选择主类(点击文件夹图标自动提供选择项):
在这里插入图片描述
(3) 配置jar包生成路径Output directory,点击应用,OK。
(4) 选择菜单栏的Build选择,Build->Build Artifacts:
在这里插入图片描述
Build即可。最终生成的jar包位于第三步中配置的位置。

将jar包上传到spark服务器的某个目录,然后进入spark的bin目录,通过spark-submit运行jar包:
在这里插入图片描述当然,对于maven工程,直接执行maven的package来生成jar包,更为方便。

参考资料

[1] https://blog.csdn.net/a18852867035/article/details/82744433
[2] https://blog.csdn.net/a1610770854/article/details/51810124
[3] https://www.jianshu.com/p/c6f8b56d8467

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值