Spark入门笔记

书籍

>
- spark 大数据处理技术
- spark mllib 机器学习实践
- Apache Spark源码剖析
- Spark快速数据处理
- 深入理解Spark 核心思想与源码分析
- 统计学习方法
- spark官方文档中文版

环境搭建教程

IDEA导入hadoop2.6的jar包

hadoop2.6.0实践:引入开发依赖的jar包
hadoop-2.5.0\share\hadoop\common 所有jar,
hadoop-2.5.0\share\hadoop\common\lib 所有jar,
hadoop-2.5.0\share\hadoop\hdfs 所有jar
hadoop-2.5.0\share\hadoop\mapreduce 所有jar
hadoop-2.5.0\share\hadoop\yarn 所有jar

hadoop及spark任务页面

  • hadoop:
    http://192.168.100.128:8088/cluster
    http://192.168.100.128:50070/dfshealth.html#tab-overview
  • spark
    http://192.168.100.128:8080

路径

hadoop:/usr/local/hadoop
安装包:/home/jerry123/spark
sbt:/usr/local/sbt
spark:/usr/local/spark
sparkapp:~/sparkapp

开启:
/etc/local/hadoop/sbin/start-all.sh
/etc/local/spark/sbin/start-all.sh

断开:
/etc/hadoop/stop-all.sh
/spark/sbin/stop-all.sh

教程链接

环境搭建错误集锦1
环境搭建错误集锦2
spark集群搭建详细步骤
环境配置
hadoop环境搭建
安装centos虚拟机
spark环境搭建
scala环境搭建:idea

spark杂记

错误解决

WARN TaskSchedulerImpl: Initial job has not accepted any resources; check your cluster uito ensure that workers are registered and have sufficient memory

当前的集群的可用资源不能满足应用程序所请求的资源。
资源分2类: cores 和 ram
Core代表对执行可用的executor slots
Ram代表每个Worker上被需要的空闲内存来运行你的Application。
解决方法:
应用不要请求多余空闲可用资源的
关闭掉已经执行结束的Application

java.lang.IllegalArgumentException: System memory 468189184 must be at least 4.718592E8

通过尝试,发现可以有2个地方可以设置
1. 自己的源代码处,可以在conf之后加上:
val conf = new SparkConf().setAppName(“word count”)
conf.set(“spark.testing.memory”, “2147480000”)//后面的值大于512m即可
2. 可以在Eclipse的Run Configuration处,有一栏是Arguments,下面有VMarguments,在下面添加下面一行(值也是只要大于512m即可)
-Dspark.testing.memory=1073741824
其他的参数,也可以动态地在这里设置,比如-Dspark.master=spark://hostname:7077
再运行就不会报这个错误了。

Exception in thread “main” java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

解决方案:
在spark-env.sh文件中添加:
export SPARK_DIST_CLASSPATH=$(hadoop classpath)

linux 命令

任务管理器查看

top命令查看内存、cpu等系统信息,按q可推出查看

防火墙设置

//查看防火墙状态
sudo service iptables status
//关闭防火墙
sudo service iptables stop
//打开防火墙
sudo service iptables start

linux下环境变量设置

vi ~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取
http://www.cnblogs.com/mengyan/archive/2012/09/04/2669894.html

查看Linux某用户属于哪个组

id user
groups user

不启动 YARN 需重命名 mapred-site.xml

如果不想启动 YARN,务必把配置文件 mapred-site.xml 重命名,改成 mapred-site.xml.template,需要用时改回来就行。否则在该配置文件存在,而未开启 YARN 的情况下,运行程序会提示 “Retrying connect to server: 0.0.0.0/0.0.0.0:8032” 的错误,这也是为何该配置文件初始文件名为 mapred-site.xml.template。

Scala在spark中的运用

概念

RDD

>
RDD(Resilient Distributed Datasets)[1] ,弹性分布式数据集, 是分布式内存的一个抽象概念,RDD提供了一种高度受限的共享内存模型,即RDD是只读的记录分区的集合,只能通过在其他RDD执行确定的转换操作(如map、join和group by)而创建,然而这些限制使得实现容错的开销很低。对开发者而言,RDD可以看作是Spark的一个对象,它本身运行于内存中,如读文件是一个RDD,对文件计算是一个RDD,结果集也是一个RDD ,不同的分片、 数据之间的依赖 、key-value类型的map数据都可以看做RDD。

