走进Spark的世界
简单了解一下Spark吧
首先,Spark是一个同时兼具离线批处理和实时流处理的数据执行引擎,其中Spark使用了DAG这样的逻辑执行计划,其大大优化了Spark的执行效率。
然后,我在这里贴出Spark的官网地址:http://spark.apache.org,想要了解一个软件的最好方法就是直接去它官网翻看它的一切。而官网又分了四个小节来介绍Spark,我们下面来详细阅读下这些简介,并和MapReduce进行一些比较。
速度
我们先简单了解一下MapReduce的一些基础。MapReduce分为map和reduce这两个部分(当然中间还有一个shuffle过程,但这里我们就把它算到reduce当中去吧),无论是map还是reduce都是一个task并且这个task是一个进程,所以我们可以总结MapReduce是基于进程,在这个过程就涉及到进程的开启和销毁了,而这些都是很耗性能的,所以这也是Spark比MapReduce快的原因。即使我们使用JVM的重用(Hadoop调优的方向)也不会比提升性能到哪里。由于MapReduce过程还会有数据落地的情况,其极大拖慢的速度和增加了磁盘IO。举个例子吧:1+1+1+1,这个过程MapReduce就是先计算出2再加1等到3再加1等到4,每次都把数据落地。Ps:并且MapReduce只有map和reduce算子,编程的过程是及其痛苦的。
那么Spark呢?不用质疑,Spark肯定就是基于线程的,在理论上是比MapReduce好很多的啦。并且上面所说的Spark是又一个DAG的逻辑执行计划的,其很好的优化了Spark的执行性能,过程就是一个pipeline(数据有时候是不用落地磁盘的,省了磁盘IO的过程,速度自然也就快很多啦),同样上面的1+1+1+1的例子,在Spark里面就可能是直接给你来个4,简单快捷。
易用性
不用我讲你们也知道MapReduce是基于java进行编程的(当然不是说你用python或者其他语言就写不出这样的逻辑,只是我们是要将编好的jar包提交的yarn上面去执行的)。但是Spark就不一样了,你可以使用java,scala,python,R等去编写。
通用性
Spark现在的4个组件:SparkSQL(离线批处理用,还能用SQL来写),SparkStreaming(实时流处理),MILB(机器学习),GraphX(图计算),屌吧!这么多功能…
跑在任意地方
Spark的模式多样化:yarn,Mesos,standalone,K8s,local等。当在使用yarn模式下时Spark就相当于一个客户端,升级起来贼方便。甚至Spark还能直接对JDBC进行数据交互,这样sqoop就没什么用了。
编译Spark
讲了这么久的Spark基础理论(其实这些都可以在官网上读到的,我也不知道我干嘛写这么多,但还是希望读者能好好看看官网或者我的博文),我们来了解下编译Spark的内容:
下载Spark
在1这里我们选择自己要下的Spark版本,然后就是选择要下载的包了,一般生产上面我们都是选择Source Code源码编译,因为在生产上我们可能会修改源码,能如果不编译你这么部署呢?选好了就是3那里进行download了,当然其实最好是从git上clone源码下来,这样我们可以自行控制分支,以后自己编译也方便很多。git的地址是:https://github.com/apache/spark.git,你可以git clone下这个仓库也可以使用命令git branch -v来检查有什么版本,git checkout一个指定的版本。
然后我们就到编译部分了,同样是查看官网:
进入到这个选项里面去后,里面提醒我们:The Maven-based build is the build of reference for Apache Spark. Building Spark using Maven requires Maven 3.5.4 and Java 8. Note that support for Java 7 was removed as of Spark 2.2.0.
要使用jdk1.8和maven3.5.4,所以你们懂的。
编译的参数
spark2.4.0.tgz这个包解压后里面就自带有一个mvn,在build这个目录下的,但是我们还是使用自己的maven来编译。又一个但是,在生产当中我们不使用maven直接编译而是到这个包下面的dev目录下执行一个make-distribution.sh的脚本命令。
官网上提供的执行命令如下:
./dev/make-distribution.sh --name custom-spark --pip --r --tgz -Psparkr -Phadoop-2.7 -Phive -Phive-thriftserver -Pmesos -Pyarn -Pkubernetes
但是这些参数是什么鬼啊?我们在git上直接打开这个脚本命令来看下究竟是些什么呢?
来这里的参数是不是和我们上面那条命令的参数很相似,MAKE_TGZ=false
MAKE_PIP=false
MAKE_R=false
NAME=none
MVN="$SPARK_HOME/build/mvn"
看你有没有指定tgz,pip,r,name是什么,然后执行了MVN="$SPARK_HOME/build/mvn,就是调用这个包下的maven嘛。当然我们不是用python和r,所以可以去掉–pip和–r这两个参数,–name就是给一个编译好以后的包名呗。
好,我们接着看,-Phadoop-2.7这个参数是什么?我们就要去这个包下的pom.xml文件中看看了,找到一个profiles的地方好好看看:
就是这里这些参数了,-P后面指定的参数都是这里被括起来的参数了,但是这个Spark的最新版本没有hadoop-2.6了,估计其他分支是有的。但是看到这里只是指定了hadoop-2.7而已(我们用hadoop-2.6啊),没有具体的版本号呀怎么办(即使是hadoop-2.7也就指定了某些具体的),所以我们还需要一个参数-Dhadoop.version=2.6.0-cdh5.7.0来表明具体的版本号:
当然,这里没列完啊,我们来指定自己需要的,但是由于maven的中央仓库可能没有cdh的版本,所以我们需要在这个pom.xml文件的repository里面添加多一条命令用来告诉指定还可以从cdh的仓库来下载,那我们在那里指定呢?看图:
就在这添加吧,但是一定要在maven的中央仓库下面添加啊,这里的这一句话已经提示了我们了:
,那么添个啥呢?
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
这样就好啦,现在我们开始编译吧,第一次编译的时候肯定很慢尤其是要检查版本号等,所以我们其实可以注释掉make-distribution.sh脚本里面的一些命令行,再添加些写好的参数进去,这样就不会检查本机的环境变量配置了,我们回到make-distribution.sh脚本里面看看是哪些是要被注释的:
就是这些了,用#号注释掉,然后在下面添加:
VERSION=2.4.0
SCALA_VERSION=2.11
SPARK_HADOOP_VERSION=2.6.0-cdh5.7.0
SPARK_HIVE=1
当然,你自己的编译所用的版本参数可以自由定义,就是这里的参数需要和你执行./make-distribution.sh 后面指定的参数一致。
最后输出的名字是啥呢?看这里:
tardir_name是这样的组成的:spark-version(你的spark的版本号) + bin + $name(你指定的名称,一般我们指定hadoop的版本号),然后定义TARDIR这个变量是$SPARK_HOME目录下的$TARDIR_NAME目录,然后删除$TARDIR这个变量所指定的目录,接着copy $DISTDIR这个变量的目录到$TARDIR这个变量所指定的目录,再执行这段代码(不知道能不能算代码呢)
tar czf "spark-$VERSION-bin-$NAME.tgz" -C "$SPARK_HOME" "$TARDIR_NAME"
最后删除$TARDIR这个目录。
如果在生产中你只想编译某一个组件的话也可以这样执行:
./build/mvn -pl:spark-streaming_2.11 clean install
idea中添加Spark依赖
添加到项目的pom.xml里面
groupId:org.apache.spark
artifactId:spark-core_2.11
version:2.4.0
这样就可以在idea里面些Spark程序了