CDH5上离线安装Spark2.3并配置hive on spark2

在先前装的CDH5.14集群中,默认安装的spark是1.6.0版本。我们现在可以现有的集群中再装spark2.x版本,能和spark1.6版本并存。

当前CDH支持的Spark2.X最新版本是Spark2.3.0,目前Apache Spark最近版本是2.3.1,即CDH的版本更新是慢半拍的,但基本上不影响使用。

下面是在CDH中安装Spark2.3的步骤:

这是官方给出安装和升级方法说明:

https://www.cloudera.com/documentation/spark2/latest/topics/spark2_installing.html

 

一. 安装准备
1. 下载所需的安装包
http://archive.cloudera.com/spark2/csd/

SPARK2_ON_YARN-2.3.0.cloudera3.jar

 

http://archive.cloudera.com/spark2/parcels/2.3.0.cloudera3/

SPARK2-2.3.0.cloudera3-1.cdh5.13.3.p0.458809-el6.parcel

SPARK2-2.3.0.cloudera3-1.cdh5.13.3.p0.458809-el6.parcel.sha1

manifest.json

 

说明:要选择相对应的系统、CDH版本

我的系统是CentOS6.7所以选择了el6,都选择cloudera3相应的parcel包

 

2. Spark2.3安装需求
● CDH Versions

● Cloudera Manager Versions

● JDK1.8+

● Scala 2.11, Python 2.7 or higher, Python 3.4 or higher

 

二、安装步骤
1. 上传CSD包到CM节点的/opt/cloudera/csd目录
# chown cloudera-scm:cloudera-scm SPARK2_ON_YARN-2.3.0.cloudera3.jar

 

2. 上传parcel的3个包到CM的/opt/cloudera/parcel-repo目录下
[root@hadoop0 parcel-repo]# ls

SPARK2-2.3.0.cloudera3-1.cdh5.13.3.p0.458809-el6.parcel

SPARK2-2.3.0.cloudera3-1.cdh5.13.3.p0.458809-el6.parcel.sha

manifest.json

 

如之前有manifest.json文件,先把之前的更名后再上传

 

3. 安装JDK1.8
安装Spark2.X必需要安装JDK1.8以上版本,因我们在安装CDH5.14时默认选择安装的是JDK1.7.0_67版本,所以要把JDK进行版本升级。否则在后面在安装spark2时会报错:

Java version 1.8 is required for Spark 2.3.

具体安装过程和报错解决在后面详细介绍。

 

4. 重启CM和集群
# service cloudera-scm-agent restart

 

5. 通过CM安装Spark2
CM页面-> 主机 -> Parcel页面可以看到新的spark2的parcel包

2.3.0.cloudera3-1.cdh5.13.3.p0.458809

然后点击 下载-进行分配-激活

 

6. 在集中添加服务
点击-添加服务,选择Spark2服务

选择一组依赖关系

进行角色分配:

加密这时默认不做选择:

 

进行下步安装

安装完成

完成后启动Spark2服务。

可以看到正常启动

 

7. 测试Spark2-shell
登录Spark2的安节点(hadoop[1-8])

 

 

三、遇到的问题
在集群中安装jdk1.8,修改CDH的JAVA_HOME方法
 

下面解决安装Spark2时出现jdk版本低的问题,

问题:在添加Spark服务进出现下面的错误

 

日志:

hu Aug 30 14:34:08 CST 2018
 
 
using /usr/java/jdk1.7.0_67-cloudera as JAVA_HOME
 
using 5 as CDH_VERSION
 
using /var/run/cloudera-scm-agent/process/ccdeploy_spark2-conf_etcspark2conf.cloudera.spark2_on_yarn_3511819582822760396 as CONF_DIR
 
using spark2-conf as DIRECTORY_NAME
 
using /etc/spark2/conf.cloudera.spark2_on_yarn as DEST_PATH
 
using spark2-conf as ALT_NAME
 
using /etc/spark2/conf as ALT_LINK
 
using 51 as PRIORITY
 
using scripts/control.sh as RUNNER_PROGRAM
 
using client as RUNNER_ARGS
 
