[笔记] 用单节点HIVE+SPARK执行ETL任务

动机

本身是java码农. 运维的Hadoop小集群上硬盘故障已经成为每天日常, 有各种hdfs故障. 最严重一次,文件没法从datanode同步到namenode的情况,导致集群完全不可用.

目前很多ELT任务都是用Spark和Hive实现的从kafka导入数据到HDFS,清洗后导入数据库. ETL代码里可能完全看不到Hdfs, 大部分都是Hive的sql操作或者Spark的rdd操作, 但Hadoop作为承载数据的基础设施, 是Hive和Spark的重要依赖. 在没有Hadoop集群运行的情况下, ETL任务还能不能运行呢?
(Hive on Spark on Yarn on Hadoop 是一般标准配置....每一层都是可以换的)

准备

1. 安装Hadoop(大概步骤,完整安装过程请参考其他文章)

wget http://mirror.bit.edu.cn/apache/hadoop/common/hadoop-3.0.3/hadoop-3.0.3-src.tar.gz
1.1. 配置环境变量(~/.bash_profile或者其他系统环境变量)
export HADOOP_CONF_DIR=hadoop安装目录/etc/hadoop

只是安装,不需要启动

2. 安装Hive

wget http://mirror.bit.edu.cn/apache/hive/hive-3.1.1/apache-hive-3.1.1-bin.tar.gz
2.1. 配置环境变量(~/.bash_profile或者其他系统环境变量)
export HIVE_HOME=Hive安装目录
2.2. 执行metastore初始化
cd Hive安装目录/bin
./schematool -dbType mysql -initSchema -url jdbc:mysql://mysql数据库:3306/metastore数据库名 -userName 数据库用户名 -passWord 数据库密码

执行成功后, 到数据库里就能看到hive初始化了一堆表来存储元数据,(恩,Hive作为一个数据仓库,用其他数据库来存储Hive的元数据)

2.3. 启动metastore
cd Hive安装目录/bin
hive --service metastore

3. 安装Spark

wget http://mirror.bit.edu.cn/apache/spark/spark-2.4.0/spark-2.4.0.tgz
3.1.编译Spark

注意这里下载的是spark源代码,因为spark本身带一个Hive1.21的实现,要在编译的时候去掉.
(实际上Hive on Spark还有一些其他细节....)

tar xzf spark-2.4.0.tgz
cd spark-2.4.0
export MAVEN_OPTS="-Xmx8g -XX:ReservedCodeCacheSize=2048m"; ./dev/make-distribution.sh --name "without-hive" --tgz "-Pscala-2.12,-Pyarn,hadoop-provided,hadoop-3.1,parquet-provided,orc-provided,-DskipTests"

编译完成后会在当前目录下生成 spark-2.4.0-bin-without-hive.tgz,解压到安装路径后配置环境变量

export SPARK_HOME=安装路径/spark-2.4.0-bin-without-hive

(免责)以下配置(作死)都是针对以上安装的版本, 换别的版本绝对会炸.

4 配置Hive on Spark

4.1 配置 Hive安装路径/conf/hive-env.sh
# Folder containing extra libraries required for hive compilation/execution can be controlled by:
export HIVE_AUX_JARS_PATH=$SPARK_HOME/jars

我观察到hive执行的classpath大概顺序是

  1. Hive安装路径下的lib里的jar
  2. HIVE_AUX_JARS_PATH变量指定的路径下的jar
  3. Hadoop安装路径/share下的jar
    很重要, 版本冲突的jar可能很雷
4.1 配置 Hive安装路径/conf/hive-site.xml

    fs.default.name

    file:///data/hive


    hive.metastore.warehouse.dir

    file:///data/hive/warehouse


 
    hive.execution.engine
    spark

 
    spark.master
    local 

4.2 解决jar包冲突(折腾了几天 ( ╯-_-)╯┴—┴ )

在Hive安装路径/lib下, Jackson是这个版本

jackson-annotations-2.9.4.jar  
jackson-core-2.9.4.jar  
jackson-databind-2.9.4.jar  

而Spark安装路径/jar下,Jackson是这个版本

jackson-annotations-2.6.7.jar
jackson-core-2.6.7.jar
jackson-databind-2.6.7.1.jar
jackson-module-paranamer-2.7.9.jar
jackson-module-scala_2.12-2.6.7.1.jar

当Spark调用jackson处理json时,因为hive的classpath的顺序,调用2.9.4的包.
所以把Spark安装路径/jar下Jackson的jar都换成和Hive安装路径/lib下一致的2.9.4版

jackson-annotations-2.9.4.jar
jackson-core-2.9.4.jar
jackson-databind-2.9.4.jar
jackson-module-paranamer-2.9.4.jar
jackson-module-scala_2.12-2.9.4.jar

那么,在哪里能找到这些jar包呢?
答案和maven一样,在maven仓库搜索

Capture.PNG

第二个jar包冲突是paramname
Hive安装目录/lib是paranamer-2.3.jar
Spark安装目录/jars是paranamer-2.8.jar
将Hive安装目录/lib里paranamer-2.3.jar换成和Spark一致, paranamer-2.8.jar.(一般尽量往高版本升级)

第三个jar包冲突很隐蔽,是lz4-java-1.4.0.jar
Spark安装目录/jars是lz4-java-1.4.0.jar
Hive安装目录/lib里却没有任何lz4-java的jar
其实是在hive-druid-handler-3.0.0.jar中
具体错误日志是:

2018-12-03T09:39:53,502  INFO [dag-scheduler-event-loop] scheduler.DAGScheduler: ResultStage 3 (Reducer 2) failed in 375.053 s due to Job aborted due to stage failure: Task 0 in stage 3.0 failed 1 times, most recent failure: Lost task 0.0 in stage 3.0 (TID 3, localhost, executor driver): java.lang.NoSuchMethodError: net.jpountz.lz4.LZ4BlockInputStream.(Ljava/io/InputStream;Z)V
        at org.apache.spark.io.LZ4CompressionCodec.compressedInputStream(CompressionCodec.scala:122)
        at org.apache.spark.serializer.SerializerManager.wrapForCompression(SerializerManager.scala:163)
        at org.apache.spark.serializer.SerializerManager.wrapStream(SerializerManager.scala:124)
        at org.apache.spark.shuffle.BlockStoreShuffleReader.$anonfun$read$1(BlockStoreShuffleReader.scala:50)
        at org.apache.spark.storage.ShuffleBlockFetcherIterator.next(ShuffleBlockFetcherIterator.scala:453)
        at org.apache.spark.storage.ShuffleBlockFetcherIterator.next(ShuffleBlockFetcherIterator.scala:64)
        at scala.collection.Iterator$$anon$11.nextCur(Iterator.scala:480)               

如果不需要hive和druid集成,就把hive-druid-handler-3.0.0.jar删除即可....

至此,Hive+Spark单机版配置完成,感觉比hdfs执行速度还快了一点.....

Hive配合UDF(读写kafka,http,redis等)食用效果更佳.... (๑乛◡乛๑)

你可能感兴趣的:([笔记] 用单节点HIVE+SPARK执行ETL任务)