闭包

>
闭包是指可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)。在PHP、Scala、Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Ruby、 Python、Go、Lua、objective c、swift 以及Java(Java8及以上)等语言中都能找到对闭包不同程度的支持。

外部数据集

>
spark支持文本文件(text files)、sequenceFiles和其他hadoop inputformat。

支持文件目录,压缩文件和通配符,如:
textFile(“my/文件目录”),textFile(“my/文件目录/.txt”)和textFile(“my/文件目录/.gz”)

部分API:
SparkContext.sholeTextFiles:读取一个包含多个小文本文件的文件目录,并返回每一个(filename,content)对,与textFile的差异是:它记录每个文件的每一行
sequenceFile[key,values]:创建SequenceFiles
SparkContext.hadoopRDD:创建hadoop inputformats,可指定任意的JobConf
RDD.saveAsObjectFile和SparkContext.objectFile支持保存一个RDD,保存格式是一个简单的Java对象序列化格式。

RDD操作:

>
支持两种操作:
转换(transformations):从已存在的数据集中创建一个新的数据集
动作(actions):在数据集上进行计算后返回一个值到驱动程序
转换仅在这个时候计算:当动作需要一个结果返回给驱动程序
可以使用persistcache方法持久化一个RDD到内存,执行动作时,此RDD就不需要重新计算,如:

val lines = sc.textFile("data.txt")
val lineLengths = lines.map(s => s.length)
val totalLength = lineLengths.reduce((a,b) => a+b)
//存入内存
lineLengths.persist()

传递函数到Spark

>
- 匿名函数
- 全局单例对象里的静态方法

object MyFunctions{
        def func1(s:String):
                String = {...}
}
myRdd.map(MyFunctions.func1)

使用键值对

>
在键值对上使用reduceByKey操作来统计在一个文件里每一行文本内容出现的次数

val lines = sc.textFile("data.txt")
val pairs = lines.map(s => (s,1))
val counts = pairs.reduceByKey((a,b) => a+b)
//将键值对按照字母进行排序
counts.sortByKey()

常用Transformations

>
- map(func):返回一个新的分布式数据集,将数据源的每一个元素传递给函数func映射组成
- filter(func):返回一个新的数据集,从数据源中选中一些元素通过函数func返回true
- flatMap(func):类似于map,但每个输入项都能被映射成多个输出项(func必须返回一个seq)
- mapPartitions(func):类似于map,但是分别运行在RDD的每个分区上,func类型必须是Iterator\

常用Actions

>
- reduce(func)
- collect()
- count()
- first()
- take(n)
- takeSample(withReplacement,num,[seed])
- takeOrdered(n,[ordering])
- saveAsTextFile(path)
- saveAsSequenceFile(path)
- saveAsObjectFile(path)
- countByKey()
- foreach(func)

RDD持久化

通过各种操作持久化(或者缓存)一个集合到内存中。下次使用时不需要重复计算
spark的缓存是一个容错的技术,若RDD的任何一个分区丢失,它可以通过原有的转换操作自动重复计算并且创建这个分区

不同存储级别

持久化集合到磁盘、集合作为序列化的java对象持久化到内存、节点间复制集合或者存储集合到tachyon中。

  • MEMORY_ONLY:系统默认存储级别:将RDD作为序列化的java对象存储到jvm。分区不被缓存
  • MEMORY_AND_DISK:将RDD作为非序列化的java对象存储到jvm中。分区被缓存到磁盘
  • MEMORY_ONLY_SER:将RDD作为序列化的java对象存储(一个分区一个byte数组)
  • MEMORY_AND_DISK_SER:和MEMORY_ONLY_SER类似,分区存到磁盘
  • DISK_ONLY:仅仅将RDD分区存储到磁盘
  • MEMORY_ONLY_2,MEMORY_AND_DISK_2:RDD分区存到磁盘,但是复制每个分区到集群的两个节点
  • OFF_HEAP(experimental):序列化格式存储RDD到tachyon中

