Cloudera Impala官方文档中文翻译-2(Using Impala to Query HBase Tables)

Using Impala to QueryHBase Tables(利用impala查询HBase Tables)

默认情况下,impalatable使用存储在HDFS中的数据文件,这种存储方式适用于批量数据加载和查询(bulk loads and query)。相反,HBase可以对用于OLTP风格的负载的数据进行高效率查询,比如查找单个row或者一个range的values。

对于impala用户来说,HBase是key-value存储形式的数据库,value包含多个fields。Key在impala table中被map到某一个column,而value的各个fields被map到impala table的其他columns。

Overview of Using HBasewith Impala(概览)

使用impala withHBase时:

l  使用Hive shell创建table

A、可以使用STORED BY

‘org.apache.hadoop.hive.hbase.HBaseStorageHandler ‘语句

B、直接把impala table map到一个已有的HBase table中

l  Map到HBase row key的impala column必须是string类型的

l  由于impala和hive共享metastore,一旦在hive中创建table后,在impalashell中使用INVALIDATE METADATA语句刷新即可看到新的table

l  在impala中查询HBase数据时,尽量使用WHERE从句定位单个key或者一个key range,这样可以提高查询效率,全表scan对于HBase效率很低

确保impala user具有对HBasetable的read/write权限。

Configuring HBase for Usewith Impala(配置)

HBase在Impala Box之外工作,没有强制需要的配置。

为了避免在HBase不可用的情况下,impala启动或者更新元数据的延迟,Cloudera建议设置timeoutvalue在/etc/impala/conf/hbase-site.xml中(在非Cloudera Manager的环境下才需要):

<property>
  <name>hbase.client.retries.number</name>
  <value>3</value>
</property>
<property>
  <name>hbase.rpc.timeout</name>
  <value>3000</value>
</property>

目前,ClouderaManager并不提供仅针对impala的HBase特有配置文件,所以你在Cloudera Manager中进行的任何的HBase配置更改都会在所有的HBase applications中生效。因此,这个timeout配置不建议在cloudera manager中设置。

Supported Data Types forHBase Columns(针对HBase列支持的数据类型)

为了弄清Impalacolumn数据如何映射到HBase中的字段(field),你应该有一些关于HBase的背景知识。在Hive shell中利用CREATE TABLE语句设置映射关系。见theHive wiki作为起点,Examples
of Querying HBase Tables from Impala
作为例子。

HBase作为一种“bitbucket”进行工作,它并不强制要求对key或者value字段输入值,所有的强制输入都是在Impala这边进行的。

为了在impala查询HBase时获得最好的性能,大多数查询会在WHERE中的column对应的row key进行比较操作。当在Hive shell中创建table时,把映射为HBase row key列的那一列设置为STRING类型。Impala可以把针对某个column的条件测试(例如操作符=, <, BETWEEN, 和IN)翻译成HBase中的快速查找,但是这个优化(predicate push down即谓词下推)仅当列为STRING类型时才有效。

从Impala 1.1开始,Impala也支持读写在HiveCREATE TABLE语句中定义的二进制类型的列,即在Hive table中使用#binary定义(通常简写为#b)。定义数值column为二进制类型通常可以降低其在HBase table中的空间占用。

切记Row key列定义成string类型的,这样可以进行快速查找。其他列可以为binary类型的,这样可以节省存储空间。

Performance Considerationsfor the Impala-HBase Integration(性能考虑)

为了理解HBase上进行SQL查询的性能特点,你应该有一些相关的背景知识。可以以 the Hive
wiki
为起点,因为Impala与Hive共享同一个metastore,所以Hive table到HBase table的列映射信息也适用于Impala。

Impala使用HBaseclient API通过JNI来查询HBase的数据。查询不直接读HFiles。额外的通信开销使得选择将数据存储在HBase还是HDFS变得很重要,同时构造高效的查询可以高效地获取HBase数据也变得很重要。

l  使用HBase table用来进行singlerow或者一个range of rows的查询,而不是scan entire table的query(如果query中不包含WHERE从句,说明很可能它对于HBase table是低效率的)

