1

跟随此链接https://cwiki.apache.org/confluence/display/Hive/HBaseIntegration#HBaseIntegration-HiveMAPtoHBaseColumnFamily

我正在尝试集成 hive 和 hbase,我在 hive-site.xml 中有这个配置:

<property>
  <name>hive.aux.jars.path</name>
  <value>
    file:///$HIVE_HOME/lib/hive-hbase-handler-2.0.0.jar,
    file:///$HIVE_HOME/lib/hive-ant-2.0.0.jar,
    file:///$HIVE_HOME/lib/protobuf-java-2.5.0.jar,
    file:///$HIVE_HOME/lib/hbase-client-1.1.1.jar,
    file:///$HIVE_HOME/lib/hbase-common-1.1.1.jar,
    file:///$HIVE_HOME/lib/zookeeper-3.4.6.jar,
    file:///$HIVE_HOME/lib/guava-14.0.1.jar
  </value>
</property>

然后在 hbase 中创建一个名为 'ts:testTable' 的表:

hbase> create 'ts:testTable','pokes'
hbase> put 'ts:testTable', '10000', 'pokes:value','val_10000'
hbase> put 'ts:testTable', '10001', 'pokes:value','val_10001'
...

hbase> scan  'ts:testTable'
ROW                       COLUMN+CELL
 10000                    column=pokes:value, timestamp=1462782972084, value=val_10000
 10001                    column=pokes:value, timestamp=1462783514212, value=val_10001
....

然后在 hive 中创建外部表:

Hive> CREATE EXTERNAL TABLE hbase_test_table(key int, value string )
       STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
       WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key, pokes:value")
       TBLPROPERTIES ("hbase.table.name" = "ts:testTable",
       "hbase.mapred.output.outputtable" = "ts:testTable");

到现在为止还挺好。但是当我试图从测试表中选择数据时,抛出了异常:

Hive> select * from hbase_test_table;
FAILED: RuntimeException java.lang.ClassNotFoundException: NULL::character varying
Error: Error while compiling statement: FAILED: RuntimeException java.lang.ClassNotFoundException: NULL::character varying (state=42000,code=40000)

我错过了什么吗?

我正在尝试 Hive 2.0.0 和 HBase 1.2.1

4

1 回答 1

1

好的,我想通了,“NULL::character varying”不是 hive 的一部分,它来自 Postgresql,因为我将它用作 Metastore 的后端。但问题是 Hive 无法识别 Postgresql 的这个异常。我们为 Hive 2.0.0 提供了以下代码:

300: if (inputFormatClass == null) {
301:   try {
302:     String className = tTable.getSd().getInputFormat();
303:     if (className == null) {
304:       if (getStorageHandler() == null) {
305:         return null;
306:       }
307:      inputFormatClass = getStorageHandler().getInputFormatClass();
308:  } else {
309:  inputFormatClass = (Class<? extends InputFormat>)
310:    Class.forName(className, true, Utilities.getSessionSpecifiedClassLoader());
    }

第 302 行不会返回应该返回的 null。这样第 310 行将尝试加载一个不存在的类。这就是程序失败的原因。

我相信这是一个兼容的错误,修复它的方法是更改​​我讨厌的数据库。所以我只是简单地将 302 替换为

if (className == null || className.toLowerCase().startsWith("null::")) {

并对getOutputFormat()方法做同样的事情,然后重新编译jar,就这样。

于 2016-05-11T07:15:37.310 回答