using /usr/sbin/update-alternatives as UPDATE_ALTERNATIVES
 
Deploying service client configs to /etc/spark2/conf.cloudera.spark2_on_yarn
 
invoking optional deploy script scripts/control.sh
 
/var/run/cloudera-scm-agent/process/ccdeploy_spark2-conf_etcspark2conf.cloudera.spark2_on_yarn_3511819582822760396/spark2-conf /var/run/cloudera-scm-agent/process/ccdeploy_spark2-conf_etcspark2conf.cloudera.spark2_on_yarn_3511819582822760396
 
Thu Aug 30 14:34:08 CST 2018: Running Spark2 CSD control script...
 
Thu Aug 30 14:34:08 CST 2018: Detected CDH_VERSION of [5]
 
Java version 1.8 is required for Spark 2.3.
 

解决:

在每个节点安装JDK1.8(可以与jdk1.7版本并存)
[root@hadoop1 ~]# rpm -ivh jdk-8u181-linux-x64.rpm

warning: jdk-8u181-linux-x64.rpm: Header V3 RSA/SHA256 Signature, key ID ec551f03: NOKEY

Preparing...                ########################################### [100%]

   1:jdk1.8                 ########################################### [100%]

 

在CM节点配置JAVA_HOME
[root@hadoop0 ~]# vi /etc/default/cloudera-scm-server

export JAVA_HOME=/usr/java/jdk1.8.0_181-amd64

 

在CM中每个主机的上配置JAVA_HOME
在CM中的点 -> 主机 -> 选择一host 

在高级页添加新的JAVA_HOME目录

 

重新启动CM服务和集群
# service cloudera-scm-server restart

 

安装完成后,再重新添加Spark2服务正常。

 

参考:

https://blog.csdn.net/u010936936/article/details/73650417

https://blog.csdn.net/chenguangchun1993/article/details/78903463

手动升级spark方法:

如果是Cluster模式:
  1. A节点启动Spark-submit,这个程序即为client,client连接Resource Manager
  2. Resource Manager指定一个Node Manager创建AppMaster,这个AppMaster就是Driver
  3. AppMaster向Resource Manager申请资源创建Spark的Excutor
  4. Excutor向Driver(AppMaster)报告程序结果
如果是Client模式:
  1. A节点启动Spark-submit,这个程序就是client,此时直接创建Driver。
  2. 连接Resource Manager创建AppMaster
  3. Driver向AppMaster申请创建Excutor,AppMaster再跟Resource Manager申请资源创建Excutor
  4. Excutor向Driver(Client)报告程序结果

那么这种环境下如何升级Spark呢?

通过上面的过程分析,可以知道,Spark版本存在两个地方:一个是A节点提交Spark-submit的程序必须是2.3.0版本的;另一个是Yarn使用的lib必须是2.3.0版本的。

虽然暂时还屡不清楚来龙去脉,但是跟着过一遍吧!

第一步,在A节点下载spark2.3的jar

 
  1. [xxx@hnode10 app]$ ls -l

  2. total 628168

  3. drwxrwxr-x 6 hdfs hdfs 4096 Jan 9 10:35 akita

  4. -rw-r--r-- 1 hdfs hdfs 18573432 Jan 9 10:34 akita-release.tar.gz

  5. lrwxrwxrwx 1 hdfs hdfs 46 Jan 2 09:37 canal -> /var/lib/hadoop-hdfs/app/canal.deployer-1.0.25

  6. drwxrwxr-x 6 hdfs hdfs 4096 Jan 2 09:36 canal.deployer-1.0.25

  7. drwxrwxr-x 4 hdfs hdfs 4096 May 31 09:11 hadoop

  8. lrwxrwxrwx 1 root root 50 Jun 5 12:34 spark -> /var/lib/hadoop-hdfs/app/spark-2.2.0-bin-hadoop2.6

  9. drwxr-xr-x 14 hdfs hdfs 4096 Nov 9 2017 spark-2.1.1-bin-hadoop2.6

  10. -rw-r--r-- 1 hdfs hdfs 198804211 Oct 23 2017 spark-2.1.1-bin-hadoop2.6.tgz

  11. drwxr-xr-x 13 hdfs hdfs 4096 Jun 5 12:33 spark-2.2.0-bin-hadoop2.6

  12. -rw-rw-r-- 1 hdfs hdfs 201706782 Jul 11 2017 spark-2.2.0-bin-hadoop2.6.tgz

  13. drwxr-xr-x 13 hdfs hdfs 4096 Feb 23 03:46 spark-2.3.0-bin-hadoop2.6

  14. -rw-rw-r-- 1 hdfs hdfs 224121109 Feb 23 03:54 spark-2.3.0-bin-hadoop2.6.tgz

  15. lrwxrwxrwx 1 root root 25 Jun 6 09:04 spark23 -> spark-2.3.0-bin-hadoop2.6