l  如果你做一个join查询,在一个大的facttable上做汇总操作,然后将结果与一个小维度的table进行join操作,考虑使用Impala存储fact table,并且HBase存储这个小维度table(因为Impala在这种情况下会对HBase table进行全表scan,而不是做single-row的HBase查找,基于这个join column,只有在HBase table足够小的情况下,全表扫描才不至于时间过长,这样才不会出现查询性能瓶颈)

Query predicates(谓词、判断)用来表示row key的start和stop key,从而限制了lookup操作的scope。如果row key不对应string类型的列,那么通常是无法正确排序的,因为comparison操作无法正常进行。

Non-key列的谓词判断被发送到HBase作为SingleColumnValueFilters进行scan,提供一些性能提升。这种情况下,HBase比在impala中使用相同的谓词返回更少的行(?这句没看懂)。尽管non-key列谓词的使用会有一些性能提升,但是这种提升与使用row-key谓词的情况相比还是微不足道的。因为这种情况下,HBase要扫描的总行数依然是没有限制的。只要有row key的predicate,那么HBase就能快速定位并返回那一行,相反的是,如果只有non-key的predicate,那么即使查询结果只有一行,HBase也要进行全表scan。

Interpreting EXPLAINOutput for HBase Queries(理解EXPLAIN语句的输出)

例如,这有一些针对Impalatable(已经映射到HBase table)的查询。例子中展示了除了EXPLAIN语句的输出,还可以看到根据哪些信息可以预知该查询针对HBase table是否是高效的查询。

第一列(cust_id)在CREATEEXTERNAL TABLE语句中被指定为key列,将该列声明为STRING类型对于性能来说是很重要的;其他列例如BIRTH_YEAR, NEVER_LOGGED_ON也声明为STRING,而不是它们本来的INT和BOOLEAN类型,因为Impala可以在HBasetable中更高效地优化这些类型。为了比较,我们将YEAR_REGISTERED这列声明为INT类型,来展示针对这一列的filtering是低效的。

describe hbase_table;
Query: describe hbase_table
+-----------------------+--------+---------+
| name                  | type   | comment |
+-----------------------+--------+---------+
| cust_id               | string |         |
| birth_year            | string |         |
| never_logged_on       | string |         |
| private_email_address | string |         |
| year_registered       | int    |         |
+-----------------------+--------+---------+

关于使用row key列等值比较条件进行单行查询是性能最好的例子:

explain select count(*) from hbase_table where cust_id = ‘[email protected]‘;
+------------------------------------------------------------------------------------+
| Explain String                                                                     |
+------------------------------------------------------------------------------------+
| Estimated Per-Host Requirements: Memory=1.01GB VCores=1                            |
| WARNING: The following tables are missing relevant table and/or column statistics. |
| hbase.hbase_table                                                                  |
|                                                                                    |
| 03:AGGREGATE [MERGE FINALIZE]                                                      |
| |  output: sum(count(*))                                                           |
| |                                                                                  |
| 02:EXCHANGE [PARTITION=UNPARTITIONED]                                              |
| |                                                                                  |
| 01:AGGREGATE                                                                       |
| |  output: count(*)                                                                |
| |                                                                                  |
| 00:SCAN HBASE [hbase.hbase_table]                                                  |
|    start key: [email protected]                                                |
|    stop key: [email protected]\0                                               |
+------------------------------------------------------------------------------------+

另外一类高效查询是针对rowkey列的一个range查找,使用SQL操作符例如>, <, =, BETWEEN。下面例子也包好一个non-key列的等值test,因为这一列也是STRING类型。Impala可以HBase执行这个test,体现在hbase filter中(见下面的output),在HBase中进行filtering比将数据全部传给impala再在impala这边进行filtering更高效。

explain select count(*) from hbase_table where cust_id between ‘a‘ and ‘b‘
  and never_logged_on = ‘true‘;
+------------------------------------------------------------------------------------+
| Explain String                                                                     |
+------------------------------------------------------------------------------------+
...

| 01:AGGREGATE                                                                       |
| |  output: count(*)                                                                |
| |                                                                                  |
| 00:SCAN HBASE [hbase.hbase_table]                                                  |
|    start key: a                                                                    |
|    stop key: b\0                                                                   |
|    hbase filters: cols:never_logged_on EQUAL ‘true‘                                |
+------------------------------------------------------------------------------------+

