数据计算平台重新搭建成功后,一切顠红,看起来心情就是舒畅,放个截图让心情爽一把:
后续当然需要做一些验证性的工作,以确保安装成功后一切都是执行ok的。
先放一些测试的json文件到hdfs的/tmp/test_json目录下,然后打开hue界面,进行hive sql执行窗口,先创建一个基于json文件的外部表:
create table json_table(`_id` string,`key` string, value string)
row format serde 'org.apache.hive.hcatalog.data.jsonserde'
stored as textfile
location '/tmp/test_json';
然后执行一下查询语句:
select * from json_table;
结果可以正常展示,然后再执行一个带条件的查询语句:
select * from json_table where `_id`='key1';
此时就报错了,hive的日志中体现出来的错误大致如下:
java.lang.runtimeexception: map operator initialization failed: org.apache.hadoop.hive.ql.metadata.hiveexception: java.lang.classnotfoundexception: class org.apache.hive.hcatalog.data.jsonserde not found
根据排查,该类存在于hive的hcategory包中,通过查找,其在我服务器的准确位置为/opt/cloudera/parcels/cdh-5.14.2-1.cdh5.14.2.p0.3/jars/hive-hcatalog-core-1.1.0-cdh5.14.2.jar。
这个错误虽然是hive日志中暴露出来的,但是很显然hive中肯定是已经引入了这个包的,要不然第一条不带条件的语句是不可能执行成功的,这个应该是hive调用的其它应用报出来的。
经过分析,hive在执行不带条件的sql语句时,如下:
select * from xx;
select * from xx limit 100;
hive为了加快执行速度,是通过fetch task模式执行的,而没有使用mr模式,因为这里没有涉及到复杂的计算,纯粹只是为了获取数据,这样处理可以节约处理的时间,也减少将其转换为mr模式的内存和cpu开销。
mr是通过yarn来最终执行的,而yarn中配置的mr执行引擎是spark,因而需要在yarn和spark中增加hive-hcatalog-core-1.1.0-cdh5.14.2.jar的引用,话说虽然简单,但是执行起来还是经过了一些折腾,特别是给spark增加jar包的引入。
以下是给spark增加lib包的失败尝试:
1.在${cdh_home}/lib/spark/lib目录下建立jar包的软链接;
2.把jar包拷贝到${cdh_home}/lib/spark/lib目录下;
3.在${cdh_home}/lib/spark/conf/classpath.txt中增加jar包路径;
4.在${cdh_home}/lib/spark/conf/spark-env.sh中增加jar包路径的路径;
每次做了以上的修改后,然后在cm上面重启spark,都希望这次修改能够生效,把依赖的jar包加到spark的运行环境中,可以每次回到命令行查看spark的classpath都没有将需要依赖的jar加进去,每次都伤心。
正在无解之时,无意中查看spark的启动参数时,发现spark使用的配置参数路径并不是我修改的spark的配置文件的路径,如下:
--properties-file /run/cloudera-scm-agent/process/797-spark_on_yarn-spark_yarn_history_server/spark-conf/spark-history-server.conf
而我修改的spark的配置文件路径是:
${cdh_home}/lib/spark/conf/
终于知道是cm的原因了,因为cm会在重新生成配置文件,即使${cdh_home}/lib/spark/conf/这个路径下面的配置文件也是根据cm中spark的配置生成的,即使在这个目录下做了修改,也会被cm给重写覆盖掉,测试的结果并不是cm每次都会重写这下面的配置文件,并不是每次通过cm重启spark这下面的配置文件都会修改,所以才不那么容易发现问题。
正确的解决办法:
1.在spark中增加新的jar包
在cm的spark配置文件所在页面,在“configuration->filter->category->advanced->spark service advanced configuration snippet (safety valve) for spark-conf/spark-env.sh”配置项中增加以下内容:
#以下脚本会写入的spark-env.sh中,是把外部目录下面的所有jar全部都加到spark的classpath
#/data/share_libs是共享外部类存放的路径,每台服务器上都有这个目录,hive-hcatalog-core-1.1.0-cdh5.14.2.jar已经在这下目录下建立了软链接到真实的文件
export share_jar_home=/data/share_libs
for f in $share_jar_home/*.jar
do
share_jar_classpath=$f:$share_jar_classpath
done
export share_jar_classpath
export spark_dist_classpath=$share_jar_classpath$spark_dist_classpath
加上以上脚本重启spark后,终于可以在命令行看到spark的classpath中包括了hive-hcatalog-core-1.1.0-cdh5.13.1.jar依赖jar包,spark本身已经不会报错找不到依赖的类了。
2.给yarn增加
找到yarn所在的目录${cdh_home}/lib/hadoop-yarn,在里面建立hive-hcatalog-core-1.1.0-cdh5.14.2.jar文件的软链接,每台服务器的yarn目录都建立这个软链接,然后重启yarn服务器,这个再执行终于不会报错了。