Hive扩展功能(七)--Hive On Spark

作者: 咸鱼翻身记 | 来源:发表于2017-02-16 17:26 被阅读545次

    软件环境:

    linux系统: CentOS6.7
    Hadoop版本: 2.6.5
    zookeeper版本: 3.4.8
    

    </br>

    主机配置:

    一共m1, m2, m3这三部机, 每部主机的用户名都为centos
    192.168.179.201: m1 
    192.168.179.202: m2 
    192.168.179.203: m3 
    
    m1: Zookeeper, Namenode, DataNode, ResourceManager, NodeManager, Master, Worker
    m2: Zookeeper, Namenode, DataNode, ResourceManager, NodeManager, Worker
    m3: Zookeeper, DataNode, NodeManager, Worker
    

    参考资料:

    spark源码编译教程
        http://blog.csdn.net/yanran1991326/article/details/46506595
    Hive on Spark搭建教程以及遇到的坑指南
        http://www.cnblogs.com/breg/p/5552342.html(可作为遇到坑时查看使用)
        http://www.cnblogs.com/linbingdong/p/5806329.html(建议参照该教程)
    官方参考配置文件
        https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties#ConfigurationProperties-Spark
    Hive On Spark官网资料:
        https://cwiki.apache.org/confluence/display/Hive/Hive+on+Spark%3A+Getting+Started
    关于Hive on Spark的讨论和进度(官方):
        https://issues.apache.org/jira/browse/HIVE-7292
    

    说明:

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


    </br>
    </br>

    一.安装Maven: (Linux下, 若使用Spark源码包自带的编译工具,则可跳过此步)

    参考资料
    Maven教程:
        http://wiki.jikexueyuan.com/project/maven/
    
    1. 下载Maven安装包

    2. 解压Maven到指定位置

    3. 编辑/etc/profile文件

    vi /etc/profile
    
    export M2_HOME=/home/centos/soft/maven
    PATH=$PATH:$M2_HOME/bin
    
    source /etc/profile
    
    1. 检验是否安装成功
    mvn -v
    
    1. 设置maven内存大小
    Linux下:
    vi /etc/profile
    
    export MAVEN_OPTS=-Xmx2g -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=512m
    
    Windows下:
    新建变量: MAVEN_OPTS
    将变量MAVEN_OPTS的值设置成:  -Xmx2g -XX:MaxPermSize=512M -XX:ReservedCodeCacheSize=512m
    

    </br>

    二.编译spark源码:

    参考资料:
    spark源码下载官方地址:
        http://spark.apache.org/downloads.html
    spark源码编译官方指南:
        http://spark.apache.org/docs/1.5.0/building-spark.html
    spark源码编译教程:
        http://blog.csdn.net/yanran1991326/article/details/46506595
    Hive On Spark遇坑指南:
        http://www.cnblogs.com/linbingdong/p/5806329.html
    

    1. 编译指令:

    (切记不可用-Phive参数, 推荐使用第一种方案, 因为第二种方案亲测编译成功后各种缺包报错)

    方案一:maven编译: (Linux下,推荐使用这种方法)

    如果想生成一个用scala2.1.2编译的spark 部署包,则要先执行change-scala-version.sh文件,执行指令如下:

    ./dev/change-scala-version.sh 2.10  (若要指定scala的编译版本时, 必须先执行该指令)
    
    mvn -Phadoop-2.6 -Pyarn -Dhadoop.version=2.6.5 -Dyarn.version=2.6.5 -Dscala-2.10 -DskipTests clean package
    

    指令参数使用介绍:

    –Phadoop-$系列:              打包时所用的Hadoop系列号,不加此参数时hadoop为pom.xml的默认系列。 
    -Dhadoop.version=$版本号     打包时所用的Hadoop版本号,不加此参数时不可从HDFS上读取数据。 
    –Pyarn                      是否支持Hadoop YARN,不加参数时为不支持yarn。 
    -Dyarn.version=$版本号         是否支持Hadoop YARN,不加参数时为不支持yarn调度。 
    –Phive                      是否在Spark SQL中支持hive,不加此参数时为不支持hive。(若要使用Hive on Spark功能时, 不能添加次参数)
    -Dscala-$版本号               打包时所用的Scala系列号,不加此参数时Scala版本为pom.xml的默认版本, 在使用此函数之前必须先执行./dev/change-scala-version.sh 2.10指令,否则无效    
    -DskipTests                是否在编译的过程中略过测试,加此参数时为略过。
    
    方案二:使用spark源码包中自带的make-distribution编译工具

    编译Spark源码(若需要用到parquet功能,则带上parquet-provided参数)
    (1)Spark2.0版本之前(hadoop版本可随实际情况修改)

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

    (2)Spark2.0版本之后(hadoop版本可随实际情况修改)

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

    </br>

    2. 编译完成
    方案一:使用Maven方式编译:

    编译成功后的Spark引用包的存放位置:

    $Spark源码目录/assembly/target/scala-2.10/spark-assembly-1.6.3-hadoop2.6.5.jar
    

    该包的只是一个资源包, 应把tgz解压安装的$SPARK_HOME/lib目录下的assembly删除, 然后将该包放入到$SPARK_HOME/lib目录下

    方案二:使用make-distribution.sh方式编译:

    编译成功后的Spark安装包的存放位置:

    $Spark源码目录/spark-1.6.0-bin-hadoop2-without-hive-src.tgz
    

    该包是一个安装包, 用tar解压出安装即可, 不推荐使用


    </br>

    3.更新说明

    更新之前有个BUG, 就是在此之前编译的Spark部署包并不能操作Hive中Paruqet, 个人猜测的原因是: 因为我之前推荐的是Maven来编译Spark部署包, 但是在编译的包里并没有支持ParquetJAR包,所以当操作Parquet表时就会报错, 在此进行BUG修复, 若不使用parquet存储格式, 则可继续用以前的方式编译,并无大碍
    想要使用Parquet储存方式, 本人目前掌握的方法是:
    使用spark源码包中自带的make-distribution编译工具, 编译指令为:

    ./dev/make-distribution.sh --name "hadoop2-without-hive" --tgz "-Pyarn,hadoop-provided,hadoop-2.6,parquet-provided"
    
    编译建议:

    在此假设你编译成功, 如果编译不成功除了对内存溢出或者报了很明显的错误之外, 其他错误的处理办法都是不断的重试,重试,再重试,不断的输入编译指令进行编译,就能编译成功了,编译时间长短不定,建议编译成功之后别把spark的源码目录删除, 因为只要没删除以后编译相同版本的就会容易很多


    在之前说过, 用make-distribution.sh编译的Spark部署包是会报错的, 那么下面对报错进行解决:
    (1)启动spark集群时报错,启动Master节点,报错信息为:

    Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/Logger
            at java.lang.Class.getDeclaredMethods0(Native Method)
            at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
            at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
            at java.lang.Class.getMethod0(Class.java:3018)
            at java.lang.Class.getMethod(Class.java:1784)
            at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
            at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
    Caused by: java.lang.ClassNotFoundException: org.slf4j.Logger
            at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
            at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
            ... 7 more
    

    解决方案:
    /home/centos/soft/hadoop/share/hadoop/common/lib目录下的slf4j-api-1.7.5.jar文件,slf4j-log4j12-1.7.5.jar文件和commons-logging-1.1.3.jar文件拷贝到/home/centos/soft/spark/lib目录下


    (2)启动spark集群时报错,启动Master节点,报错信息为:

    Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/conf/Configuration
            at java.lang.Class.getDeclaredMethods0(Native Method)
            at java.lang.Class.privateGetDeclaredMethods(Class.java:2570)
            at java.lang.Class.getMethod0(Class.java:2813)
            at java.lang.Class.getMethod(Class.java:1663)
            at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
            at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)
    Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.conf.Configuration
            at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
            at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
            at java.security.AccessController.doPrivileged(Native Method)
            at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
            at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
            ... 6 more
    

    解决方案:

    官网参考:
        https://spark.apache.org/docs/latest/hadoop-provided.html#apache-hadoop
    

    编辑spark-env.sh文件,添加下列该项:

    vi  $SPARK_HOME/conf/spark-env.sh
    
    export  SPARK_DIST_CLASSPATH=$(/home/centos/soft/hadoop/bin/hadoop classpath)
    

    </br>
    </br>

    三.配置YARN

    若Hive on Spark使用YARN作为调度器,则配置YARN,否则,跳过此步骤,不进行配置.

    官方参考资料
        https://hadoop.apache.org/docs/r2.4.1/hadoop-yarn/hadoop-yarn-site/CapacityScheduler.html
        https://hadoop.apache.org/docs/r2.7.1/hadoop-yarn/hadoop-yarn-site/FairScheduler.html
    

    </br>
    </br>

    四.配置Hive

    1.导包到HIVE_HOME/lib目录下
    1. 在Hive-2.2.0版本之前
    将$SPARK_HOME/lib目录下assembly的jar包链接到HIVE_HOME/lib目录下
    
    1. 在Hive-2.2.0版本之后,
      yarn模式:
    将scala-library, spark-core, spark-network-common包链接到HIVE_HOME/lib目录下
    

    本地模式:

    chill-java, chill, jackson-module-paranamer, jackson-module-scala, ersey-container-servlet-core, jersey-server, json4s-ast, kryo-shaded, minlog, scala-xml, spark-launcher, spark-network-shuffle, park-unsafe, xbean-asm5-shaded包链接到HIVE_HOME/lib目录下
    
    2.上传JAR包到HDFS上
    1. 在Hive-2.2.0版本之前,
      $HIVE_HOME/lib目录下assembly的包上传到HDFS上,并在hive-site.xml文件中配置assembly包位置:
    <property>
            <name>spark.yarn.jar</name>
            <value>hdfs://ns1/spark-assembly.jar</value>
    </property>
    
    1. 在Hive-2.2.0版本之后,
      将$SPARK_HOME/lib目录下的所有包上传到HDFS上,并在hive-site.xml文件中配置以下配置项:
    <property>
            <name>spark.yarn.jars</name>
            <value>hdfs://ns1/spark-jars/*</value>
    </property>
    
    3.综上所述:

    Hive的配置项为以下配置, 编辑hive-site.xml文件 (以下配置是Spark2.2.0之前的YARN模式下的配置)

    <!-- property>
        <name>spark.master</name>
        <value>yarn-cluster</value>
        <description> YARN Model </description>
    </property -->
    <property>
        <name>spark.master</name>
        <value>spark://m1:7077</value>
        <description> Standalone Model </description>
    </property>
    <property>
        <name>spark.home</name>             
        <value>/home/centos/soft/spark/</value>
    </property>
    <property>
        <name>hive.execution.engine</name>
        <value>spark</value>
    </property>
    <property>
        <name>spark.enentLog.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>spark.enentLog.dir</name>
        <value>/home/centos/soft/spark/logs/enentLogDir</value>
    </property>
    <property>
        <name>spark.serializer</name>                   
        <value>org.apache.spark.serializer.KryoSerializer</value>
    </property>
    <property>
      <name>spark.executor.extraJavaOptions</name>
      <value>-XX:+PrintGCDetails -Dkey=value -Dnumbers="one two three"</value>
    </property>
    <property>
        <name>spark.executor.cores</name>                       
        <value>1</value>
    </property>
    <property>
        <name>spark.executor.instances</name>               
        <value>1</value>
    </property>
    <property>
        <name>spark.executor.memory</name>                  
        <value>512m</value>
    </property>
    <property>
        <name>spark.driver.memory</name>
        <value>512m</value>
    </property>
    <property>
        <name>yarn.nodemanager.resource.memory-mb</name>
        <value>512</value>
    </property>
    <property>
        <name>spark.yarn.executor.memoryOverhead</name>         
        <value>75</value>
    </property>
    <property>
        <name>spark.yarn.driver.memoryOverhead</name>           
        <value>75</value>
    </property>
    <property>
      <name>spark.yarn.jar</name>
      <value>hdfs://ns1/Jar/spark-assembly-1.6.0-hadoop2.6.0.jar</value>
    </property>
    <property>
      <name>hive.spark.client.channel.log.level</name>
      <value>DEBUG</value>
    </property>
    <property>
      <name>hive.spark.client.rpc.server.address</name>
      <value>m1</value>
    </property>
    <property>
      <name>spark.driver.extraJavaOptions</name>
      <value>-XX:PermSize=128M -XX:MaxPermSize=512M</value>
    </property>
    <!-- 索引用到的配置项 -->
    <property>
        <name>hive.optimize.index.filter</name>
        <value>true</value>
    </property>
    <property>
        <name>hive.optimize.index.groupby</name>
        <value>true</value>
    </property>
    

    </br>
    </br>

    三.配置Spark

    举例说明:
    1. 当在YARN模式下运行Spark时,我们通常建议将spark.executor.cores设置为5,6或7(在spark-default.conf中设置),这取决于典型节点可以被整除。例如,如果yarn.nodemanager.resource.cpu-vcores19,那么6是一个更好的选择(所有执行器只能有相同数量的内核,这里如果我们选择5,那么每个执行器只有3个内核;如果我们选择7,则只使用2个执行器,并且将浪费5个核心)。如果它是20,那么5是一个更好的选择(因为这样你会得到4个执行者,没有核心被浪费)。

    2. 对于spark.executor.memory,我们建议计算yarn.nodemanager.resource.memory-mb *(spark.executor.cores / yarn.nodemanager.resource.cpu-vcores),然后在spark.executor.memory和spark之间分割yarn.executor.memoryOverhead。根据我们的实验,我们建议将spark.yarn.executor.memoryOverhead设置为总内存的15-20%

    3. 在确定了每个执行器接收到多少内存之后,您需要决定将多少个执行器分配给查询。在GA发行Spark动态执行器分配将被支持。然而对于这个测试,只能使用静态资源分配。基于每个节点中的物理内存和spark.executor.memoryspark.yarn.executor.memoryOverhead的配置,您将需要选择实例数并设置spark.executor.instances

    4. 现在一个现实世界的例子。假设有10个节点,每个节点具有64GB的内存,具有12个虚拟核心,例如,yarn.nodemanager.resource.cpu-vcores = 12。一个节点将用作主节点,因此集群将具有9个从节点。我们将spark.executor.cores配置为6.给定64GBram yarn.nodemanager.resource.memory-mb将是50GB。我们将确定每个执行程序的内存量,如下所示:50GB *(6/12)= 25GB。我们将20%分配给spark.yarn.executor.memoryOverhead5120,将80%分配给spark.executor.memory20GB

    5. 在这个9节点集群上,每个主机有两个执行器。因此,我们可以将spark.executor.instances配置为介于218之间的某个值。值18将利用整个集群。


    </br>

    配置项解析:
    spark.executor.cores                         Between 5-7, See tuning details section
    spark.executor.memory                       yarn.nodemanager.resource.memory-mb * (spark.executor.cores / yarn.nodemanager.resource.cpu-vcores) 
    spark.yarn.executor.memoryOverhead         15-20% of spark.executor.memory
    spark.executor.instances                     Depends on spark.executor.memory + spark.yarn.executor.memoryOverhead, see tuning details section.
    
    配置项范例:

    在spark-default.conf文件下配置以下配置项:

    spark.executor.cores=1
    spark.executor.memory=512m
    spark.yarn.executor.memoryOverhead=75
    spark.executor.instances=1
    

    </br>
    </br>

    四.配置HPL/SQL

    将HPL/SQL存储过程调用的计算引擎改为Spark, 编辑hplsql-site.xml文件, 修改下列配置项(因本人使用Hive On Spark, 所以在下列配置项中将mr改为spark, 根据实际情况而定)

    <property>
      <name>hplsql.conn.init.hiveconn</name>
      <value>
         set mapred.job.queue.name=default;
         set hive.execution.engine=spark; 
         use default;
      </value>
      <description>Statements for execute after connection to the database</description>
    </property>
    <property>
      <name>hplsql.conn.init.hive2conn</name>
      <value>
         set mapred.job.queue.name=default;
         set hive.execution.engine=spark; 
         use default;
      </value>
      <description>Statements for execute after connection to the database</description>
    </property>
    

    </br>
    </br>

    五.测试

    重启metastore, spark-master, spark-slaves服务, 进入Hive测试

    sh  $SPARK_HOME/bin/stop-master.sh
    sh  $SPARK_HOME/bin/stop-slaves.sh
    sh  $SPARK_HOME/bin/start-master.sh
    sh  $SPARK_HOME/bin/start-slaves.sh
    sh  $HIVE_HOME/bin/hive --service metastore
    sh  $HIVE_HOME/bin/hive --service hiveserver2
    
    sh  $HIVE_HOME/bin/hive 
    
    select count(*) from bill_auth;
    

    </br>
    </br>

    六.官方推荐配置项:

    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
    

    </br>
    </br>
    </br>

    相关文章

      网友评论

        本文标题:Hive扩展功能(七)--Hive On Spark

        本文链接:https://www.haomeiwen.com/subject/wswcwttx.html