动机
本身是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大概顺序是
- Hive安装路径下的lib里的jar
- HIVE_AUX_JARS_PATH变量指定的路径下的jar
- 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仓库搜索
第二个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等)食用效果更佳.... (๑乛◡乛๑)