Spark学习
spark core
图中有4个map task和3个reduce task.
1、切片、默认一个block块对应一个切片。
2、执行自定义的map逻辑。
3、将数据写入内存环形缓冲区(100M)。
4、当达到80M的时候会溢写到磁盘,生成一个文件。
- 对数据做分区和排序
- hash分区 :key.hashcode%reduce数量
- shuffle:将相同的key分到同一个reduce中,并不代表同一个reduce只有一个key的数据。
- 快速排序。
5、合并多个小文件,归并排序
一个map task 执行完成:每一个map task都会产生一个文件。
6、当所有的map task执行完成之后开始执行 reduce task 。reduce task 在执行之前会先去map task 所在的节点拉取数据。
7、合并多个文件
8、执行自定义的reduce逻辑每一个key执行一次
- 每一个reduce task会在hdfs中产生一个文件。
spark运行模式
local:多用于测试
Standalone
Mesos
Yarn:最具前景
RDD五大特性
package com.shujia.spark.core import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} object Demo1WordCount { def main(args: Array[String]): Unit = { /** * 1、建spark环境 */ //spark环境配置对象 val conf = new SparkConf() //设置spark项目名称 conf.setAppName("WordCount") //设置运行环境 conf.setMaster("local") //创建spark上下文对象,sc是spark写代码的入口 val sc = new SparkContext(conf) /** * 2、读取文件 * * RDD:弹性的分布式数据集,现阶段可以当成list集合使用 */ val linesRDD: RDD[String] = sc.textFile("data/words.txt") /** * 3、将单词展开 */ val flatRDD: RDD[String] = linesRDD.flatMap(line => line.split(",")) /** * 4、分组 */ val groupByRDD: RDD[(String, Iterable[String])] = flatRDD.groupBy(word => word) /** * 5、统计单词数量 */ val wordCount: RDD[String] = groupByRDD.map { case (word: String, iter: Iterable[String]) => val count: Int = iter.size s"$word\t$count" } /** * 6、保存数据 */ wordCount.saveAsTextFile("data/wordCount") } }
RDD五大特性
- 1、RDD由一组分区组成,读取文件默认一个black块对应一个分区,后面的rdd的分区数和前面的rdd一样。
- 2、函数实际上是作用在每个分区上的,一个分区由一个task处理,有多少个分区就有多少个task。写代码是基于RDD写的代码,最终运行时,算子是作用在分区上的
- 3、RDD之间有依赖关系,宽依赖和窄依赖,有shuffle是宽依赖,没有shuffle是窄依赖。宽依赖前是一个Stage,宽依赖后是一个Stage(map或reduce端)
- 4、分区类的算子只能作用在KV格式的RDD上,groupByKey,reduceByKey.
- 5、Spask为task的计算提供了最佳的计算位置,移动计算而不是移动数据。
RDD中默认是没有数据的,数据在shuffle阶段会落地,在其他阶段数据会流过去。
RDD的分区数
分区数越多,并行度越高,在资源充足的情况下效率越高
- 1、读取文件,默认等于切片的数量。
- 2、读取文件可以设置最小分区数minPartitions,控制RDD的分区数,只能在切片数的基础上,增加分区数,不能减少分区数。原则是需要保证每一个分区的数据量差不多
- 3、窄依赖的算子不能改变分区数,默认等于前一个RDD的分区数。
- 4、宽依赖的算子分区数默认等于前一个RDD的分区数,也可以手动设置分区数。
Spark常用算子
转换算子:Transformations
转换算子:将一个RDD转换成另一个RDD, 转换算子是懒执行,需要一个action算子来触发执行
-
map:将RDD的数据一条一条传递给后面的函数,函数的返回值构建成一个新的RDD。
- map是算子不会改变总的数据函数
-
filter:将RDD的数据一条一条传递给后面的函数,如果函数返回true保留数据,函数返回false过滤数据。
- filter会减少RDD的数据行数。
-
flatMap:将RDD的数据一条一条传递给后面的函数,函数的返回值必须是一个集合,最后会将集合展开构建成一个新的RDD
- 一行变多行
-
sample:可以从数据中抽样一部分数据
-
groupBy:按照指定的字段进行分组,返回一个KV格式的RDD,key是分组的字段,value是一个迭代器。迭代器的数据没有完全加载到内存中,迭代器只能迭代一次。groupBy算子需要将相同的key分到同一个分区中,所以会产生shuffle。
-
groupByKey:按照key进行分组
- groupBy和groupByKey的区别
1、代码:groupBy可以在任何类型的RDD上使用,groupByKey只能作用在kv格式的RDD上
2、groupByKey之后RDD的结构相对简单一点
3、性能:groupByKey shuffle过程需要传输的数据量比groupBy小,性能更高
- groupBy和groupByKey的区别
-
reduceByKey:按照key对value做聚合,需要一个聚合函数,reduceByKey也会产生shuffle
reduceByKey会在map端做预聚合,预聚合之后shuffle过程需要传输的数据量减少,性能更高。
尽量使用reduceByKey代替groupByKey
reduceByKey没有groupByKey灵活
-
union:合并两个RDD,两个RDD的类型要一致,不会对数据去重。union只是在逻辑层面合并了,物理层面没有合并。合并之后新的RDD的分区数等于前面两个RDD分区数之和。
-
join:
- inner join :内关联,两边都有才能关联上
- left join :左关联,以左表为基础,如果右表没有数据,补null
- Option: 两个取值,有值或者None, 如果没有关联上,就是None
- full join : 全关联,只要有一边有数据就会出结果,如果另一边没有,补null
-
sortBy:指定一个字段进行排序,默认是升序。ascending = false 降序。
-
mapValue:对value做处理,可以不变。
-
mapPartitions:一次处理一个分区的数据,将一个分区的数据一个一个传递给后面的函数,迭代器中是一个分区的数据,函数的返回值也需要是一个迭代器。mapPartitionsWithIndex: 对了一个分区的编号。
操作算子:Actions
操作算子:触发任务执行,一个action算子会触发一次任务执行, 同时每一个ation算子都会触发前面的代码执行
- action算子,action算子的返回值不是一个rdd, 每一个action算子都会触发一个job执行
- foreach:循环RDD
- saveAsTextFile:保持数据
- count:统计行数
- collect:将rdd转换成集合。当处理的数据量很大时,会导致内存溢出
- take:取top
- reduce:全局聚合
- sum:求和,rdd必须可以求和
spark缓存
-
Cache:对多次使用的RDD进行缓存
checkpoint:将rdd的数据缓存到hdfs中,任务失败了数据也不会丢失
cache:是将数据缓存再spark执行的服务器的内存或者磁盘上,如果任务执行失败数据就没了
checkpoint: 主要是再spark streaming中使用,用来保证任务的高可用
spark独立集群
1、上传解压,配置环境变量 配置bin目录
解压
tar -xvf spark-2.4.5-bin-hadoop2.7.tgz
重命名
mv spark-2.4.5-bin-hadoop2.7 spark-2.4.5
配置环境变量
vim /etc/profile
2、修改配置文件 conf
cp spark-env.sh.template spark-env.sh
增加配置
export SPARK_MASTER_IP=master
export SPARK_MASTER_PORT=7077
export SPARK_WORKER_CORES=2
export SPARK_WORKER_INSTANCES=1
export SPARK_WORKER_MEMORY=2g
export JAVA_HOME=/usr/local/soft/jdk1.8.0_171
master相当于RM worker相当于NM
增加从节点配置
cp slaves.template slaves
node1
node2
增加从节点
3、复制到其它节点
scp -r spark-2.4.5 node1:`pwd`
scp -r spark-2.4.5 node2:`pwd`
4、在主节点执行启动命令
启动集群,在master中执行
./sbin/start-all.sh
http://master:8080/ 访问spark ui
- standalone client模式 日志在本地输出,一般用于上线前测试(bin/下执行)
需要进入到spark-examples_2.11-2.4.5.jar 包所在的目录下执行
cd /usr/local/soft/spark-2.4.5/examples/jars
提交spark任务
spark-submit --class org.apache.spark.examples.SparkPi --master spark://master:7077 --executor-memory 512m --total-executor-cores 1 spark-examples_2.11-2.4.5.jar 100
2、standalone cluster模式 上线使用,不会再本地打印日志
spark-submit --class org.apache.spark.examples.SparkPi --master spark://master:7077 --executor-memory 512M --total-executor-cores 1 --deploy-mode cluster spark-examples_2.11-2.4.5.jar 100
spark-shell spark 提供的一个交互式的命令行,可以直接写代码
spark-shell master spark://master:7077
整合yarn
在公司一般不适用standalone模式,因为公司一般已经有yarn 不需要搞两个资源管理框架
停止spark集群
在spark sbin目录下执行 ./stop-all.sh
spark整合yarn只需要在一个节点整合, 可以删除node1 和node2中所有的spark 文件
1、增加hadoop 配置文件地址
vim spark-env.sh
增加
export HADOOP_CONF_DIR=/usr/local/soft/hadoop-2.7.6/etc/hadoop
2、往yarn提交任务需要增加两个配置 yarn-site.xml(/usr/local/soft/hadoop-2.7.6/etc/hadoop/yarn-site.xml)
先关闭yarn
stop-all.sh
cd /usr/local/soft/hadoop-2.7.6/etc/hadoop
vim yarn-site.xml
3、增加配置
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>false</value>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
4、同步到其他节点,重启yarn
scp -r yarn-site.xml node1:`pwd`
scp -r yarn-site.xml node2:`pwd`
启动yarn
start-all.sh
cd /usr/local/soft/spark-2.4.5/examples/jars
3.spark on yarn client模式 日志在本地输出,一班用于上线前测试
spark-submit --class org.apache.spark.examples.SparkPi --master yarn-client spark-examples_2.11-2.4.5.jar 100
4.spark on yarn cluster模式 上线使用,不会再本地打印日志 减少io
spark-submit --class org.apache.spark.examples.SparkPi --master yarn-cluster spark-examples_2.11-2.4.5.jar 100
获取yarn程序执行日志 执行成功之后才能获取到
yarn logs -applicationId application_1560967444524_0003
hdfs web ui
http://node1:50070
yarn ui
http://node1:8088
spark client和cluster
到
yarn logs -applicationId application_1560967444524_0003
hdfs web ui
http://node1:50070
yarn ui
http://node1:8088