存储级别的选择

内存利用率与cpu利用效率之间进行权衡

  • MEMORY_ONLY:cpu利用率最高
  • MEMORY_ONLY_SER:选择更快序列化提高对象的空间使用率
  • 除非函数计算RDD花费大或者需要过滤大量数据,否则不要将RDD存储到磁盘
  • 更快的错误恢复:利用重复存储级别
  • 大量内存环境或多应用程序的环境中,OFF_HEAP具有优势:1.运行多个执行者共享tachyon中相同的内存池,2.显著减小垃圾回收的花费,3.单个执行者崩溃,缓存的数据不会丢失

删除数据

Spark会利用最近最少原则删除老旧的数据,若想手动删除,可以使用RDD.unpersist()

共享变量

两种:广播变量和累加器

广播变量

允许程序员缓存一个只读的变量在每台机器上面,而不是每个任务保存一份拷贝。利用广播变量,能以高效方式将大数据量输入集合的副本分配给每个节点。

SparkContext.broadcast(v):从一个初始变量v中创建。

val broadcastVar = sc.broadcast(Array(1,2,3))
broadcastVar.value

累加器

只能通过关联操作进行“加”操作,具有高效并行性。

  • 利用累加器将数组里所有元素相加
     
    //从初始变量v创建累加器
    val accum = sc.accumulator(0,"my accumulator")
    sc.parallelize(Array(1,2,3,4)).foreach(x => accum += x)
    //只能使用value方法来读取累加器的值
    accum.value
  • 利用AccumulatorParam创建自己的累加器类型
     
    object VectorAccumulatorParam extends AccumulatorParam[Vector]{
    //提供一个“0值”
    def zero(initialvalue:Vector):Vector = {
    Vector.zeros(initialValue.size)
    }
    //计算两个值的和
    def addInPlace(v1:Vector,v2:Vector):Vector = {
    v1 += v2
    }
    }
    //创建累加器
    val vecAccum = sc.accumulator(new Vector(...))(VectorAccumulatorParam)

简单实例

程序从监听TCP套接字的数据服务器获取文本数据,然后计算文本中包含的单词数

import org.apache.spark._
import org.apache.spark.streaming._
import org.apache.spark.streaming.StreamingContext._
//创建一个具有两个执行线程以及一秒批间隔时间的本地StreamingContext
val conf = new SparkConf().setMaster("local[2]").setAppName("NetworkWordCount")
val ssc = new StreamingContext(conf,Seconds(1))
//创建一个DStream,表示从TCP源(主机localhost,端口9999)获取流式数据
val lines = ssc.socketTextStream("localhost",9999)>//lines变量是一个DStream,表示即将从数据服务器获取得到的流数据。
//这个DStream的每条记录都代表一行文本。
//将DStream中的每行文本都切分成单词
//flatMap是一对多的DStream操作,把源DStream的每条记录都生成多条新纪录来创建新DStream。
val words = lines.flatMap(_.split(" "))
//计算单词的个数:
//words转换成(word,1),利用转换后新的DStream计算每批数据的词项,最后打印每秒计算的词频
val pairs = words.map(word => (word,1))
val wordCounts = pairs.reduceByKey(_ + _)
wordCounts.print()
//开始执行计算
ssc.start()
ssc.awaitTermination()

运行步骤
- 运行Netcat作为数据服务器:nc -lk 9999
- 终端输入:./bin/run/example streaming.NetworkWordCount localhost 9999

关联

maven仓库

Maven中的仓库用来存放生成的构建和各种依赖。

\
###初始化StreamingContext >Spark Streaming所有流操作的主要入口,可以用SparkConf对象创建 >
>import org.apache.spark._
>import org.apache.spark.streaming._
>//appName表示应用显示杂集群UI的名字
>//master是Spark、Mesos
>val conf = new SparkConf().setAppName(appName).setMaster(master)
>val ssc = new StreamingContext(conf,Seconds(1))
>

>

你可能感兴趣的:(大数据)