第二步,修改配置文件和启动脚本

解压后,创建一个新的软连接 spark23到对应的目录:

ln -s /var/lib/hadoop-hdfs/app/spark-2.3.0-bin-hadoop2.6 spark23

然后配置对应的启动脚本:

 
  1. [xxx@hnode10 bin]$ ls -l

  2. total 9588

  3. -rwxr-xr-x 1 hdfs hdfs 2991 Oct 23 2017 spark2-shell

  4. -rwxr-xr-x 1 hdfs hdfs 1013 Oct 23 2017 spark2-submit

  5. -rwxr-xr-x 1 root root 2993 Jun 6 17:39 spark23-shell

  6. -rwxr-xr-x 1 root root 1015 Jun 6 17:41 spark23-submit

在spark23-submit中修改SPARK_HOME

 
  1. export SPARK2_HOME=/var/lib/hadoop-hdfs/app/spark23

  2. exec "${SPARK2_HOME}"/bin/spark-class org.apache.spark.deploy.SparkSubmit "$@"

在spark23-shell中修改SPARK_HOME

 
  1. cygwin=false

  2. case "$(uname)" in

  3. CYGWIN*) cygwin=true;;

  4. esac

  5.  
  6. # Enter posix mode for bash

  7. set -o posix

  8.  
  9. export SPARK2_HOME=/var/lib/hadoop-hdfs/app/spark23

  10. ....

修改Spark2.3中的配置文件spark-defaults.conf

 
  1. spark.yarn.jars hdfs://nameservice1/app/spark23/lib/*.jar

  2. spark.history.fs.logDirectory hdfs://nameservice1/user/spark/applicationHistory

其中spark.yarn.jars指定了yarn使用的spark jar包目录。

第三步,在hdfs中上传yarn使用的lib

449064-20180606184756266-479991649.jpg

背景

Hive默认使用MapReduce作为执行引擎,即Hive on mr。实际上,Hive还可以使用Tez和Spark作为其执行引擎,分别为Hive on Tez和Hive on Spark。由于MapReduce中间计算均需要写入磁盘,而Spark是放在内存中,所以总体来讲Spark比MapReduce快很多。因此,Hive on Spark也会比Hive on mr快。为了对比Hive on Spark和Hive on mr的速度,需要在已经安装了Hadoop集群的机器上安装Spark集群(Spark集群是建立在Hadoop集群之上的,也就是需要先装Hadoop集群,再装Spark集群,因为Spark用了Hadoop的HDFS、YARN等),然后把Hive的执行引擎设置为Spark。

Spark运行模式分为三种1、Spark on YARN 2、Standalone Mode 3、Spark on Mesos。
Hive on Spark默认支持Spark on YARN模式,因此我们选择Spark on YARN模式。Spark on YARN就是使用YARN作为Spark的资源管理器。分为Cluster和Client两种模式。

一、环境说明

本教程Hadoop相关软件全部基于CDH5.5.1,用yum安装,系统环境如下:

  • 操作系统:CentOS 7.2
  • Hadoop 2.6.0
  • Hive1.1.0
  • Spark1.5.0
  • MySQL 5.6
  • JDK 1.8
  • Maven 3.3.3
  • Scala 2.10

各节点规划如下:

192.168.117.51     Goblin01           nn1  jn1  rm1  worker  master  hive  metastore  mysql
192.168.117.52     Goblin02    zk2    nn2  jn2  rm2  worker          hive
192.168.117.53     Goblin03    zk3    dn1  jn3       worker          hive
192.168.117.54     Goblin04    zk4    dn2            worker          hive

说明:Goblin01~04是每台机器的hostname,zk代表zookeeper,nn代表hadoop的namenode,dn代表datanode,jn代表journalnode,rm代表resourcemanager,worker代表Spark的slaves,master代表Spark的master

二、编译和安装Spark(Spark on YARN)

2.1 编译Spark源码

要使用Hive on Spark,所用的Spark版本必须不包含Hive的相关jar包,hive on spark 的官网上说“Note that you must have a version of Spark which does not include the Hive jars”。在spark官网下载的编译的Spark都是有集成Hive的,因此需要自己下载源码来编译,并且编译的时候不指定Hive。

我们这里用的Spark源码是spark-1.5.0-cdh5.5.1版本,下载地址如下:

http://archive.cloudera.com/cdh5/cdh/5/spark-1.5.0-cdh5.5.1-src.tar.gz

下载完后用 tar xzvf 命令解压,进入解压完的文件夹,准备编译。

注意:编译前请确保已经安装JDK、Maven和Scala,maven为3.3.3及以上版本,并在/etc/profile里配置环境变量。

命令行进入在源码根目录下,执行

  ./make-distribution.sh --name "hadoop2-without-hive" --tgz "-Pyarn,hadoop-provided,hadoop-2.6,parquet-provided"

若编译过程出现内存不足的情况,需要在运行编译命令之前先运行:

export MAVEN_OPTS="-Xmx2g -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=512m"

来设置Maven的内存。

编译过程由于要下载很多Maven依赖的jar包,需要时间较长(大概一两个小时),要保证网络状况良好,不然很容易编译失败。若出现以下结果,则编译成功:

 

编译成功.jpg

编译成功后,会在源码根目录下多出一个文件(红色部分):

spark-1.5.0-cdh5.5.1-bin-hadoop2-without-hive.tgz

 

编译完生成的文件.png

2.2 安装Spark

  • 将编译完生成的spark-1.5.0-cdh5.5.1-bin-hadoop2-without-hive.tgz拷贝到Spark的安装路径,并用 tar -xzvf 命令解压

  • 配置环境变量

    $vim /etc/profile
    export SPARK_HOME=spark安装路径
    $source /etc/profile
    

2.3 配置Spark

配置spark-env.sh、slaves和spark-defaults.conf三个文件

  • spark-env.sh

主要配置JAVA\_HOME、SCALA\_HOME、HADOOP\_HOME、HADOOP\_CONF\_DIR、SPARK\_MASTER\_IP等

export JAVA_HOME=/usr/lib/jvm/java
export SCALA_HOME=/root/scala
export HADOOP_HOME=/usr/lib/hadoop
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop 
export YARN_CONF_DIR=$HADOOP_HOME/etc/hadoop
export SPARK_LAUNCH_WITH_SCALA=0
export SPARK_WORKER_MEMORY=1g
export SPARK_DRIVER_MEMORY=1g
export SPARK_MASTER_IP=192.168.117.51
export SPARK_LIBRARY_PATH=/root/spark-without-hive/lib
export SPARK_MASTER_WEBUI_PORT=18080
export SPARK_WORKER_DIR=/root/spark-without-hive/work
export SPARK_MASTER_PORT=7077
export SPARK_WORKER_PORT=7078
export SPARK_LOG_DIR=/root/spark-without-hive/log
export SPARK_PID_DIR='/root/spark-without-hive/run'
  • slaves(将所有节点都加入,master节点同时也是worker节点)
Goblin01
Goblin02
Goblin03
Goblin04
  • spark-defaults.conf
 spark.master                     yarn-cluster
 spark.home                       /root/spark-without-hive
 spark.eventLog.enabled           true
 spark.eventLog.dir               hdfs://Goblin01:8020/spark-log
 spark.serializer                 org.apache.spark.serializer.KryoSerializer
 spark.executor.memory            1g
 spark.driver.memory              1g
 spark.executor.extraJavaOptions  -XX:+PrintGCDetails -Dkey=value -Dnumbers="one two three"