这样的查询是低效的:如果Impala必须评估一些predicates,因为Impala必须scan整个HBase table。Impala只能把关于STRING类型column的predicate下推给HBase处理,而下例中是INT类型,故output中最下面的predicate:这一行表示这个等值test会在数据都传输给impala之后才能进行:(即explain输出的predicate:语句不会在HBase中执行,这一点与hbase
filters、start key、stop key不同)

explain select count(*) from hbase_table where year_registered = 2010;
+------------------------------------------------------------------------------------+
| Explain String                                                                     |
+------------------------------------------------------------------------------------+
...

| 01:AGGREGATE                                                                       |
| |  output: count(*)                                                                |
| |                                                                                  |
| 00:SCAN HBASE [hbase.hbase_table]                                                  |
|    predicates: year_registered = 2010      

这样的查询也是低效的:如果key列与任何非常量值进行比较。这里,即使key column是STRING类型的,并且使用=操作符,Impala也必须scan整个HBase table,因为key column是与另外一列的value进行比较,而不是一个常量:

explain select count(*) from hbase_table where cust_id = private_email_address;
+------------------------------------------------------------------------------------+
| Explain String                                                                     |
+------------------------------------------------------------------------------------+
...

| 01:AGGREGATE                                                                       |
| |  output: count(*)                                                                |
| |                                                                                  |
| 00:SCAN HBASE [hbase.hbase_table]                                                  |
|    predicates: cust_id = private_email_address                                    |
+------------------------------------------------------------------------------------+

当前,针对row key的OR,IN语句test没有优化成直接的查找,这个限制未来可能会被解决。所以请每次check EXPLAIN的output来观察你的query是否是一个对于HBase table来说高效的查询。

explain select count(*) from hbase_table where
  cust_id = ‘[email protected]‘ or cust_id = ‘[email protected]‘;
+----------------------------------------------------------------------------------------+
| Explain String                                                                         |
+----------------------------------------------------------------------------------------+
...

| 01:AGGREGATE                                                                           |
| |  output: count(*)                                                                    |
| |                                                                                      |
| 00:SCAN HBASE [hbase.hbase_table]                                                      |
|    predicates: cust_id = ‘[email protected]‘ OR cust_id = ‘[email protected]‘ |
+----------------------------------------------------------------------------------------+

explain select count(*) from hbase_table where
  cust_id in (‘[email protected]‘, ‘[email protected]‘);
+------------------------------------------------------------------------------------+
| Explain String                                                                     |
+------------------------------------------------------------------------------------+
...

| 01:AGGREGATE                                                                       |
| |  output: count(*)                                                                |
| |                                                                                  |
| 00:SCAN HBASE [hbase.hbase_table]                                                  |
|    predicates: cust_id IN (‘[email protected]‘, ‘[email protected]‘)      |
+------------------------------------------------------------------------------------+

拆分成单个针对单行的查询,然后在application中合并结果,或者combine单行查询使用UNION ALL关键词:

select count(*) from hbase_table where cust_id = ‘[email protected]‘;
select count(*) from hbase_table where cust_id = ‘[email protected]‘;

explain
  select count(*) from hbase_table where cust_id = ‘[email protected]‘
  union all
  select count(*) from hbase_table where cust_id = ‘[email protected]‘;
+------------------------------------------------------------------------------------+
| Explain String                                                                     |
+------------------------------------------------------------------------------------+
...

| |  04:AGGREGATE                                                                    |
| |  |  output: count(*)                                                             |
| |  |                                                                               |
| |  03:SCAN HBASE [hbase.hbase_table]                                               |
| |     start key: [email protected]                                            |
| |     stop key: [email protected]\0                                           |
| |                                                                                  |
| 10:MERGE                                                                           |
...

| 02:AGGREGATE                                                                       |
| |  output: count(*)                                                                |
| |                                                                                  |
| 01:SCAN HBASE [hbase.hbase_table]                                                  |
|    start key: [email protected]                                                |
|    stop key: [email protected]\0                                               |
+-------------------------------------------

总结

即尽量使用string类型的列,尽量使用WHERE限制key的范围,这样避免将所有数据传输到impala中进行查找。

