调整使用底层HBase表的Hive查询

时间:2015-05-06 10:56:41

标签: performance hadoop hive hbase integration

我在Hbase中有一个表让我们说“tbl”,我想用它来查询它 蜂巢。因此,我将表映射到配置单元如下:

CREATE EXTERNAL TABLE tbl(id string, data map<string,string>)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,data:")
TBLPROPERTIES("hbase.table.name" = "tbl");

查询如:

select * from tbl", "select id from tbl", "select id, data
from tbl

非常快。

但像

这样的查询
select id from tbl where substr(id, 0, 5) = "12345"

select id from tbl where data["777"] IS NOT NULL 

非常慢。

从Hbase shell运行时相反:

"scan 'tbl', {
COLUMNS=>'data', STARTROW='12345', ENDROW='12346'}" or
"scan 'tbl', { COLUMNS=>'data', "FILTER" =>
FilterList.new([qualifierFilter('777')])}"
它快闪电了!

当我查看由hive在jobtracker上生成的mapred作业时 发现“map.input.records”计算Hbase表中的所有项目, 这意味着工作甚至在启动任何映射器之前进行全表扫描! 此外,我怀疑它将所有数据从Hbase表复制到hdfs 执行前的mapper tmp输入文件夹。

所以,我的问题是 - 为什么hive的hbase存储处理程序不能翻译 hive查询到适当的hbase函数?为什么它会扫描所有记录 然后使用“where”子句对它们进行切片?如何改进?

任何提高Hive查询性能的建议(映射到HBase表)。

我们可以在HBase表上创建二级索引吗?

我们正在使用HBase和Hive集成,并尝试调整Hive查询的性能。

1 个答案:

答案 0 :(得分:10)

很多问题!我会尽力回答所有问题,并提供一些性能提示:

数据不会复制到HDFS,但HIVE生成的mapreduce作业会将其中间数据存储在HDFS中。

HBase(more info)不支持辅助索引或备用查询路径。

Hive会将所有内容转换为需要时间分发的MapReduce作业。初始化,如果你的行数非常少,那么Hbase shell中的简单SCAN操作比Hive查询更快,但是对于大数据集,在数据节点之间分配作业是必须的。

Hive HBase处理程序在提取启动和启动时并没有做得很好。从查询中停止行键,substr(id, 0, 5) = "12345"之类的查询将不会使用start&amp;停止行键。

在执行查询之前,运行EXPLAIN [your_query];命令并检查 filterExpr: 部分,如果找不到,您的查询将执行全表扫描。在旁注中, Filter Operator: 中的所有表达式都将转换为适当的过滤器。

EXPLAIN SELECT * FROM tbl WHERE (id>='12345') AND (id<'12346')
STAGE PLANS:
  Stage: Stage-1
    Map Reduce
      Alias -> Map Operator Tree:
        tbl 
          TableScan
            alias: tbl 
            filterExpr:
                expr: ((id>= '12345') and (id < '12346'))
                type: boolean
            Filter Operator
                ....

幸运的是,有一种简单的方法可以确保开始&amp;当您查找行键前缀时,会使用停止行键,只需将substr(id, 0, 5) = "12345"转换为更简单的查询:id>="12345" AND id<"12346",它将由处理程序检测并启动&amp;停止行键将提供给SCAN(12345,12346)

现在,这里有一些提示,以加快您的查询(很多):

  • 确保设置以下属性以利用批处理来减少RPC调用的数量(数量取决于列的大小)

    SET hbase.scan.cache=10000;

    SET hbase.client.scanner.cache=10000;

  • 确保设置以下属性以在任务跟踪器中运行分布式作业,而不是运行本地作业。

    SET mapred.job.tracker=[YOUR_JOB_TRACKER]:8021;

    SET hbase.zookeeper.quorum=[ZOOKEEPER_NODE_1],[ZOOKEEPER_NODE_2],[ZOOKEEPER_NODE_3];

  • 将SELECT语句的列数减少到最少。尽量不要SELECT *

  • 每当你想使用start&amp;停止行键以防止全表扫描,始终提供key>=xkey<y表达式(不要使用BETWEEN运算符)

  • 执行前始终EXPLAIN SELECT您的查询。