spark.master指定Spark运行模式,可以是yarn-client、yarn-cluster...

spark.home指定SPARK_HOME路径

spark.eventLog.enabled需要设为true

spark.eventLog.dir指定路径,放在master节点的hdfs中,端口要跟hdfs设置的端口一致(默认为8020),否则会报错

spark.executor.memory和spark.driver.memory指定executor和dirver的内存,512m或1g,既不能太大也不能太小,因为太小运行不了,太大又会影响其他服务

三、配置YARN

配置yarn-site.xml,跟hdfs-site.xml在同一个路径下($HADOOP_HOME/etc/hadoop)

<property>
  <name>yarn.resourcemanager.scheduler.class</name>
  <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
</property>

四、配置Hive

  • 添加spark依赖到hive(将spark-assembly-1.5.0-cdh5.5.1-hadoop2.6.0.jar拷贝到$HIVE\_HOME/lib目录下)

进入SPARK\_HOME

cp spark-assembly-1.5.0-cdh5.5.1-hadoop2.6.0.jar /usr/lib/hive/lib
  • 配置hive-site.xml

配置的内容与spark-defaults.conf相同,只是形式不一样,以下内容是追加到hive-site.xml文件中的,并且注意前两个配置,如果不设置hive的spark引擎用不了,在后面会有详细的错误说明。且这里可以指定hive on spark2的spark.home


<property>
  <name>hive.execution.engine</name>
  <value>spark</value>
</property>

<property>
  <name>hive.enable.spark.execution.engine</name>
  <value>true</value>
</property>

<property>
  <name>spark.home</name>
  <value>/root/spark-without-hive</value>
</property>
<property>
  <name>spark.master</name>
  <value>yarn-client</value>
</property>
<property>
  <name>spark.enentLog.enabled</name>
  <value>true</value>
</property>
<property>
  <name>spark.enentLog.dir</name>
  <value>hdfs://Goblin01:8020/spark-log</value>
</property>
<property>
  <name>spark.serializer</name>
  <value>org.apache.spark.serializer.KryoSerializer</value>
</property>
<property>
  <name>spark.executor.memeory</name>
  <value>1g</value>
</property>
<property>
  <name>spark.driver.memeory</name>
  <value>1g</value>
</property>
<property>
  <name>spark.executor.extraJavaOptions</name>
  <value>-XX:+PrintGCDetails -Dkey=value -Dnumbers="one two three"</value>
</property>

五、验证是否安装配置成功

1.验证Spark集群

注意:在启动Spark集群之前,要确保Hadoop集群和YARN均已启动

  • 进入$SPARK_HOME目录,执行:
./sbin/start-all.sh

用jps命令查看51节点上的master和worker,52、53、54节点上的worker是否都启动了

  • 同样在$SPARK_HOME目录下,提交计算Pi的任务,验证Spark集群是否能正常工作,运行如下命令
./bin/spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode client lib/spark-examples-1.5.0-cdh5.5.1-hadoop2.6.0.jar 10

若无报错,并且算出Pi的值,说明Spark集群能正常工作

2.验证Hive on Spark是否可用

  • 命令行输入 hive,进入hive CLI
  • set hive.execution.engine=spark; (将执行引擎设为Spark,默认是mr,退出hive CLI后,回到默认设置。若想让引擎默认为Spark,需要在hive-site.xml里设置)
  • create table test(ts BIGINT,line STRING); (创建表)
  • select count(*) from test;
  • 若整个过程没有报错,并出现正确结果,则Hive on Spark配置成功。

六、遇到的问题

0

编译spark基于maven有两种方式

  • 用mvn 命令编译
./build/mvn -Pyarn -Phadoop-2.6 -Dhadoop.version=2.6.0 -DskipTests clean package 

编译到倒数MQTT模块一直报错,而且编译出的文件比较大,不适合安装集群,因此不推荐。使用Intellij IDEA maven 插件报错如下:

 

spark-build-fail.png

  • 使用spark提供的预编译脚本,网络状况稳定,会编译出需要的安装版本,推荐。命令
