上个月通过email,帮朋友的朋友解决了一个Cloudera的Spark-SQL无法访问HBase做数据分析的问题,记录一下。
首先,对方已经做好了Hive访问HBase,所以spark-sql原则上可以通过调用Hive的元数据来访问Hbase。但是执行极慢,而且日志无报错。中间都是邮件沟通,先问了几个问题,是否启用了Kerberos,是否Hive访问Hbase正常,HBase shell访问数据是否正常等等,回答说没有用Kerberos,Hive访问Hbase正常,spark-sql读取Hive元数据也正常,Hbase shell也正常,就是spark-sql跑不了。
其次,对方有两套环境,实验室环境可以跑,但是生产环境不能跑,然后实验室和生产环境版本和各种xml配置都完全一样,所以实在找不到不能跑的原因了。
前期看日志,由于没有任何WARN或ERROR,所以很难排查,初步推断是由于配置错误造成的,但是哪里配置错误,因为都是邮件,无法确定。后来对方又发过来一个日志,说约3小时后报错,显示如下。
Job aborted due to stage failure: Task 0 in stage 0.0 failed 4 times, most recent failure: Lost task 0.3 in stage 0.0 (TID 3, BData-h2): org.apache.hadoop.hbase.client.NoServerForRegionException: Unable to find region for in xxxxxxxx after 35 tries.
Spark界面中的这段报错证明了确实是配置错误的这个推断,这个报错通常是由于Spark无法通过API访问Hbase的Region造成的。那么,如果是cloudera版的,都是预先就已经做好兼容性了,所以可以排除因兼容性问题导致的无法访问,那么只能有一个原因就是配置错误。
接着对比了一下实验室环境和生产环境的spark启动日志,发现两边所加载的jar包不一致,推断是spark-env或者是hbase-env配置有出入导致的,将这一推断告知对方,并建议将hbase/lib/*和hbase-site.xml等文件写入到spark的SPARK_DIST_CLASSPATH中。于是对方将hbase/lib和/etc/hbase/conf路径添加到SPARK_DIST_CLASSPATH中,问题解决。
这个排错是个特别小的问题,但是本着可能会对他人有帮助,同时自己别忘了的原则,还是记录一下。