我在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查询的性能。
答案 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>=x
和key<y
表达式(不要使用BETWEEN运算符)
执行前始终EXPLAIN SELECT
您的查询。