Impala只能把针对STRING类型列的predicates下推到HBase中去,但是对于其他类型比如INT型的column的predicate,只能是在impala这边做过滤,所以必须对HBase进行全表scan。

如果key column不是和常量值进行比较,那么也是低效的,也要进行全表扫描,比如select count(*) from hbase_table where cust_id =private_email_address。

Configuration Options forJava HBase Applications(配置参数)

如果你有一个HBaseJava application调用了 org.apache.hadoop.hbase.client.Scan的setCacheBlocks或者setCaching方法,你也可以使用Impala查询参数来设置这些值来控制HBaseregion
server的内存压力。例如,当在HBase中进行查询并导致全表scan是,你可以通过关闭HBASE_CACHE_BLOCKS设置并指定一个很大的值给HBASE_CACHING来降低内存占用并且加速查询。

设置这些参数,在impala-shell中执行如下命令:

-- Same as calling setCacheBlocks(true) or setCacheBlocks(false).
set hbase_cache_blocks=true;
set hbase_cache_blocks=false;

-- Same as calling setCaching(rows).
set hbase_caching=1000;

或者更新impalad的默认文件/etc/default/impala,并且设置HBASE_CACHE_BLOCKSand/or HBASE_CACHING in the -default_query_options setting forIMPALA_SERVER_ARGS。细节请参考Modifying
Impala Startup Options

Note:在Impala 2.0或者更新版本中,这些选项是可设置的,通过JDBC或者ODBC接口,使用SET语句。

Use Cases for QueryingHBase through Impala(用例)

Impala查询HBase table的通常情景:

l  在impala中保存大的facttables,在HBase中保存smaller dimension tables。Fact tables使用Parquet或者其他类型的二进制格式(针对scan操作进行优化的)文件存储。Join操作scan这个大的impala fact table,并且使用高效的single-row lookup来交叉引用HBase中的table。即大表和小表join时,用impala扫描大表,结果作为join过滤条件传给HBase,以快速定位对应的row。

l  使用HBase存储快速增长的counter数据,比如一个webpage已经被访问了多少次,一个user已经发起了多少次连接等。HBase对于捕捉这种变化无常的data是非常有效的,因为它的append-only存储机制对于把每个change写入disk非常高效,并且一个query总是返回最新的value。

l  在HBase中存储非常wide的table。Wide table可能有几千个columns,通常记录着某个项目的很多属性。这些table通常是sparse的,大部分列的值是NULL或者0、false、空字符串等。例如某个网站服务的用户作为一个row,他可能仅仅用过其中的几个服务,通常的query是:查找一个single row,提取出所有列的信息,而不是做sum、averge等impala中常见的操作。

比如impala table中存储着某个网站的流量信息(一张大表),impala选出了浏览该网站的50个user,现在如果要看这些user的属性的话,我们只需与HBase中存储的user table进行join,这样只需scan这50个rows,而不必扫描全表。

Loading Data into an HBaseTable(加载数据到HBasetable中)

Impala中可以对HBase表insert单行,因为插入单行操作对于HBase本来就是有效的,但是对于存储在HDFS中的其他impala table,insert单行是不行的,因为这样会产生很多小文件,必须批量插入。

Impala中没有update语句,但是使用相同的rowkey进行insert时可以起到update的效果,因为相同的row key插入时会覆盖原来的value。

Limitations andRestrictions of the Impala and HBase Integration(二者集成的限制和束缚)

l  Impala中的DROP TABLE语句执行后,HBase中的table没有remove,只是impala中的remove了

l  Hive中支持INSERT OVERWRITE语句,可以清空整个table,然后插入新数据,但是impala里不支持对于HBase table的这类语句,你只能插入新行或者使用相同的row key更新原有行

l  Impala中对HBase table执行CREATE TABLE LIKE语句时,在HBase中发生的是产生一个对旧表的别名,并没有完全复制出一个新表,所以应该避免使用此语句

l  在impala中使用INSERT…SELECT语句向HBasetable中插入数据时,首先插入的行数可能比SELECT出来的少,因为各个行可能有key列值相同的,那样就只会产生一列结果,其次,无法保证多个相同key的rows插入时,由于后来的row会替换已有row的值,这样就没法保证最终插入的row的值是最新的了,谨慎使用。

