蜂房存储处理程序

Introduction

本页记录了在HBaseIntegration上作为工作的一部分添加到 Hive 的存储处理程序支持。目的是使 Hive 能够以模块化,可扩展的方式访问由其他系统存储和 Management 的数据。

除了 HBase,还可以为Hypertable提供存储处理程序实现,并且正在针对CassandraAzure TableJDBC(MySQL 和其他),MongoDBElasticSearchPhoenix HBaseVoltDBGoogle Spreadsheets开发其他实现。 Kafka handler演示可用。

Hive 存储处理程序支持基于 Hadoop 和 Hive 中现有的可扩展性功能:

  • input formats

  • output formats

  • serialization/deserialization libraries

除了将它们 Binding 在一起,存储处理程序还可以实现新的元数据钩子接口,从而允许 Hive DDL 同时且一致地用于 ManagementHive 元存储和其他系统目录中的对象定义。

Terminology

在存储处理程序之前,Hive 已经有了“托管”表与“外部”表的概念。托管表的定义主要在 Hive 的元存储中 Management,而 Hive 负责数据存储。外部表是其定义在某个外部目录中 Management 的表,并且其数据 Hive 不拥有(即,在删除表时不会删除它)。

存储处理程序在* native non-native *表之间进行了区分。本地表是 Hive 无需存储处理程序即可知道如何进行 Management 和访问的表。nonlocal 表是需要存储处理程序的表。

这两个区别(“托管”与“外部” *和“本地与 nonlocal”)是正交的。因此,基表有四种可能性:

  • 托管本机:默认情况下使用 CREATE TABLE 可获得的内容

  • 外部本机:未指定 STORED BY 子句时使用 CREATE EXTERNAL TABLE 会得到什么

  • 托管 nonlocal:指定 STORED BY 子句时使用 CREATE TABLE 会得到什么; Hive 将定义存储在其元存储中,但自身不会创建任何文件;而是调用存储处理程序并创建一个相应的对象结构的请求

  • 外部非本机:指定 STORED BY 子句后,使用 CREATE EXTERNAL TABLE 可获得的内容; Hive 在其元存储区中注册该定义,然后调用存储处理程序以检查其是否与另一个系统中的主定义匹配

请注意,在这些定义中我们避免使用术语“基于文件的*”,因为其他系统使用的存储形式无关紧要。

DDL

通过新的 STORED BY 子句创建表时,存储处理程序与表相关联,该表是现有 ROW FORMAT 和 STORED AS 子句的替代方法:

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
  [(col_name data_type [COMMENT col_comment], ...)]
  [COMMENT table_comment]
  [PARTITIONED BY (col_name data_type [col_comment], col_name data_type [COMMENT col_comment], ...)]
  [CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name, ...)] INTO num_buckets BUCKETS]
  [
   [ROW FORMAT row_format] [STORED AS file_format]
   | STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]
  ]
  [LOCATION hdfs_path]
  [AS select_statement]

如果指定了 STORED BY,则不能指定 row_format(DELIMITED 或 SERDE)和 STORED AS。可以将可选的 SERDEPROPERTIES 指定为 STORED BY 子句的一部分,并将传递给存储处理程序提供的 Serde。

有关更多信息,请参见CREATE TABLE行格式,存储格式和 SerDe

Example:

CREATE TABLE hbase_table_1(key int, value string) 
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES (
"hbase.columns.mapping" = "cf:string",
"hbase.table.name" = "hbase_table_0"
);

DROP TABLE 照常工作,但非本机表尚不支持 ALTER TABLE。

存储处理程序接口

下面是必须由存储处理程序实现的 Java 接口;有关详细信息,请参见代码中的 Javadoc:

package org.apache.hadoop.hive.ql.metadata;

import java.util.Map;

