Spark学习笔记(一)——Spark编程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Shingle_/article/details/81988742

Apache Spark是一个分布式计算框架,旨在简化运行于计算机集群上的并行程序的编写。

Spark的前辈:MPI、MapReduce

特性:迭代式计算、交互式探索、内存缓存计算

Spark软件栈

  • Spark Core:任务调度、内存管理、错误恢复、与存储系统交互,弹性分布式数据集(resilient distributed dataset, RDD)
  • Spark SQL:可与Hive Metastore交互
  • Spark Steaming:能从Flume、Kafka读取数据
  • MLlib:分类、回归、聚类、协同过滤
  • GraphX:并行的图计算

Spark编程模型

每个Spark应用都由一个驱动器程序来发起集群上的各种并行操作,驱动器程序通过一个SparkContext对象来访问Spark。Spark集群是由两类程序构成:一个驱动程序和多个执行程序。本地模式时对所有的处理都运行在同一个JVM中,而在集群模式时包括一个运行Spark单机主程序和驱动程序的主节点和各自运行一个执行程序进程的多个工作节点。

Spark Shell

在Spark Shell中,实际的驱动器程序就是Spark Shell本身,shell启动时就创建了一个SparkContext对象,sc变量。

  • Scala Shell
  • Python Shell

SparkContext类和SparkConf类

Spark也可以在Java、Scala或Python的独立程序中使用,与shell中使用的主要区别在于需要自动初始化SparkContext。

例如:(Python中)

from pyspark import SparkConf, SparkContext

conf = SparkConf().setMaster("local").setAppName("My App")
sc = SparkContext(conf = conf)

弹性分布式数据集(RDD)

在Spark中,通过对分布式数据集的操作来表达意图,这些计算会自动地在集群上并行进行。RDD是Spark对分布式数据和计算的基本抽象。

两种创建RDD的方法:

  • 用SparkContext基于外部数据源**创建**RDD,包括HDFS上的文件、通过JDBC访问的数据库表或Spark Shell中创建的本地对象集合。
  • 在一个或多个已有的RDD上执行转换操作来创建RDD,包括记录过滤、对具有相同键值的记录做汇总,把多个RDD关联在一起。
val collection = List("a", "b", "c", "d", "e")
val rddFromCollection = sc.parallelize(collection)

val rddFromTextFile = sc.textFile("LICENSE")

RDD操作

  • 转换(transformation):对一个数据集里的所有记录执行某种函数,从而使记录发生改变,如mapfilterfilterNotSpark中的转换操作时延后的!在RDD上调用一个转换操作并不会立即触发相应的计算,这些转换操作会链接起来,在执行操作被调用时才被高效的计算。
val intFromStringRDD = rddFromTextFile.map(line => line.size)
函数名(1个RDD) 目的
map() 将函数应用于RDD的每个元素,将返回值构成新的RDD
flatMap() 将函数应用于RDD的每个元素,将返回的迭代器的所有内容构成新的RDD
filter() 返回一个由通过传给filter()的函数的元素组成的RDD
distinct() 去重
sample(withReplacement, fraction, [seed]) 对RDD采样,以及是否替换
函数名(2个RDD) 目的
union() 生成一个包含两个RDD中所有元素的RDD
intersection() 求两个RDD共同的元素的RDD
subtract() 移除一个RDD中的内容
cartesian() 与另一个RDD的笛卡儿积
  • 执行(action):运行某些计算或聚合操作,并将结果返回运行SparkContext的那个驱动程序。如firsttakecollect
函数名 目的
collect() 返回RDD中的所有元素
count() RDD中的元素个数
countByValue() 各个元素在RDD中出现的次数
take(num) 从RDD中返回num个元素
top(num) 从RDD中返回最前面的num个元素
takeOrdered(num)(ordering) 从RDD中按照提供的顺寻返回最前面的num个元素
takeSample(w ithReplacement, num, [seed])
reduce(func) 并行整合RDD中所有数据,如sum
fold(zero)(func) 和reduce()一样,但是需要提供初始值
aggregate(zeroValue)(seqOp, combOp) 和reduce()相似,通常返回不同类型的函数
foreach(func) 对RDD中的每个元素使用给定的函数