Examples of Querying HBaseTables from Impala(查询实例)

1、  首先在HBase中创建一个表,HBase中创建的table是“enabled”状态,在hbaseshell中dropping:他们之前必须执行disable ‘table_name’语句;

$ hbase shell
...
create ‘hbasealltypessmall‘, ‘bools‘, ‘ints‘, ‘floats‘, ‘strings‘
quit

2、在hive中创建外部表指向HBasetable,注意用来做key的列最好使用string类型,其他类型也可以,但是lookup的速度要慢很多,string最快;

下例中创建了一个外部表映射到hbase table中。由于是一个外部表,所以在impala或者Hive中drop之后,原始的hbase table并没有删除。STORED BY语句目前在Impala中还不支持,所以需要在Hive shell中使用CREATE TABLE语句执行。WITH SERDEPROPERTIED语句声明了第一列(id)代表row key列,并且映射其余列到HBase列簇中。

$ hive
...
hive> CREATE EXTERNAL TABLE hbasestringids (
  id string,
  bool_col boolean,
  tinyint_col tinyint,
  smallint_col smallint,
  int_col int,
  bigint_col bigint,
  float_col float,
  double_col double,
  date_string_col string,
  string_col string,
  timestamp_col timestamp)
STORED BY ‘org.apache.hadoop.hive.hbase.HBaseStorageHandler‘
WITH SERDEPROPERTIES (
  "hbase.columns.mapping" =
  ":key,bools:bool_col,ints:tinyint_col,ints:smallint_col,ints:int_col,ints:  bigint_col,floats:float_col,floats:double_col,strings:date_string_col,  strings:string_col,strings:timestamp_col"
)
TBLPROPERTIES("hbase.table.name" = "hbasealltypessmall");

Note:在Hive中创建table之后,下次connectto impala时要执行INVALIDATE METADATA table_name语句,以便让impala知道这个新的table。

Without a String Row Key

本例中定义lookupkey column为INT类型,而不是STRING类型。

Note:尽管这样定义可以,但是Cloudera强烈建议使用STRING类型作为key列,因为这样lookup操作更快。

再次,执行CREATETABLE语句在Hive中,然后切换到Impala和impala-shell中执行查询:

$ hive
...
CREATE EXTERNAL TABLE hbasealltypessmall (
  id int,
  bool_col boolean,
  tinyint_col tinyint,
  smallint_col smallint,
  int_col int,
  bigint_col bigint,
  float_col float,
  double_col double,
  date_string_col string,
  string_col string,
  timestamp_col timestamp)
STORED BY ‘org.apache.hadoop.hive.hbase.HBaseStorageHandler‘
WITH SERDEPROPERTIES (
  "hbase.columns.mapping" =
  ":key,bools:bool_col,ints:tinyint_col,ints:smallint_col,ints:int_col,ints:bigint_col,floats   :float_col,floats:double_col,strings:date_string_col,strings:string_col,strings:timestamp_col"
)
TBLPROPERTIES("hbase.table.name" = "hbasealltypessmall");

Example Queries

一旦建立了与HBasetable的映射关系,你就可以执行查询了。例如:

# if the row key is mapped as a string col, range predicates are applied to the scan
select * from hbasestringids where id = ‘5‘;

# predicate on row key doesn‘t get transformed into scan parameter, because
# it‘s mapped as an int (but stored in ASCII and ordered lexicographically)
select * from hbasealltypessmall where id < 5;
时间: 2024-10-28 15:27:28

Cloudera Impala官方文档中文翻译-2(Using Impala to Query HBase Tables)的相关文章

Erlang epmd官方文档中文翻译

本文含epmd简介及官方文档之翻译,文档地址 http://erlang.org/doc/man/epmd.html翻译时的版本 R19.1 中英文水平都不咋地,不通顺处海涵,就酱. 简介 Erlang分布式系统中节点是通过节点名字互相连接的,节点名字为[email protected]_ADDRESS格式. epmd是分布式erlang中比较重要的模块.集群中每台机器都有一个epmd进程,这些进程端口号都用同一个端口号(默认4396端口).所有节点启动的时候都会连接到本机对应的epmd进程,它

