在《Spark2.1.0之运行环境准备》一文中,已经介绍了如何准备好基本的Spark运行环境,现在是时候实践一下,以便于在使用过程中提升读者对于Spark最直接的感触!本文通过Spark的基本使用,让读者对Spark能有初步的认识,便于引导读者逐步深入学习。
在《Spark2.1.0之运行环境准备》一文曾经简单运行了spark-shell,并用下图进行了展示(此处再次展示此图)。
图1 执行spark-shell进入Scala命令行
图1中显示了很多信息,这里进行一些说明:
由于Spark core的默认日志级别是WARN,所以看到的信息不是很多。现在我们将Spark安装目录的conf文件夹下的log4j.properties.template以如下命令复制出一份:
cp log4j.properties.template log4j.properties
并将log4j.properties中的log4j.logger.org.apache.spark.repl.Main=WARN修改为log4j.logger.org.apache.spark.repl.Main=INFO,然后我们再次运行spark-shell,将打印出更丰富的信息,如图2所示。
图2 Spark启动过程打印的部分信息
从图2展示的启动日志中我们可以看到SecurityManager、SparkEnv、BlockManagerMasterEndpoint、DiskBlockManager、MemoryStore、SparkUI、Executor、NettyBlockTransferService、BlockManager、BlockManagerMaster等信息。它们是做什么的?刚刚接触Spark的读者只需要知道这些信息即可,具体内容将在后边的博文给出。
这一节,我们通过word count这个耳熟能详的例子来感受下Spark任务的执行过程。启动spark-shell后,会打开Scala命令行,然后按照以下步骤输入脚本:
输入val lines =sc.textFile("../README.md", 2),以Spark安装目录下的README.md文件的内容作为word count例子的数据源,执行结果如图3所示。
图3 步骤1执行结果
图3告诉我们lines的实际类型是MapPartitionsRDD。
图4 步骤2执行结果
图4告诉我们lines在经过flatMap方法的转换后得到的words的实际类型也是MapPartitionsRDD。
图5 步骤3执行结果
图5告诉我们words在经过map方法的转换后得到的ones的实际类型也是MapPartitionsRDD。
输入val counts = ones.reduceByKey(_ + _),对单词进行计数值的聚合,执行结果如图6所示。
图6 步骤4执行结果
图6告诉我们ones在经过reduceByKey方法的转换后得到的counts的实际类型是ShuffledRDD。
输入counts.foreach(println),将每个单词的计数值打印出来,作业的执行过程如图7和图8所示。作业的输出结果如图9所示。
图7 步骤5执行过程第一部分
图8 步骤5执行过程第二部分
图7和图8展示了很多作业提交、执行的信息,这里挑选关键的内容进行介绍:
图9 步骤5输出结果
图9展示了单词计数的输出结果和最后打印的任务结束的日志信息。
笔者在本文介绍的word count例子是以SparkContext的API来实现的,读者朋友们也可以选择在spark-shell中通过运用SparkSession的API来实现。
有了对Spark的初次体验,下面可以来分析下spark-shell的实现原理了,请看——《Spark2.1.0之剖析spark-shell》