./make-distribution.sh --name "hadoop2-without-hive" --tgz "-Pyarn,hadoop-provided,hadoop-2.6,parquet-provided"

结果如上文所述。

1

运行:

./bin/spark-submit --class org.apache.spark.examples.SparkPi  --master yarn  lib/spark-examples-1.5.0-cdh5.5.1-hadoop2.6.0.jar 10

报错:

 

spark-fail.png

原因:

hdfs的默认端口为8020 ,而我们在spark-default.conf中配置成了8021端口,导致连接不上HDFS报错

spark.eventLog.enabled           true
spark.eventLog.dir              hdfs://Goblin01:8021/spark-log

解决:

配置spark-default.conf中的spark.eventLog.dir 为本地路径,也就是不持久化日志到hdfs上,也就没有和hdfs的通行

or

spark-default.conf 注释掉 spark.eventLog.enabled true

or

在spark-default.conf里配置的eventLog端口跟hdfs的默认端口(8020)一致

or

由于配置的hdfs是高可用的,51,52都可以作为namenode,我们的spark集群的主节点在51上,当51上的namenode变成standby,导致无法访问hdfs的8020端口(hdfs默认端口),也就是说在51上读不出hdfs上spark-log的内容,在spark-default.conf中配置为spark.eventLog.dir hdfs://Goblin01:8021/spark-log,如果发生这种情况,直接kill掉52,让namenode只在51上运行。(这个后面要搭建spark的高可用模式解决)

2

运行:

在hive里设置引擎为spark,执行select count(*) from a;

报错:

Failed to execute spark task, with exception 'org.apache.hadoop.hive.ql.metadata.HiveException(Unsupported execution engine: Spark. Please set hive.execution.engine=mr)'

解决:

这是因为CDH版的Hive默认运行支持Hive on Spark(By default, Hive on Spark is not enabled).

需要用cloudera manager(cloudera官网给的的方法,但是要装cloudera manager,比较麻烦,不建议)

Go to the Hive service.
Click the Configuration tab.
Enter Enable Hive on Sparkin the Search field.
Check the box for Enable Hive on Spark (Unsupported).
Locate the Spark On YARN Service and click SPARK_ON_YARN.
Click Save Changes to commit the changes.

或者

在hive-site.xml添加配置(简单、推荐)

<property>
<name>hive.enable.spark.execution.engine</name>
<value>true</value>
</property>

3

终端输入hive无法启动hive CLI

原因:namenode挂了

解决:重启namenode

4

运行:

./bin/spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode client lib/spark-examples-1.5.0-cdh5.5.1-hadoop2.6.0.jar 10

问题:

没有报错,但是出现以下情况,停不下来

 

停不下来.png

原因:

  1. ResourceManager或者NodeManager挂掉,一直没有NodeManager响应,任务无法执行,所有停不下来。
  2. 还有一种情况是spark有别的application在运行,导致本次spark任务的等待或者失败

解决:

  1. 对于原因1,重启ResourceManager和NodeManager。
service hadoop-yarn-resourcemanager start;
service hadoop-yarn-nodemanager start;
  1. 对于原因2,解决办法是在hadoop配置文件中设置yarn的并行度,在/etc/hadoop/conf/capacity-scheduler.xml文件中配置yarn.scheduler.capacity.maximum-am-resource-percent from 0.1 to 0.5
 <property>
    <name>yarn.scheduler.capacity.maximum-am-resource-percent</name>
    <value>0.5</value>
    <description>
      Maximum percent of resources in the cluster which can be used to run
      application masters i.e. controls number of concurrent running
      applications.
    </description>
  </property>

参考资料


Hive on spark 配置及调优:

Hive默认使用的计算框架是MapReduce,在我们使用Hive的时候通过写SQL语句,Hive会自动将SQL语句转化成MapReduce作业去执行,但是MapReduce的执行速度远差与Spark。通过搭建一个Hive On Spark可以修改Hive底层的计算引擎,将MapReduce替换成Spark,从而大幅度提升计算速度。接下来就如何搭建Hive On Spark展开描述。

  注:本人使用的是CDH5.9.1,使用的Spark版本是1.6.0,使用的集群配置为4个节点,每台内存32+G,4 Core。

