Hive集成HBase(一)

Hive集成HBase(二)

在介绍Hive集成HBase的使用之前,我们先看看Hive和HBase之间通信用到的一个包,这个包至关重要,容不得有半点差池,否则就会集成失败。下面这个官网链接可供参考https://cwiki.apache.org/confluence/display/Hive/StorageHandlers。因此,第一篇文章先讨论Hive和HBase的通信包,第二篇才开始介绍Hive集成HBase之后的使用。

1.hive-hbase-handler.jar

在Hive继承HBase中,二者的通信包就是hive-hbase-handler.jar,极其重要。如果我们用$HIVE_HOME/lib目录下的hive-hbase-handler-x.y.z.jar,那么一般都不会集成成功,反而报错如:


FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. org.apache.hadoop.hbase.HTableDescriptor.addFamily(Lorg/apache/hadoop/hbase/HColumnDescriptor;)V



这说明Hive和HBase的版本不兼容。因此,我们必须根据自己安装的Hive和HBase的版本自己重新编译hive-hbase-handler.jar,而且还有修改hive-handler的源码(

没错,你绝对没有看错我们要修改源代码。不过,不要恐慌,我们只修改两三行代码而已)



2.编译hive-hbase-handler源码

hive-hbase-handler的源码在Hive源码中,因此,我们需要先在下载Hive源码,官网地址:

http://mirror.bit.edu.cn/apache/hive/


现在我们按照以下步骤来完成编译:


1.把hive-hbase-handler源码导入到Eclipse中

首先,需要在Eclipse中新建一个Java项目,项目名可以随便起,如hivehbase。

hive和hbase整合原理 hive与hbase集成_Hive

然后,我们在src目录下导入hive-handler源码。




hive和hbase整合原理 hive与hbase集成_hive和hbase整合原理_02


在Hive源码中找到hive-handler源码,切记现在hive-handler目录下的java目录,而不是把hive-handler导入

hive和hbase整合原理 hive与hbase集成_hive_03

hive和hbase整合原理 hive与hbase集成_hive_04

接着,选择org目录即可。

hive和hbase整合原理 hive与hbase集成_hbase_05

2.下载依赖jar包

注意:不同版本之间的集成依赖的包的数量和种类不一样。

依赖的jar包有这么些(Hive1.0.1和HBase1.1.3集成)。



hive和hbase整合原理 hive与hbase集成_hive和hbase整合原理_06


再看Hive1.2.1和HBase0.98的集成,需要的jar却是(其实,如果不修改源代码还需要high-scale-lib-x.y.z.jar,在下一节我会告知在哪里修改源代码):



hive和hbase整合原理 hive与hbase集成_hive和hbase整合原理_07



关于这些jar包在哪下载,我们可以去Maven中央仓库http://repo.maven.apache.org/maven2/。但是,有一个jar包——high-scale-lib-x.y.z.jar在Maven中央仓库找不到,它的下载地址是http://www.java2s.com/Code/Jar/h/Downloadhighscalelib10jar.htm。不过还是建议在$HIVE_HOME\lib和$HBASE_HOME\lib里面找相应的jar。关于high-scale-lib-x.y.z.jar,我们后面还要提到 high-scale-lib-x.y.z.jar。然后,把上述jar包加入CLASSPATH就不会报错了。如果到此,你觉得已经没错了,可以编译了。那么,你就大错特错了(除非你用的是HBase1.0之前的版本)。因为你用此时编译的hive-hbase-handler.jar,当把Hive表存到HBase表中时,会报错:

java.lang.NoClassDefFoundError: org/cliffc/high_scale_lib/Counter。



3.修改hive-handler源代码

前面让你留意了high-scale-lib-x.y.z.jar,因为正是high-scale-lib-x.y.z.jar,才使得我们需要修改hive-handler源码。我们找到org.apache.hadoop.hive.hbase.HBaseStorageHandler,然后定位到472行(仅对于Hive1.0.1),可以看到org.cliffc.high_scale_lib.Counter.class。


我们可以找到源码:


TableMapReduceUtil.addDependencyJars(
          jobConf, HBaseStorageHandler.class, TableInputFormatBase.class,
          org.cliffc.high_scale_lib.Counter.class); // this will be removed for HBase 1.0



看到后面的注释,所以我们把这三行代码修改为:

TableMapReduceUtil.addDependencyJars(
          jobConf, HBaseStorageHandler.class, TableInputFormatBase.class);


对于Hive1.2.1的源码又不一样了,找到org.apache.hadoop.hive.hbase.HBaseStorageHandler,定位到源码:

private static Class counterClass = null;
  static {
    try {
      counterClass = Class.forName("org.cliffc.high_scale_lib.Counter");
    } catch (ClassNotFoundException cnfe) {
      // this dependency is removed for HBase 1.0
    }
  }
  @Override
  public void configureJobConf(TableDesc tableDesc, JobConf jobConf) {
    try {
      HBaseSerDe.configureJobConf(tableDesc, jobConf);
      /*
       * HIVE-6356
       * The following code change is only needed for hbase-0.96.0 due to HBASE-9165, and
       * will not be required once Hive bumps up its hbase version). At that time , we will
       * only need TableMapReduceUtil.addDependencyJars(jobConf) here.
       */
      if (counterClass != null) {
        TableMapReduceUtil.addDependencyJars(
          jobConf, HBaseStorageHandler.class, TableInputFormatBase.class, counterClass);
         
      }



严格来讲应该修改成:

//  private static Class counterClass = null;
//  static {
//    try {
//      counterClass = Class.forName("org.cliffc.high_scale_lib.Counter");
//    } catch (ClassNotFoundException cnfe) {
//      // this dependency is removed for HBase 1.0
//    }
//  }
  @Override
  public void configureJobConf(TableDesc tableDesc, JobConf jobConf) {
    try {
      HBaseSerDe.configureJobConf(tableDesc, jobConf);
      /*
       * HIVE-6356
       * The following code change is only needed for hbase-0.96.0 due to HBASE-9165, and
       * will not be required once Hive bumps up its hbase version). At that time , we will
       * only need TableMapReduceUtil.addDependencyJars(jobConf) here.
       */
      if (counterClass != null) {
        TableMapReduceUtil.addDependencyJars(
//          jobConf, HBaseStorageHandler.class, TableInputFormatBase.class, counterClass);
          jobConf, HBaseStorageHandler.class, TableInputFormatBase.class);
      }



但是,也可以只修改成这样即可:

if (counterClass != null) {
        TableMapReduceUtil.addDependencyJars(
//          jobConf, HBaseStorageHandler.class, TableInputFormatBase.class, counterClass);
          jobConf, HBaseStorageHandler.class, TableInputFormatBase.class);
      }


4.打包

现在我们终于可以打包了。这个jar是不可执行的。



hive和hbase整合原理 hive与hbase集成_hbase_08