Spark 下载、安装与命令行交互操作起步

        一直以为 spark 与 hadoop 关系密切,最近读了文档才发现 spark 应该看着一个独立的分布式计算框架,于是开始独立尝试(没有 hadoop 环境)。

1. Windows 环境 spark 安装问题

    从官网(http://spark.apache.org/downloads.html)下载 pre-built for hadoop 2.7 版本 spark。解压后运行 bin\pyspark2.cmd,报错:

2018-04-30 23:04:45 ERROR Shell:397 - Failed to locate the winutils binary in the hadoop binary path
java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries.
        at org.apache.hadoop.util.Shell.getQualifiedBinPath(Shell.java:379)
        at org.apache.hadoop.util.Shell.getWinUtilsPath(Shell.java:394)
        at org.apache.hadoop.util.Shell.<clinit>(Shell.java:387)
        at org.apache.hadoop.util.StringUtils.<clinit>(StringUtils.java:80)
        at org.apache.hadoop.security.SecurityUtil.getAuthenticationMethod(SecurityUtil.java:611)
        at org.apache.hadoop.security.UserGroupInformation.initialize(UserGroupInformation.java:273)
        at org.apache.hadoop.security.UserGroupInformation.ensureInitialized(UserGroupInformation.java:261)
        at org.apache.hadoop.security.UserGroupInformation.loginUserFromSubject(UserGroupInformation.java:791)
        at org.apache.hadoop.security.UserGroupInformation.getLoginUser(UserGroupInformation.java:761)
        at org.apache.hadoop.security.UserGroupInformation.getCurrentUser(UserGroupInformation.java:634)
        at org.apache.spark.util.Utils$$anonfun$getCurrentUserName$1.apply(Utils.scala:2464)
        at org.apache.spark.util.Utils$$anonfun$getCurrentUserName$1.apply(Utils.scala:2464)
        at scala.Option.getOrElse(Option.scala:121)
        at org.apache.spark.util.Utils$.getCurrentUserName(Utils.scala:2464)
        at org.apache.spark.SecurityManager.<init>(SecurityManager.scala:222)
        at org.apache.spark.deploy.SparkSubmit$.secMgr$lzycompute$1(SparkSubmit.scala:393)
        at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$secMgr$1(SparkSubmit.scala:393)
        at org.apache.spark.deploy.SparkSubmit$$anonfun$prepareSubmitEnvironment$7.apply(SparkSubmit.scala:401)
        at org.apache.spark.deploy.SparkSubmit$$anonfun$prepareSubmitEnvironment$7.apply(SparkSubmit.scala:401)
        at scala.Option.map(Option.scala:146)
        at org.apache.spark.deploy.SparkSubmit$.prepareSubmitEnvironment(SparkSubmit.scala:400)
        at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:170)
        at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:136)
        at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)


嗯,找不到 winutils,去github(https://github.com/steveloughran/winutils)克隆下来,设置环境变量:

SET HADOOP_HOME=D:\ws\winutils\hadoop-2.7.1

SET PATH=%PATH%;%HADOOP_HOME%\bin

再次运行,spark logo不断闪屏:

Spark 下载、安装与命令行交互操作起步

    然后进入 winutils 项目的 hadoop-2.7.1\bin目录:删掉除 winutils.exe 外的exe文件,xml文件后,重新进入命令行执行,运行 pyspark 或 pyspark2 进入了交互模式。

    对于出现这个问题的原因暂时没有深究,估计因为我下载的是 pre-built for hadoop 2.7 版本 spark 导致。以后有空会使用 pre-built for user provided apache hadoop 进行确认。

2. Linux 环境下的 spark 安装问题

    Ubuntu 18.04 LTS 版本 4月26日 release ,于是立即下载了优麒麟 18.04 来尝鲜。同样下载 pre-built for hadoop 2.7 版本 spark。进入bin/pyspark没啥问题,但是调用spark.createDataFrame报如下错误:

>>> c = spark.createDataFrame(b)
Traceback (most recent call last):                                              
  File "<stdin>", line 1, in <module>
  File "/home/hejiang/app/spark-2.3.0-bin-hadoop2.7/python/pyspark/sql/session.py", line 691, in createDataFrame
    jdf = self._jsparkSession.applySchemaToPythonRDD(jrdd.rdd(), schema.json())
  File "/home/hejiang/app/spark-2.3.0-bin-hadoop2.7/python/lib/py4j-0.10.6-src.zip/py4j/java_gateway.py", line 1160, in __call__
  File "/home/hejiang/app/spark-2.3.0-bin-hadoop2.7/python/pyspark/sql/utils.py", line 79, in deco
    raise IllegalArgumentException(s.split(': ', 1)[1], stackTrace)
pyspark.sql.utils.IllegalArgumentException: u'Unable to locate hive jars to connect to metastore. Please set spark.sql.hive.metastore.jars.'

    根据网友提示查看jdk版本,发现ubuntukylin 18.04默认是openjdk-11-jdk包(java -version显示10.0.1)。于是卸载重新安装openjdk-8-jdk版本后不再报错。

3. 交互操作起步

    Spark 1.X 核心概念是 RDD。RDD 可以用两个方式产生:并行化本地(Driver内)数据集产生,或者从分布式资源加载产生。

    Spark 2.X 核心概念是 DataFrame。DataFrame 的好处是可以使用 SQL(或者类 SQL) 操作数据集。其实这个 Idea 从微软 dotNet 发明 Linq 以来,不断被各种语言演绎,到 Spark 可算炉火纯青了:在数据集上使用简洁的 SQL 语句方便地获取数据,还能直接用于 ML 计算,而这一切都是分布式操作,数据按需在 stage 之间 shuffle,很完美。

     尝试一下:

Spark 下载、安装与命令行交互操作起步

    简单解释如下:

1. 导入需要的模块对象 Row (DataFrame 理解的数据行)

from pyspark.sql import Row 

2. 产生本地数据

a = range(1,10)

3. 并行化数据,然后转换为 DataFrame 喜欢的对象

b = sc.parallelize(a).map(lamda i: Row(col=i))

4. 创建数据集,数据集上可以执行 SQL 语句

c = spark.createDataFrame(b)

5. 打印数据集 schema

c.printSchema()

6. 打印数据集执行计划

c.explain(True)

Spark 下载、安装与命令行交互操作起步

7. 把数据集注册为视图

c.createOrReplaceTempView("ccc")

8. 在数据集上执行 SQL 查询

d = spark.sql("select * from ccc where col > 4 and col < 8")

9. 打印执行计划

 d.explain(True)

10. 执行 SQL 语句,获取结果

d.show()