Matlab最新的官方文档中文翻译

文章翻译的是Matlab最新的官方文档R2016b,可能后续如果我还有时间会继续翻译,希望能够帮到大家,翻译的不好请大家不要吐槽. Matlab官方文档地址:http://cn.mathworks.com/help/pdf_doc/matlab/getstart.pdf Desktop Basics  当您启动MATLAB时,桌面以其默认布局显示如下: 说明:请大家对照着英文原版看,我没有截图,因为实在太麻烦 桌面包括以下面板: ?当前文件夹 - 访问您的文件. ?命令窗口 - 在命令行中输入命

SparkSql官方文档中文翻译(java版本)

1 概述(Overview) 2 DataFrames 2.1 入口:SQLContext(Starting Point: SQLContext) 2.2 创建DataFrames(Creating DataFrames) 2.3 DataFrame操作(DataFrame Operations) 2.4 运行SQL查询程序(Running SQL Queries Programmatically) 2.5 DataFrames与RDDs的相互转换(Interoperating with RDD

[Documentation]UIImageView官方文档中文翻译

An image view object provides a view-based container for displaying either a single image or for animating a series of images. For animating the images, the UIImageView class provides controls to set the duration and frequency of the animation. You c

Bootstrap-datepicker3官方文档中文翻译---Markup/标记(原版翻译 http://bootstrap-datepicker.readthedocs.io/en/latest/index.html)

Markup/标记 下面是已经支持的标签的例子.这些标签本身不会提供DatePicker控件:你需要在标签上实例化Datepicker. input/输入框 最简单的例子: input获得焦点 (使用鼠标点击或者tab按钮跳入) 都会出现该控件. <input type="text" class="form-control" value="02-16-2012"> component/组件 在一个类名为.input-group的boo

Django 2.0官方文档中文 渣翻 总索引(个人学习,欢迎指正)

Django 2.0官方文档中文 渣翻 总索引(个人学习,欢迎指正) 置顶 2017年12月08日 11:19:11 阅读数:20277 官方原文: https://docs.djangoproject.com/en/2.0/ 当前翻译版本: v2.0 Python版本要求: v3.4+ (译者注:本人目前在南京一家互联网公司工作,职位是测试开发工程师.因为测试工作中经常会用到编码语言,如Python.Java.Shell等,所以几年前萌生了对Python语法的学习.Django作为Python

别开心太早,Python 官方文档的翻译差远了

近几天,很多公众号发布了 Python 官方文档的消息.然而,一个特别奇怪的现象就发生了,让人啼笑皆非. Python 文档的中文翻译工作一直是“默默无闻”,几个月前,我还吐槽过这件事<再聊聊Python中文社区的翻译>,当时我们的进度是 10.3%,远远落后于日本和法国,甚至落后于巴西! 这次所谓的中文版,当然是未完成翻译的残品.刚查了下,整体进度是 19.7%. 翻译进度不足20% 有的公众号在发布消息的时候,说明了这不是官宣.不是正式发布版,还指出了中文版的访问地址是隐藏入口.这都是忠于

uFrame 1.6 官方文档随意翻译(一)

前言: 建议直接看官方英文文档,下面都是一些简单的翻译. The Kernel The Kernel是uFrame的本质,负责处理加载场景,系统和服务. Subsystems 作为一个容器,组成许多Nodes. Subsystems允许你分离项目中的逻辑部分和可复用部分. System Loaders System Loaders常用语初始化信息. Node Elements 主要负责ViewModel(Unity中uFrame框架附带了Controller)部分 For example, Pl

Jinja2学习笔记暨官方文档的翻译

http://blog.csdn.net/lgg201/article/details/4647471 呵呵, 刚刚看完Python模板引擎Jinja2的文档, 感觉很好, 觉得动态语言真是很好.  模板引擎竟然可以做的如此灵活....真是不错.... 下面直接把看文档过程的笔记发布出来, 呵呵, 基本上就是翻译, 加了不多的一点自己的解释......希望可以帮到大家 补充: 1. 在模板中设置自定义变量: {% set variable_name = value %} 比如设置{% set u