Spark 指南
Spark 是继 Hadoop 之后新一代的大数据分布式处理平台。它是一个基于内存、容错型的分布式计算引擎,与 Hadoop MapReduce 相比,计算速度要快100倍。 Spark 卓越的用户体验以及统一的技术堆栈基本上解决了大数据领域所有的核心问题,使得 Spark 迅速成为当前最为热门的大数据基础平台。
Spark 提供了多语言支持包括 Scala, Python, Java, R 等,特别适合迭代计算和交互式操作。它在 RDD(Resilient Distributed Dataset,一个容错的、并行的数据结构) 基础之上提供了 Spark streaming 流式计算,结构化数据处理组件 SparkSQL,机器学习库 MLlib 以及图计算 GraphX 等,详情请参阅 Spark 官方网站 。
系统部署架构
与 Hadoop 一样, Spark 采用的是 master/slave 架构。青云既提供纯计算引擎的 Spark 集群,也提供与 Hadoop HDFS 集成的 Spark 集群,后者 Spark 的 worker 节点运行在 Hadoop 的存储 HDFS DataNode 节点上。 如下图所示,青云 Spark 集群分三种节点类型:主节点 (Spark master node 和 Hadoop NameNode),从节点 (Spark worker nodes 和 Hadoop DataNodes) 和客户端 (Driver node)。青云 Spark 目前 采用的是 Standalone cluster manager 进行集群资源管理,用户通过客户端与 Spark、Hadoop 集群交互,用户的 driver program 将运行在 driver node上。详情见下面测试 Spark 章节。
创建 Spark
大数据平台包括 Spark 的运维是非常繁琐的,而在青云上,您可以在2到3分钟创建一个 Spark 集群,集群支持横向与纵向在线伸缩,还提供了监控告警等功能,使得管理集群异常方便。 集群将运行于私有网络内,结合青云提供的高性能硬盘,在保障高性能的同时兼顾您的数据安全。
注解
为了保障数据安全, Spark 集群需要运行在受管私有网络中。所以在创建一个 Spark 集群之前,至少需要一个路由器和一个受管私有网络,受管私有网络需要和路由器连接,并开启 DHCP 服务(默认开启)。
第一步:选择基本配置
在创建的对话框中,您需要选择 Spark 版本号、CPU、内存配置,集成 HDFS 与否,节点存储大小,填写名称(可选)和 worker 节点数量等。
注解
主机配置1核2G 和2核4G 仅供测试使用;1个 Worker 节点(无 HDFS) 和2个 Worker 节点(有 HDFS)仅供测试使用。
第二步:配置网络
在配置网络的过程中,首先需要选择 Spark 要加入的私有网络,然后可以为 Spark 中的每个节点指定 IP, 也可以选择“自动分配”,让系统自动指定 IP。
第三步:创建成功
当 Spark 创建完成之后,您可以查看每个节点的运行状态。 如图所示,当节点显示为“活跃”状态,表示该节点启动正常。 当每个节点都启动正常后 Spark 集群显示为“活跃”状态,表示您已经可以正常使用 Spark 服务了。
测试 Spark
Spark 创建完成之后可以测试其可用性。
创建 Spark Driver 主机
首先与创建一个普通主机一样,在您的控制台创建一个基于系统映像 ID 为 bigdata-clientb 的 Ubuntu 主机 (假设主机名为 i-tp5n8o28), 同时需要将该主机加入 Spark 同一私有网络。该主机已经安装了 Spark, Hadoop, JRE 等软件并且做了一些配置的修改。您可以直接用这个主机进行下面的测试。 Spark 集群的主机名是按照不同角色定义的:
- Spark master: <Spark master 节点 ID>-spark-master
- Hadoop NameNode: <Hadoop NameNode 节点 ID>-hadoop-master
- Spark worker: <Spark worker 节点 ID>-slave
假设 Spark master 的 URL 为 spark://skn-8ct52oqk-spark-master:7077。这个 URL 可以在您控制台 Spark 详情页查到,也可以在 Spark 提供的监控页查到(请参考下面的监控告警章节)
注解
由于 Ubuntu 主机名对应 IP 127.0.0.1存在 已知问题。所以先要在 /etc/hosts 文件里把127.0.0.1修改成主机的私网 IP (假设为192.168.107.20),同时还需要加上 Spark master,Hadoop NameNode (集成 HDFS) 和 workers 主机名(可不填)与私网 IP 的信息,改完后的 /etc/hosts 类似于:
192.168.107.20 localhost 192.168.107.20 i-tp5n8o28 192.168.107.77 skn-8ct52oqk-spark-master 192.168.107.88 skn-2pfpy7bo-hadoop-master 192.168.107.99 skn-kflp37ij-slave
测试一
这个测试是求1到1,000,000的和。在客户端主机里先切换成 root 用户(或者每次执行命令前加 sudo -E),然后输入以下命令进入 Spark shell:
cd /usr/local/spark ./bin/spark-shell --master spark://skn-8ct52oqk-spark-master:7077
注解
通常情况下你需要执行下面的命令 。SPARK_EXECUTOR_MEMORY 的大小不能超过节点可用内存,每个节点的可用内存可以通过 spark master 节点的8080端口查到(请参考下面的监控告警章节)。
SPARK_EXECUTOR_MEMORY=2g ./bin/spark-shell --master spark://skn-8ct52oqk-spark-master:7077
等 scala shell 准备好后您可以输入以下代码进行测试。您也可以用 pyspark 进入 python shell,该 shell 启动了 IPython, 您可以利用 IPython 的一些特性如 tab 功能等。
scala>val data = new Array[Int](1000000) scala>for (i <- 0 until data.length) | data(i) = i + 1 scala>val distData = sc.parallelize(data) scala>distData.reduce(_+_)
您能看到类似于这样的结果 res1: Int = 1784293664。
测试二
这个测试是统计 <Spark Home> 下的文件 README.md 中多少行包含单词 Spark, 不过该文件是存放在 Hadoop HDFS 文件系统中, 所以您在创建 Spark 的时候需要选择使用 HDFS。青云 Spark 的 HDFS 在创建的时候自动帮您生成了两个用户: /user/root 和 /user/ubuntu。假设 Hadoop HDFS 的 URL 为 hdfs://skn-2pfpy7bo-hadoop-master:9000,这个 URL 可以在您控制台 Spark 详情页查到, 也可以在 Hadoop 提供的监控页查到(请参考下面的监控告警章节)。您也需要把这个 host 的 IP 信息写到 /etc/hosts 文件里。然后在客户端主机里先切换成 root 用户(或者每次执行命令前加 sudo -E),并执行下面命令把文件上传到 HDFS 中:
cd /usr/local/hadoop bin/hadoop distcp file:///usr/local/spark/README.md hdfs://skn-2pfpy7bo-hadoop-master:9000/user/ubuntu/README.md
如果客户端没打开 Spark shell, 请参考测试一进入 Spark shell,然后输入以下代码测试:
scala>val textFile = sc.textFile("hdfs://skn-2pfpy7bo-hadoop-master:9000/user/ubuntu/README.md") scala>textFile.filter(line => line.contains("Spark")).count()
您能看到类似于这样的结果 res4: Long = 19
测试三
这个测试来自 Spark 官方文档,测试的是 SparkSQL。同样,如果客户端没打开 Spark shell, 请参考测试一进入 Spark shell,然后输入以下代码测试:
scala>val sqlContext = new org.apache.spark.sql.SQLContext(sc) scala>val df = sqlContext.read.json("examples/src/main/resources/people.json") scala>df.show() scala>df.printSchema() scala>df.select("name").show()
您也可以把文件如同测试二一样上传到 HDFS 测试
在线伸缩
增加节点
您可以在 Spark 详细页点击“新增节点”按钮增加 worker,可以对每个新增节点指定 IP 或选择自动分配。
删除节点
您可以在 Spark 详细页选中需要删除的 worker 节点,然后点“删除”按钮。如果您的 Spark 是集成了 HDFS,那么不能一次删除多个节点,只能一个一个的删, 并且必须等到上个节点删除后且 decommission 结束才能删除下一个节点,否则数据会丢失,青云在此操作时会锁定 Spark 集群不让对其进行其它的操作,同时这个 decommission 状态可以从 Hadoop NameNode 的 50070 端口提供的监控信息观察到。Decommission 是在复制即将删除节点上的数据到别的节点上,如果您的数据量比较大,这个过程会比较长。 因为青云的 HDFS 副本因子默认为 2,所以当您的 Spark worker (Hadoop DataNode) 节点数为 3 的时候就不能再删除节点。如果您修改了 HDFS 的副本因子须记住对应的最少节点数, 同时要预先知道其它节点的总硬盘空间足够拷贝删除节点的内容,才能进行删除。
注解
对集成 HDFS 的 Spark,删除节点是一个比较危险的操作,要仔细阅读上面的指南。
纵向伸缩
由于不同类节点压力并不同,所以青云 Spark 支持对 Spark master节点、Hadoop NameNode 和 Spark worker节点分别进行纵向伸缩。通常情况下两个主节点的压力不会太大, 在创建 Spark 的时候我们自动给两个主节点分配较低配置,但随着压力增大您可能需要对这些节点扩容。
升级
目前青云提供最新的版本1.4.1、1.5.0和1.6.0。旧版本的用户可以很方便的升级到新版本(也可以回退到旧版本),先关闭 Spark 集群,然后右键 Spark,点击升级,选择新的版本号,最后启动集群即可。客户端 (driver) 升级可自行在现有的客户端主机里下载 Spark,也可以重新创建一个基于系统映像 ID 为 bigdata-clientb 的 Ubuntu 主机。
监控和告警
Spark 和 Hadoop 提供了丰富的监控信息。如果需要通过公网访问这些信息您需要先在路由器上设置端口转发,同时打开防火墙相应的下行端口。Hadoop NameNode 默认端口是50070, Spark master 默认端口8080提供了集群的信息,Spark driver(您的客户端,一个基于 bigdata-clientb Ubuntu 系统映像创建的主机) 的默认端口是4040,提供了当前运行的 应用监控信息。因此私网可以访问以下 URL:
- http://<Hadoop NameNode private IP>:50070
- http://<spark master private IP>:8080
- http://<spark driver private IP>:4040
同时我们还提供了对每个节点资源的监控和告警服务,包括 CPU 使用率、内存使用率、硬盘使用率等,以帮助用户更好的管理和维护 Spark 集群。
查看 Job History
在运行 Spark 应用的时候,driver 提供了一个 Web URL (4040端口,见 监控和告警) 用于展示应用程序监控信息, 但这个 URL 会随着应用程序的退出而关闭,为查看 Spark 的历史应用程序信息,Spark 提供了 history server。首先您需要在 driver 上配置 history server。
配置 history server
在 driver 的 spark home 的 conf/spark-default.conf 文件里添加如下参数, 青云提供的 driver (您的客户端,一个基于 bigdata-clientb 的 Ubuntu 系统映像创建的主机) 的 spark home 为 /usr/local/spark-<version>,请根据您的 Hadoop 相应地修改下面的 <hadoop-master>。
spark.eventLog.enabled true spark.eventLog.dir hdfs://<hadoop-master>:9000/spark/history spark.eventLog.compress true
上面的 spark.eventLog.dir 和下面的 spark.history.fs.logDirectory 指向的是 HDFS 的地址用来存储历史信息,所以需要先在 HDFS 里创建目录,在 driver 的 hadoop home 下执行如下命令。
./bin/hdfs dfs -mkdir -p hdfs://<hadoop-master>:9000/spark/history
在 spark home 的 conf/spark-env.sh 里添加如下参数
export SPARK_HISTORY_OPTS="-Dspark.history.ui.port=18080 -Dspark.history.retainedApplications=5 -Dspark.history.fs.logDirectory=hdfs://<hadoop-master>:9000/spark/history"
启动 history server
在 spark home 下执行下面命令
./sbin/start-history-server.sh
然后您可以打开 http://<spark-driver>:18080 查看 Job History
参数详解
以下的参数以 spark.history 开头的需要在 spark-env.sh 中的 SPARK_HISTORY_OPTS 中配置,以 spark.eventLog 开头的在 spark-defaults.conf 里配置。
- spark.history.ui.port
默认值:18080,history server 的 WEB 端口
- spark.history.retainedApplications
默认值:50,在内存中保存应用程序历史记录的个数,如果超过这个值,旧的应用程序信息将被删除,当再次访问已被删除的应用信息时需要重新构建页面
- spark.history.updateInterval
默认值:10,单位秒,更新日志相关信息的时间间隔
- spark.history.kerberos.enabled
默认值:false,是否使用 kerberos 方式登录访问 history server,如果设置为 true,就要配置下面的两个属性
- spark.history.kerberos.principal
history server 的 kerberos 主体名称
- spark.history.kerberos.keytab
history server 的 kerberos keytab 文件位置
- spark.history.ui.acls.enable
默认值:false,授权用户查看应用程序信息的时候是否检查 ACL。如果启用,只有应用程序所有者和 spark.ui.view.acls 指定的用户可以查看应用程序信息,否则不做任何检查
- spark.eventLog.enabled
默认值:false,是否记录 Spark 事件,用于应用程序在完成后重构 WEB UI
- spark.eventLog.dir
保存日志相关信息的路径,可以是 hdfs:// 开头的 HDFS 路径,也可以是 file:// 开头的本地路径,注意都需要提前创建
- spark.eventLog.compress
默认值:false,是否压缩 Spark 事件,当 spark.eventLog.enabled 为 true 的时候有效,默认使用的是 snappy