优化使用基础 HBase 表的 Hive 查询



我在 Hbase 中有一个表,让我们说"tbl",我想使用 蜂房。因此,我将一个表映射到 hive,如下所示:

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 在作业跟踪器上生成的映射作业时,我 发现"map.input.records"计算了Hbase表中的所有项目, 这意味着该作业甚至在启动任何映射器之前都会进行全表扫描!! 此外,我怀疑它将所有数据从 Hbase 表复制到 hdfs 到 执行前的映射器 TMP 输入文件夹。

所以,我的问题是 - 为什么 hbase 存储处理程序的 hbase 不转换 将查询转换为适当的 HBase 函数?为什么它会扫描所有记录 然后使用"where"子句将它们切片?如何改进?

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

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

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

很多问题!,我将尝试回答所有问题,并为您提供一些性能提示:

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

HBase 不支持二级索引或备用查询路径(详细信息)。

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

Hive HBase 处理程序在从查询中提取开始和停止行键时做得不是很好,像substr(id, 0, 5) = "12345"这样的查询不会使用开始和停止行键。

在执行查询之前,请运行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
....

幸运的是,有一种简单的方法可以确保在查找行键前缀时使用开始和停止行键,只需将substr(id, 0, 5) = "12345"转换为更简单的查询:id>="12345" AND id<"12346",处理程序将检测到它,并开始和停止行键将提供给扫描(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 *

  • 每当您想使用开始和停止行键来防止全表扫描时,请始终提供key>=xkey<y表达式(不要使用 BETWEEN 运算符)

  • 在执行查询之前,请务必EXPLAIN SELECT查询。

最新更新