import org.apache.hadoop.conf.Configurable;
import org.apache.hadoop.hive.metastore.HiveMetaHook;
import org.apache.hadoop.hive.ql.plan.TableDesc;
import org.apache.hadoop.hive.serde2.SerDe;
import org.apache.hadoop.mapred.InputFormat;
import org.apache.hadoop.mapred.OutputFormat;

public interface HiveStorageHandler extends Configurable {
  public Class<? extends InputFormat> getInputFormatClass();
  public Class<? extends OutputFormat> getOutputFormatClass();
  public Class<? extends SerDe> getSerDeClass();
  public HiveMetaHook getMetaHook();
  public void configureTableJobProperties(
    TableDesc tableDesc,
    Map<String, String> jobProperties);
}

HiveMetaHook是可选的,并将在下一节中进行描述。如果getMetaHook返回非 null,则返回的对象的方法将作为 metastore 修改操作的一部分被调用。

configureTableJobProperties方法是计划作业以供 Hadoop 执行的一部分。存储处理程序负责检查表定义并在 jobProperties 上设置相应的属性。在执行时,只有这些 jobProperty 对 Importing 格式,输出格式和 Serde 可用。

另请参阅FilterPushdownDev,以了解存储处理程序如何参与过滤器评估(以避免全表扫描)。

HiveMetaHook Interface

HiveMetaHook界面如下所示;有关详细信息,请参见代码中的 Javadoc:

package org.apache.hadoop.hive.metastore;

import org.apache.hadoop.hive.metastore.api.MetaException;
import org.apache.hadoop.hive.metastore.api.Partition;
import org.apache.hadoop.hive.metastore.api.Table;

public interface HiveMetaHook {
  public void preCreateTable(Table table)
    throws MetaException;
  public void rollbackCreateTable(Table table)
    throws MetaException;
  public void commitCreateTable(Table table)
    throws MetaException;
  public void preDropTable(Table table)
    throws MetaException;
  public void rollbackDropTable(Table table)
    throws MetaException;
  public void commitDropTable(Table table, boolean deleteData)
    throws MetaException;

请注意,无论在 Hive 配置中是否使用远程 Thrift Metastore 进程,都始终从 HiveClient 端 JVM(而不是从 Thrift Metastore 服务器)进行元钩子调用。这意味着包含存储处理程序类的 jar 需要在 Client 端上可用,但在二手服务器上不可用。

还要注意,在针对 Hive 元存储和存储处理程序的元数据事务中没有两阶段提交的功能。结果,有一个很小的窗口,DDL 期间的崩溃可能导致两个系统不同步。

Open Issues

  • 当前,存储处理程序类名称是通过表属性storage_handler保存到 metastore 的;这可能应该是 MStorageDescriptor 上的一流属性

  • 根据存储处理程序在 CREATE TABLE 期间返回的内容,将帮助程序类的名称(例如 Importing 格式和输出格式)保存到 metastore 中。最好将这些保留为空,以防以后在处理程序升级中更改它们时

  • 即使未为其创建 Hive 文件,当前也为 nonlocal 表设置了虚拟位置(就好像它是本地表一样)。我们希望存储 null,但是首先我们需要解决将数据源信息传递到 Importing 格式的方式(HIVE-1133)

  • 当前仅在表级别设置存储处理程序。我们可能希望允许为每个分区指定它们,包括支持跨越不同存储处理程序的表。

  • FileSinkOperator 可能应该重构,因为 nonlocal 表不会作为文件访问,这意味着很多逻辑与它们无关

  • 作为临时目录修复操作的一部分,支持临时禁用元存储库钩子可能是一个好主意。

  • CREATE TABLE 语法并不像上面给出的那样严格。为了防止同时指定 STORED BY 和 row_format,需要进行一些更改

  • 当前禁止创建 nonlocal 表的 CREATE TABLE AS SELECT。尽管并非对所有存储处理程序都有意义,但应该有可能支持这一点。例如,对于 HBase,直到存储处理程序能够自动填写列 Map 才有意义。