1.   配置Yarn

  Yarn需要配置两个参数:yarn.nodemanager.resource.cpu-vcores和yarn.nodemanager.resource.memory-mb。yarn.nodemanager.resource.cpu-vcores代表可以为container分配的CPU 内核的数量。yarn.nodemanager.resource.memory-mb代表可分配给容器的物理内存大小。

1)   配置cpu core

  为每个服务分配一个core,为操作系统预留2个core,剩余的可用的core分配给yarn。我使用的集群共有16个core,留出4个,剩余的12个core分配给yarn。

   

 

2)   配置内存

  设置Yarn内存为36G

   

 

2.   配置Spark

  给Yarn分配完资源后,需要配置一些Spark的参数,设置Spark可使用的资源。包括executor和Driver的内存,分配executor和设置并行度。

3)   配置executor内存

  在配置executor的内存大小的时候,需要考虑以下因素:

  • 增加executor的内存可以优化map join。但是会增加GC的时间。
  • 在某些情况下,HDFS客户端没有并行处理多个写请求,在有多个请求竞争资源的时候会出现一个executor使用过多的core。
  • 尽可能的减少空闲的core的个数,cloudera推荐设置spark.executor.cores为4,5,6,这取决于给yarn分配的资源。

  比如说,因为我们有12个core可用,我们可以设置为4,这样12/4余数为0,设置为5的话会剩余两个空闲。设置4个可使得空闲的core尽可能的少。

  这样配置之后我们可以同时运行三个executor,每个executor最多可以运行4个任务(每个core一个)。

  还有一点是要求spark.executor.memoryOverhead和spark.executor.memory的和不能超过yarn.scheduler.maximum-allocation-mb设置的值。我的scheduler请求最大内存分配的是12G。

   

 

4)   配置Driver内存

  Spark Driver端的配置如下:

  • spark.driver.memory---当hive运行在spark上时,driver端可用的最大Java堆内存。
  • spark.yarn.driver.memoryOverhead---每个driver可以额外从yarn请求的堆内存大小。这个参数加上spark.driver.memory就是yarn为driver端的JVM分配的总内存。

  Spark在Driver端的内存不会直接影响性能,但是在没有足够内存的情况下在driver端强制运行Spark任务需要调整。

5)   设置executor个数

  集群的executor个数设置由集群中每个节点的executor个数和集群的worker个数决定,如果集群中有3个worker,则Hive On Spark可以使用的executor最大个数是12个(3 * 4)。

  Hive的性能受可用的executor的个数影响很明显,一般情况下,性能和executor的个数成正比,4个executor的性能大约是2个executor性能的一倍,但是性能在executor设置为一定数量的时候会达到极值,达到这个极值之后再增加executor的个数不会增加性能,反而有可能会为集群增加负担。

6)   动态分配executor

  设置spark.executor.instances到最大值可以使得Spark集群发挥最大性能。但是这样有个问题是当集群有多个用户运行Hive查询时会有问题,应避免为每个用户的会话分配固定数量的executor,因为executor分配后不能回其他用户的查询使用,如果有空闲的executor,在生产环境中,计划分配好executor可以更充分的利用Spark集群资源。

  Spark允许动态的给Spark作业分配集群资源,cloudera推荐开启动态分配。

7)   设置并行度

  为了更加充分的利用executor,必须同时允许足够多的并行任务。在大多数情况下,hive会自动决定并行度,但是有时候我们可能会手动的调整并行度。在输入端,map task的个数等于输入端按照一定格式切分的生成的数目,Hive On Spark的输入格式是CombineHiveInputFormat,可以根据需要切分底层输入格式。调整hive.exec.reducers.bytes.per.reducer控制每个reducer处理多少数据。但是实际情况下,Spark相比于MapReduce,对于指定的hive.exec.reducers.bytes.per.reducer不敏感。我们需要足够的任务让可用的executor保持工作不空闲,当Hive能够生成足够多的任务,尽可能的利用空闲的executor。