注: 通常只在需要将结果返回到驱动程序所在节点以供本地处理时,才调用collect函数。如果在一个非常大的数据集上调用该函数,可能耗尽驱动程序的可用内存,导致程序崩溃。

pair RDD

函数名(1个RDD) 目的
reduceByKey(func) 合并具有相同键的值
groupByKey() 对具有相同键的值进行分组
combineByKey(createCombiner, mergeValue, mergeCombiners, partitioner) 使用不同的返回类型合并具有相同键的值
mapValues(func) 对pair RDD中的每个值应用一个函数而不改变键
flatMapValues(func) 对pair RDD中每个值应用一个返回迭代器函数,然后对返回的每个元素都生成一个对应原键的键值对记录
keys() 返回一个仅包含键的RDD
values() 返回一个仅包含值的RDD
sortByKey() 返回一个根据键排序的RDD
函数名(2个RDD) 目的
subtractByKey() 删掉RDD中键与other RDD中键相同的元素
join() 对两个RDD进行内连接
rightOuterJoin() 对两个RDD进行连接操作,确保第一个RDD的键必须存在(右外连接)
leftOuterJoin() 对两个RDD进行连接操作,确保第二个RDD的键必须存在(左外连接)
cogroup() 将两个RDD中拥有相同键的数据分组到一起

RDD缓存策略\持久化
Spark最强大的功能之一就是能够把数据缓存在集群的内存中。通过rddFromTextFile.cache函数实现。

Spark为持久化RDD定义了几种不同的机制,用不同的StoreageLevel表示。rdd.cache()rdd.persist(StorageLevel.MEMORY)的简写,将RDD存储为未序列化的java对象。存储级别:(MEMORY、MEMORY_SER、MEMORY_AND_DISK、MEMORY_AND_DISK_SER)。什么时候需要缓存数据需要对空间时间进行权衡,还需要考虑垃圾回收的开销。调用unpersist()方法可以手动把持久化的RDD从缓存中移除。

广播变量和累加器

广播变量为只读变量,由运行SparkContext的驱动程序创建后发送给参与计算的节点。

val broadcastAList = sc.broadcast(List("a", "b", "c", "d", "e"))

累加器也是一种被广播到工作节点的变量,不同于广播变量,累加器可以累加,能保证在全局范围内累加起来的值能被正确的并行计算以及返回驱动程序。

聚合与统计

聚合:对集群数据进行聚合时,一定要时刻记住我们分析的数据是存放在多台机器上的,并且聚合需要连接机器的网络来移动数据(需要考虑数据传输的效率)。

val grouped = mds.groupBy(md => md.matched)

创建直方图:(类别变量)

val matchCounts = parsed.map(md => md.matched).countByValue()
val matchContsSeq = matchCounts.toSeq
matchContsSeq.sortby(_._1).foreach(println)

连续变量的统计

import java.long.Double.isNaN
parsed.map(md => md.scores(0)).filter(!isNaN(_)).stats()

val stats = (0 until 9).map(md => md.scores(i)).filter(!isNaN(_)).stats()

Spark编程的核心概念:通过一个驱动器程序创建一个SparkContext和一系列RDD,然后进行并行操作。

  • 从外部数据中创建出输入RDD
  • 使用诸如filter()这样的转化操作对RDD进行转化,以定义新的RDD
  • 告诉Spark对需要被重用的中间结果RDD执行persist()操作
  • 使用行动操作(如count()first())来触发一次并行计算,Spark会对计算进行优化后再执行。

Spark机器学习

见Blog:

Spark学习笔记(二)——Spark机器学习


《Spark快速大数据分析》(《Learning Spark: Lightning-fast Data Analysis》)

《Spark高级数据分析》(《Advanced Analytics with Spark》)

《Spark 机器学习》(《Machine Learning with Spark》)

http://spark.apache.org

猜你喜欢

转载自blog.csdn.net/Shingle_/article/details/81988742
今日推荐