Spark基础篇(一) - 概述&&源码编译

第一章:Spark的产生背景 <-- MapReduce的局限性

第二章:Spark概述及特点

第三章:自定义编译Spark

第一章:MapReduce的局限性–>Spark的产生

  1. 繁杂,不管是开发还是测试代码,即使写一个wordcount都需要借助于map和reduce;

  2. 计算效率是低的,基于如下几个方面:

  • mapreduce是基于进程级别的:有一堆的mapTask和reducetask;
  • IO:会出现频繁的网络和磁盘IO,比如第一个作业的输出作为第二个作业的输入,需要借助chain写到hdfs上
  • Mapreduce的执行流程,每个阶段都会排序,但是有很多场景排序是没有必要的
  1. 所以综上它不适合迭代处理,不适合实时处理,mapreduce只适合离线处理
各个框架单独为战&&使用Spark框架做比较:

在这里插入图片描述
解析:
1、通常情况从HDFS上读取数据,通过ETL之后,再把数据写回HDFS上,这一步使用Hadoop/Mapreduce;接下来我们要做一个机器学习相关的功能,使用Mahout来解决,同样的设计到hdfs的读和写;第三步我们要做一个查询操作,使用Hive,每次都会涉及到Hadoop的读和写;

2、如果使用Spark来解决问题的话,只涉及到Hdfs的读 --> ETL操作,中间来进行Train,最后一步进行一些查询,结果还是落地到HDFS上;

  • 第一步与第二步,第二步与第三步之间都使用RDD/DF/DS

  • 相比而言肯定是使用第二套环境更好的

第二章:Spark概述及其特点

2.1、四大特性(Speed、Ease Of Use、Generality、Runs Everywhere)

  • 官网:spark.apache.org

Apache Spark is a unified analytics engine for large-scale data processing.(Apache Spark是一个用于大规模数据处理的统一分析引擎)

1、Speed:速度快
Apache Spark achieves high performance for both batch and streaming data, using a state-of-art DAG scheduler, a query optimizer, and a physical execution engine.

  • spark无论对于批处理、流处理,使用最先进的DAG图,查询优化器和一个物理执行引擎。
体现在如下几个方面:
memory
thread
sort	可排序可不排序
DAG	rdd.map.filter....		lazy操作,必须触发action	--> 流水线式的,pipeline

2、Ease of Use:易用性
Write application quickly in Java, Scala, Python, R, and SQL

Spark offers over 80 high-level operators that make it easy to build parallel apps. And you can use it interactively(交互式的) from the Scala, Python, R, and SQL shells.

  • 提供了超过80个高级别的算子,比如在Hive中的join、groupby、count在Spark中是都有提供的,所以使用起来非常的方便。

df = spark.read.json(“logs.json”) df.where(“age > 21”).select (“name.first”).show()

  • Spark’s Python DataFrame API Read JSON files with automatic schema inference

3、Generality:通用性
Combine SQL, streaming, and complex analytics.

Spark powers a stack of libraries including SQL and DataFrames, MLlib for machine learning, Graphx, and Spark Streaming. You can combine these libraries seamlessly in the same application.

  • Spark提供了强有力的栈包括了很多库(SQL和DataFrames)
    在这里插入图片描述

4、Runs Everywhere:可以运行在任何地方

Spark runs on Hadoop, Apache Mesos, Kubernetes, standalone, or in the cloud. it can access diverse data sources.

You can run Spark using its standalone cluster mode, on EC2, on Hadoop YARN, on Mesos, or on Kubernetes. Access data in HDFS, Alluxio, Apache Cassandra, Apache HBase, Apache Hive, and hundreds of other sources.

1、Spark能够跑在不同的运行模式上,此处的Hadoop指的是hdfs存储,更多的是指yarn;它支持多样的数据源,Spark可以直接对接亚马逊s3;对于早期起步的大数据公司,Hadoop可以理解为大数据的代表;

2、数据肯定是存放在hdfs上的,如果新出的框架不支持HDFS的读写,该怎么办,直接不用。
解决:直接在机器上装一个Spark,不需要做任何数据的迁移。
  • Spark SQL的外部数据源是核心

Spark小结:
fast + general + engine
write code: java/scala/python/R
run: memory/DAG/thread mode

2.2、Spark版本介绍

接下来的学习部署统一都使用Spark2.4.2版本,2.4.2的含义:
2:major version:APIs change
4:minor version:APIs/features add
2:patch version:only bug fixes
第三位选择:最好选择非0的,因为bug未被修复过

第三章:自定义编译的Spark

1、前置条件:

scala-2.11.12、apache-maven-3.5.4、下载spark源码进行编译:

2、修改版本进行跳过检测&&修改仓库地址:

1、vi编辑$SPARK_HOME/dev/make-distribution.sh 文件
# that is 128~146 Lines
#VERSION=$("$MVN" help:evaluate -Dexpression=project.version $@ 2>/dev/null\
# | grep -v "INFO"\
# | grep -v "WARNING"\
# | tail -n 1)
#SCALA_VERSION=$("$MVN" help:evaluate -Dexpression=scala.binary.version $@ 
2>/dev/null\
# | grep -v "INFO"\
# | grep -v "WARNING"\
# | tail -n 1)
#SPARK_HADOOP_VERSION=$("$MVN" help:evaluate -Dexpression=hadoop.version $@ 
2>/dev/null\
# | grep -v "INFO"\
# | grep -v "WARNING"\
# | tail -n 1)
#SPARK_HIVE=$("$MVN" help:evaluate -Dexpression=project.activeProfiles -pl sql/hive 
$@ 2>/dev/null\
# | grep -v "INFO"\
# | grep -v "WARNING"\
# | fgrep --count "<id>hive</id>";\
# # Reset exit status to 0, otherwise the script stops here if the last grep finds 
nothing\
# # because we use "set -o pipefail"
# echo -n)

2、添加如下信息来进行修改:
# 为了让编译的时候跳过检测
VERSION=2.4.2 # spark 版本
SCALA_VERSION=2.11 # scala 版本
SPARK_HADOOP_VERSION=2.6.0-cdh5.16.2 #对应的 hadoop 版本
SPARK_HIVE=1 # 支持的 hi

3、修改pom.xml,注释掉原有的仓库地址,添加阿里云和cloudera仓库地址:
<repository>
 <id>maven-ali</id>
 <url>http://maven.aliyun.com/nexus/content/groups/public//</url>
 <releases>
 <enabled>true</enabled>
 </releases>
 <snapshots>
 <enabled>true</enabled>
 <updatePolicy>always</updatePolicy>
 <checksumPolicy>fail</checksumPolicy>
 </snapshots>
 </repository>
 <repository>
 <id>cloudera</id>
 <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
 </repository>

3、进行编译:

./dev/make-distribution.sh \
--name cdh5.16.2 \
--tgz \ 
-Dhadoop.version=2.6.0-cdh5.16.2 \
-Phadoop-2.6 \ 
-Phive \ 
-Phive-thriftserver \ 
-Pyarn

解释:-name指的是编译出来的包名
-tgz指的是编译出来后打包
-Phadoop-2.6、-Dhadoop.version=2.6.0-cdh5.7.0打的包支持集成Hadoop相关的服务
-Pyarn打的包支持yarn
-Phive打的包支持hive
-Phive-thriftserver打的包支持hive相关服务

编译完成后会在$SPARK_HOME下出现一个目录:spark-2.4.2-bin-cdh5.16.2.tgz

3.1、Spark目录解读

1、bin目录:存放脚本,主要是spark-shell
2、sbin:启动服务
3、jars:存放jar包
4、conf:配置目录

在我们的整套Spark课程中需要使用的命令:

  • spark-shell
  • spark-submit
  • beeline
  • spark-sql

如何查看命令帮助:
Spark-shell --help ==> 查看命令帮助
./spark-shell直接进行启动

1、修改Spark的日志级别:
拷贝一份配置文件:cp $SPARK_HOME/conf/log4j.properties.template log4j.properties
修改配置文件:vi log4j.properties --> 修改log4j.rootCategory = INFO,console 改为自己想要的日志级别。

2、SparkContext(sc)
概念:是Spark应用程序的入口

3、WebUI在4040端口上
spark-shell Application UI <-- 名字

4、master=local[*]
master是用来设置spark应用程序以什么样的方式运行;local表示本地
扩展:spark://host:port standalone
mesos://host:port Yarn
yarn Hadoop\YARN
k8s://https://host:port k8s

5、local[*]

  • *表示所有线程,一般设置为2就行了

6、application id
对应在4040端口上面的environment页面

7、spark-session
暂时可以理解为一个大框

小结:spark-shell底层调用的就是spark-submit

3.2、在Spark客户端上完成一个wordcount

1、在spark-shell中测试:

2、读入文件:
val file = sc.textFile(“file://home/hadoop/data/ruozeinput.txt”)

3、flatMap将每个单词压扁:
file.flatMap(_.split("\t")).collect

4、为每个单词赋上一个1:
file.flatMap(.split("\t")).map((_,1)).collect

5、进行reduce操作,将相同的key进行分发:
(a,1) (a,1) (a,1) (b,1) ⇒ (a,<1,1,1>)、(b,1)

file.flatMap(.split("\t")).map(,1).reduceByKey(+).collect

需求:对这个wordcount进行降序排列
sortby是按照key来排序的,但是目前次数是在value位置上,所以我们要交换位置:

第一步:

  • val result = file.flatMap(.split("\t")).map(,1).reduceByKey(+)

结果:

scala> result.collect
res1: Array[(String, Int)] = Array((hello,2), (world,2), (jepson,1), (ruoze,1))

第二步:

  • result.map(x => (x._2,x._1)).sortByKey(false).map(x => (x._2,x._1)).collect

结果:

scala> result.map(x =>(x._2,x._1)).sortByKey(false).map(x =>(x._2,x._1)).collect
res16: Array[(String, Int)] = Array((hello,2), (world,2), (jepson,1), (ruoze,1))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值