3.   配置Hive

  Hive on Spark的配置大部分即使不使用Hive,也可以对这些参数调优。但是hive.auto.convert.join.noconditionaltask.size这个参数是将普通的join转化成map join的阈值,这个参数调优对于性能有很大影响。MapReduce和Spark都可以通过这个参数进行调优,但是这个参数在Hive On MR上的含义不同于Hive On Spark。

  数据的大小由两个统计量标识:

  • ·totalSize 磁盘上数据的大小
  • ·rawDataSize 内存中数据的大小

  Hive On MapReduce使用的是totalSize,Spark使用rawDataSize。数据由于经过一系列压缩、序列化等操作,即使是相同的数据集,也会有很大的不同,对于Hive On Spark,需要设置   hive.auto.convert.join.noconditionaltask.size,将普通的join操作转化成map join来提升性能,集群资源充足的情况下可以把这个参数的值适当调大,来更多的触发map join。但是设置太高的话,小表的数据会占用过多的内存导致整个任务因为内存耗尽而失败,所有这个参数需要根据集群的资源来进行调整。

  Cloudera推荐配置两个额外的配置项:

  hive.stats.fetch.column.stats=true

  hive.optimize.index.filter=true

  以下还整理了一些配置项用于hive调优:

hive.optimize.reducededuplication.min.reducer=4

hive.optimize.reducededuplication=true

hive.merge.mapfiles=true

hive.merge.mapredfiles=false

hive.merge.smallfiles.avgsize=16000000

hive.merge.size.per.task=256000000

hive.merge.sparkfiles=true

hive.auto.convert.join=true

hive.auto.convert.join.noconditionaltask=true

hive.auto.convert.join.noconditionaltask.size=20M(might need to increase for Spark, 200M)

hive.optimize.bucketmapjoin.sortedmerge=false

hive.map.aggr.hash.percentmemory=0.5

hive.map.aggr=true

hive.optimize.sort.dynamic.partition=false

hive.stats.autogather=true

hive.stats.fetch.column.stats=true

hive.compute.query.using.stats=true

hive.limit.pushdown.memory.usage=0.4 (MR and Spark)

hive.optimize.index.filter=true

hive.exec.reducers.bytes.per.reducer=67108864

hive.smbjoin.cache.rows=10000

hive.fetch.task.conversion=more

hive.fetch.task.conversion.threshold=1073741824

hive.optimize.ppd=true

 

8)   设置Pre-warming Yarn Container

  我们使用Hive On Spark的时候,提交第一个查询时,看到查询结果可能会有比较长的延迟,但是再次运行相同的SQL查询,完成速度要比第一个查询快得多。

  当Spark使用yarn管理资源调度时,Spark executor需要额外的时间来启动和初始化,在程序运行之前,Spark不会等待所有的executor准备好之后运行,所有在任务提交到集群之后,仍有一些executor处于启动状态。在Spark上运行的作业运行速度与executor个数相关,当可用的executor的个数没有达到最大值的时候,作业达不到最大的并行性,所有Hive上提交的第一个SQL查询会慢。

  如果是在长时间会话这个应该问题影响很小,因为只有执行第一个SQL的时候会慢,问题不大,但是很多时候我们写的Hive脚本,需要用一些调度框架去启动(如Oozie)。这时候我们需要考虑进行优化。

  为了减少启动时间,我们可以开启container pre-warming机制,开启后只有当任务请求的所有executor准备就绪,作业才会开始运行。这样会提升Spark作业的并行度。

  Hive默认使用的计算框架是MapReduce,在我们使用Hive的时候通过写SQL语句,Hive会自动将SQL语句转化成MapReduce作业去执行,但是MapReduce的执行速度远差与Spark。通过搭建一个Hive On Spark可以修改Hive底层的计算引擎,将MapReduce替换成Spark,从而大幅度提升计算速度。接下来就如何搭建Hive On Spark展开描述。

  注:本人使用的是CDH5.9.1,使用的Spark版本是1.6.0,使用的集群配置为4个节点,每台内存32+G,4 Core。

转载于:https://my.oschina.net/hblt147/blog/3010431

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值