Spark on Hive:入门
Hive on Spark为Hive提供了利用Apache Spark作为其执行引擎的能力。
<span style="color:#172b4d">设置hive.execution.engine = spark;</span>
在HIVE-7292中添加了Spark上的Hive 。
版本兼容性
Hive on Spark仅使用特定版本的Spark进行测试,因此只能确保给定版本的Hive与特定版本的Spark一起使用。其他版本的Spark可能与给定版本的Hive一起使用,但这不能保证。下面是Hive版本列表及其相应的兼容Spark版本。
hive版 | spark版 |
---|---|
master | 2.3.0 |
3.0.x | 2.3.0 |
2.3.x | 2.0.0 |
2.2.x | 1.6.0 |
2.1.x | 1.6.0 |
2.0.x | 1.5.0 |
1.2.x | 1.3.1 |
1.1.x | 1.2.0 |
spark安装
按照说明安装Spark:
YARN模式:http : //spark.apache.org/docs/latest/running-on-yarn.html
独立模式:https: //spark.apache.org/docs/latest/spark-standalone.html
Hive on Spark 默认支持 YARN模式下的Spark。
对于安装,请执行以下任务:
- 安装Spark(从源代码下载预构建的Spark或构建程序集)。
- 安装/构建兼容版本。Hive root
pom.xml
的<spark.version>定义了它构建/测试的Spark版本。 - 安装/构建兼容的分发版。每个版本的Spark都有几个发行版,对应不同版本的Hadoop。
- 安装Spark后,找到并记下<spark-assembly - *。jar>位置。
-
请注意,您必须拥有不包含Hive jar 的Spark版本 。意思是没有使用Hive配置文件构建的。如果您将使用Parquet表,建议您也启用“镶木地板”配置文件。否则,Parquet依赖项可能会发生冲突。要从安装中删除Hive jar,只需在Spark存储库下使用以下命令:
在Spark 2.0.0之前:
.
/make-distribution
.sh --name
"hadoop2-without-hive"
--tgz
"-Pyarn,hadoop-provided,hadoop-2.4,parquet-provided"
自Spark 2.0.0起:
.
/dev/make-distribution
.sh --name
"hadoop2-without-hive"
--tgz
"-Pyarn,hadoop-provided,hadoop-2.7,parquet-provided"
自Spark 2.3.0起:
.
/dev/make-distribution
.sh --name
"hadoop2-without-hive"
--tgz
"-Pyarn,hadoop-provided,hadoop-2.7,parquet-provided,orc-provided"
- 安装/构建兼容版本。Hive root
- 启动Spark群集
- 记下<Spark Master URL>。这可以在Spark master WebUI中找到。
配置YARN
而不是容量调度程序,需要公平的调度程序。这为YARN集群中的工作公平分配了相同的资源份额。
yarn.resourcemanager.scheduler.class = org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler
配置Hive
-
要向Hive添加Spark依赖项:
- 在Hive 2.2.0之前,将spark-assembly jar链接到
HIVE_HOME/lib
。 - 从Hive 2.2.0开始,Spark上的Hive运行Spark 2.0.0及更高版本,它没有装配jar。
- 要以YARN模式(纱线客户端或纱线群集)运行,请将以下罐子链接到
HIVE_HOME/lib
。- scala-library
- spark-core
- spark-network-common
- 要以LOCAL模式运行(仅用于调试),除了上面的那些之外,还要链接以下jar
HIVE_HOME/lib
。- chill-java chill jackson-module-paranamer jackson-module-scala jersey-container-servlet-core
- jersey-server json4s-ast kryo-shaded minlog scala-xml spark-launcher
- spark-network-shuffle spark-unsafe xbean-asm5-shaded
- 要以YARN模式(纱线客户端或纱线群集)运行,请将以下罐子链接到
- 在Hive 2.2.0之前,将spark-assembly jar链接到
-
配置Hive执行引擎以使用Spark:
有关配置Hive和远程Spark驱动程序的其他属性,请参阅Hive配置属性的Spark部分。
-
为Hive配置Spark-application配置。请参阅:http: //spark.apache.org/docs/latest/configuration.html。这可以通过将具有这些属性的文件“spark-defaults.conf”添加到Hive类路径,或者通过在Hive配置(
hive-site.xml
)上设置它们来完成。例如:set spark.master=<Spark Master URL>
set spark.eventLog.enabled=
true
;
set spark.eventLog.dir=<Spark event log folder (must exist)>
set spark.executor.memory=512m;
set spark.serializer=org.apache.spark.serializer.KryoSerializer;
配置属性详细信息
spark.executor.memory
: 每个执行程序进程使用的内存量。spark.executor.cores
:每个执行程序的核心数。-
spark.yarn.executor.memoryOverhead
:在纱线上运行Spark时,每个执行程序要分配的堆外内存量(以兆字节为单位)。这是内存,可以解决VM开销,实习字符串,其他本机开销等问题。除了执行程序的内存之外,启动执行程序的容器需要一些额外的内存用于系统进程,这就是这个开销是什么对于。 spark.executor.instances
:分配给每个应用程序的执行程序数。spark.driver.memory
:分配给远程Spark上下文(RSC)的内存量。我们建议4GB。spark.yarn.driver.memoryOverhead
:我们建议400(MB)。
-
允许Yarn在节点上缓存必要的spark依赖关系jar,这样每次应用程序运行时都不需要分发它。
-
在Hive 2.2.0之前,将spark-assembly jar上传到hdfs文件(例如:hdfs:// xxxx:8020 / spark-assembly.jar)并在hive-site.xml中添加以下内容
<property>
<name>spark.yarn.jar</name>
<value>hdfs:
//xxxx:8020/spark-assembly.jar</value>
</property>
-
Hive 2.2.0,将$ SPARK_HOME / jars中的所有jar上传到hdfs文件夹(例如:hdfs:/// xxxx:8020 / spark-jars)并在hive-site.xml中添加以下内容
<property>
<name>spark.yarn.jars</name>
<value>hdfs:
//xxxx:8020/spark-jars/*</value>
</property>
-
配置Spark
设置执行程序内存大小比简单地将其设置为尽可能大更复杂。有几件事需要考虑:
-
更多执行程序内存意味着它可以为更多查询启用mapjoin优化。
-
另一方面,更多执行程序内存从GC角度来看变得难以处理。
- 一些实验表明,HDFS客户端不能很好地处理并发写入器,因此如果执行器核心太多,它可能会面临竞争条件。
需要针对群集调整以下设置,这些设置也可能适用于在Spark上的Hive之外提交Spark作业:
属性 | 建议 |
---|---|
spark.executor.cores | 在5-7之间,请参阅调整详细信息部分 |
spark.executor.memory | yarn.nodemanager.resource.memory-mb *(spark.executor.cores / yarn.nodemanager.resource.cpu-vcores) |
spark.yarn.executor.memoryOverhead | spark.executor.memory的15-20% |
spark.executor.instances | 取决于spark.executor.memory + spark.yarn.executor.memoryOverhead,请参阅调整详细信息部分。 |
调整细节
在YARN模式下运行Spark时, 我们通常建议将spark.executor.cores设置 为5,6或7,具体取决于典型节点可被整除的内容。例如,如果 yarn.nodemanager.resource.cpu-vcores是19,那么6是更好的选择(所有执行者只能拥有相同数量的核心,如果我们选择5,那么每个执行者只获得3个核心;如果我们选择7,然后只使用2个执行器,浪费5个核心)。如果它是20,那么5是更好的选择(因为这样你将获得4个执行器,并且没有浪费核心)。
因为 spark.executor.memory
,我们建议计算 yarn.nodemanager.resource.memory-mb *(spark.executor.cores / yarn.nodemanager.resource.cpu-vcores) 然后在spark.executor.memory和。之间进行拆分。根据我们的实验,我们建议设置 为总内存的15-20%左右。 spark.yarn.executor.memoryOverhead
spark.yarn.executor.memoryOverhead
在确定每个执行程序收到多少内存之后,您需要确定将多少执行程序分配给查询。在GA版本中,将支持Spark动态执行程序分配。但是,对于此测试版,只能使用静态资源分配。根据每个节点的物理内存的配置 spark.executor.memory
和spark.yarn.executor.memoryOverhead
,你需要选择实例和组的数量spark.executor.instances
。
现在是一个真实的例子。假设10个节点每个节点有64GB内存,有12个虚拟内核,例如 yarn.nodemanager.resource.cpu-vcores=12
。一个节点将用作主节点,因此集群将具有9个从节点。我们将配置spark.executor.cores
为6.鉴于64GB的RAM yarn.nodemanager.resource.memory-mb
将为50GB。我们将确定每个执行程序的内存量,如下所示:50GB *(6/12)= 25GB。我们将分配20%spark.yarn.executor.memoryOverhead
,或5120,和80%spark.executor.memory
,或20GB。
在这个9节点集群上,每个主机有两个执行程序。因此,我们可以配置spark.executor.instances
2到18之间的值。值18将使用整个群集。
常见问题(绿色已解决,将从此列表中删除)
问题 | 原因 | 解析度 | ||
---|---|---|---|---|
Error: Could not find or load main class org.apache.spark.deploy.SparkSubmit | Spark依赖项未正确设置。 | 向Hive添加Spark依赖关系,请参阅上面的步骤1 。 | ||
org.apache.spark.SparkException: Job aborted due to stage failure: Task 5.0:0 had a not serializable result: java.io.NotSerializableException: org.apache.hadoop.io.BytesWritable | Spark序列化程序未设置为Kryo。 | 将spark.serializer设置为org.apache.spark.serializer.KryoSerializer,请参阅上面的步骤3 。 | ||
[ERROR] Terminal initialization failed; falling back to unsupported java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected | Hive升级到Jline2,但Hadoop lib中存在jline 0.94。 |
| ||
Spark executor gets killed all the time and Spark keeps retrying the failed stage; you may find similar information in the YARN nodemanager log. WARN org.apache.hadoop.yarn.server.nodemanager.containermanager.monitor.ContainersMonitorImpl: Container [pid=217989,containerID=container_1421717252700_0716_01_50767235] is running beyond physical memory limits. Current usage: 43.1 GB of 43 GB physical memory used; 43.9 GB of 90.3 GB virtual memory used. Killing container. | 对于YARN上的Spark,如果节点管理器使用的内存大于“spark.executor.memory”+“spark.yarn.executor.memoryOverhead”的配置大小,则会终止Spark执行器。 | 增加“spark.yarn.executor.memoryOverhead”以确保它涵盖执行程序的堆外内存使用情况。 | ||
Run query and get an error like: FAILED: Execution Error, return code 3 from org.apache.hadoop.hive.ql.exec.spark.SparkTask In Hive logs, it shows: java.lang.NoClassDefFoundError: Could not initialize class org.xerial.snappy.Snappy | 在Mac上发生(未经官方支持)。 这是Mac的一般Snappy问题,并不是Hive on Spark独有的,但是这里注意到了解决方法,因为启动Spark客户端需要它。 | 在启动Hive或HiveServer2之前运行此命令: export HADOOP_OPTS =“ - Dorg.xerial.snappy.tempdir = / tmp -Dorg.xerial.snappy.lib.name = libsnappyjava.jnilib $ HADOOP_OPTS” | ||
Stack trace: ExitCodeException exitCode=1: .../launch_container.sh: line 27: $PWD:$PWD/__spark__.jar:$HADOOP_CONF_DIR.../usr/hdp/${hdp.version}/hadoop/lib/hadoop-lzo-0.6.0.${hdp.version}.jar:/etc/hadoop/conf/secure:$PWD/__app__.jar:$PWD/*: bad substitution
| /etc/hadoop/conf/mapred-site.xml中的关键mapreduce.application.classpath包含一个在bash中无效的变量。 | 来自mapreduce.application.classpath r emove
从 /etc/hadoop/conf/mapred-site.xml | ||
Exception in thread "Driver" scala.MatchError: java.lang.NoClassDefFoundError: org/apache/hadoop/mapreduce/TaskAttemptContext (of class java.lang.NoClassDefFoundError) at org.apache.spark.deploy.yarn.ApplicationMaster$$anon$2.run(ApplicationMaster.scala:432) | MR不在YARN类路径上。 | 如果在HDP上改变了 /hdp/apps/${hdp.version}/mapreduce/mapreduce.tar.gz#mr-framework 至 /hdp/apps/2.2.0.0-2041/mapreduce/mapreduce.tar.gz#mr-framework | ||
java.lang.OutOfMemoryError: PermGen space with spark.master=local | 默认情况下(SPARK-1879),Spark自己的启动脚本将PermGen增加到128 MB,因此我们需要在hive启动脚本中增加PermGen。 | 如果使用JDK7,请在conf / hive-env.sh中追加以下内容:
如果使用JDK8,请在Conf / hive-env.sh中追加以下内容:
|
推荐配置
有关这些设置的详细信息,请参阅HIVE-9153。
mapreduce.input.fileinputformat.split.maxsize =
750000000 hive.vectorized.execution.enabled = true
hive.cbo.enable = true
hive.optimize.reducededuplication.min.reducer = 4
hive.optimize.reducededuplication = true
hive.orc.splits .include.file.footer = false
hive.merge.mapfiles = true
hive.merge.sparkfiles = false
hive.merge.smallfiles.avgsize = 16000000
hive.merge.size.per.task =
256000000 hive.merge.orcfile.stripe。 level = true
hive.auto.convert.join = true
hive.auto.convert.join.noconditionaltask = true
hive.auto.convert.join.noconditionaltask.size = 894435328
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.vectorized.execution.reduce.enabled = false
hive.vectorized .groupby.checkinterval = 4096
hive.vectorized.groupby.flush.percent = 0.1
hive.compute.query.using.stats = true
hive.limit.pushdown.memory.usage = 0.4
hive.optimize.index.filter = true
hive。 exec.reducers.bytes.per.reducer = 67108864
hive.smbjoin.cache.rows = 10000
hive.exec.orc.default.stripe.size = 67108864
hive.fetch.task.conversion = more
hive.fetch.task.conversion。 threshold = 1073741824
hive.fetch.task.aggr = false
mapreduce.input.fileinputformat.list-status.num-threads = 5
spark.kryo.referenceTracking = false
spark.kryo.classesToRegister = org.apache.hadoop.hive.ql.io.HiveKey,org.apache.hadoop.io。 BytesWritable,org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch
有关其他属性,请参阅配置页面的Spark部分。