Phoenix查询测试经验总结

1. 背景

适当的索引能够让极大提升查询速度,因此在Phoenix查询的测试用例中包括了对有索引跟无索引的查询性能的比较。测试过程中遇到一些问题,在此记录下来。

2. 问题及解决

2.1. 创建索引时报错,报错如下:

//创建索引语句:
0: jdbc:phoenix:localhost> CREATE INDEX ind_1 ON TESTINPUT(ff1);

//报错:
Error: ERROR 1029 (42Y88): Mutable secondary indexes must have the hbase.regionserver.wal.codec property set to org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec in the hbase-sites.xml of every region server tableName=IND_1 (state=42Y88,code=1029)
java.sql.SQLException: ERROR 1029 (42Y88): Mutable secondary indexes must have the hbase.regionserver.wal.codec property set to org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec in the hbase-sites.xml of every region server tableName=IND_1
    at org.apache.phoenix.exception.SQLExceptionCode$Factory$1.newException(SQLExceptionCode.java:396)
    at org.apache.phoenix.exception.SQLExceptionInfo.buildException(SQLExceptionInfo.java:145)
    at org.apache.phoenix.schema.MetaDataClient.createIndex(MetaDataClient.java:1162)
    at org.apache.phoenix.compile.CreateIndexCompiler$1.execute(CreateIndexCompiler.java:95)
    at org.apache.phoenix.jdbc.PhoenixStatement$2.call(PhoenixStatement.java:322)
    at org.apache.phoenix.jdbc.PhoenixStatement$2.call(PhoenixStatement.java:314)
    at org.apache.phoenix.call.CallRunner.run(CallRunner.java:53)
    at org.apache.phoenix.jdbc.PhoenixStatement.executeMutation(PhoenixStatement.java:312)
    at org.apache.phoenix.jdbc.PhoenixStatement.execute(PhoenixStatement.java:1435)
    at sqlline.Commands.execute(Commands.java:822)
    at sqlline.Commands.sql(Commands.java:732)
    at sqlline.SqlLine.dispatch(SqlLine.java:808)
    at sqlline.SqlLine.begin(SqlLine.java:681)
    at sqlline.SqlLine.start(SqlLine.java:398)
    at sqlline.SqlLine.main(SqlLine.java:292)
  • 原因:Phoenix支持两种索引:可变索引跟不可变索引。在可变表上建的索引是可变索引,在不可变表上建的索引是不可变索引。可变索引是指插入或删除数据的时候会同时更新索引;不可变索引适用于只写入一次不再更改的表,索引只建立一次,再插入数据不会更新索引。上面使用的语句是创建可变索引,需要在hbase-site.xml中进行相关配置使其支持可变索引(不可变索引无需另外配置,默认支持)。

  • 解决:对HMaster和HRegionserver节点分别增加配置,然后重启HBase集群

    • HMaster
    <property>
      <name>hbase.regionserver.wal.codec</name>
      <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
    </property>
    <property>
     <name>hbase.master.loadbalancer.class</name>
     <value>org.apache.phoenix.hbase.index.balancer.IndexLoadBalancer</value>
    </property>
    <property>
     <name>hbase.coprocessor.master.classes</name>
     <value>org.apache.phoenix.hbase.index.master.IndexMasterObserver</value>
    

</property>

 - HRegionserver

<property>
<name>hbase.regionserver.wal.codec</name>
<value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
</property>
<property>
<name>hbase.region.server.rpc.scheduler.factory.class</name>
<value>org.apache.hadoop.hbase.ipc.PhoenixRpcSchedulerFactory</value>
<description>Factory to create the Phoenix RPC Scheduler that usesseparate queues for index and metadata updates</description>
</property>
<property>
<name>hbase.rpc.controllerfactory.class</name>
<value>org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory</value>
<description>Factory to create the Phoenix RPCScheduler that uses separate queues for index and metadataupdates</description>
</property>
<property>
<name>hbase.coprocessor.regionserver.classes</name>
<value>org.apache.hadoop.hbase.regionserver.LocalIndexMerger</value>
</property>


### 2.2. 对10亿数据查询时,报错如下:

16/11/29 10:33:50 WARN client.ScannerCallable: Ignore, probably already closed
org.apache.hadoop.hbase.regionserver.LeaseException: org.apache.hadoop.hbase.regionserver.LeaseException: lease '1132' does not exist
at org.apache.hadoop.hbase.regionserver.Leases.removeLease(Leases.java:221)
at org.apache.hadoop.hbase.regionserver.Leases.cancelLease(Leases.java:206)

...

org.apache.phoenix.exception.PhoenixIOException: org.apache.phoenix.exception.PhoenixIOException: Failed after attempts=36, exceptions:
Tue Nov 29 10:33:50 CST 2016, null, java.net.SocketTimeoutException: callTimeout=60000, callDuration=60321: row '��s,d' on table 'TEST11' at region=TEST11,\x11\x00\x00\x00\x00\x00\x00\x00\x00,1479985615575.c3adb68acea8d88d223bffd3acc16c2e., hostname=node-20-105,60020,1480385981798, seqNum=1244662

...

Caused by: org.apache.hadoop.hbase.ipc.CallTimeoutException: Call id=18173, waitTime=60001, operationTimeout=60000 expired.
at org.apache.hadoop.hbase.ipc.Call.checkAndSetTimeout(Call.java:70)
at org.apache.hadoop.hbase.ipc.RpcClientImpl.call(RpcClientImpl.java:1197)
...


- 原因:

某些查询需要很长时间才能返回结果,被HBase的超时机制杀掉了。

- 思路:

增大超时时间,在hbase-site.xml里增加了如下配置:

<property>
<name>hbase.rpc.timeout</name>
<value>600000</value>
</property>

<property>
<name>hbase.client.operation.timeout</name>
<value>600000</value>
</property>

<property>
<name>hbase.client.scanner.timeout.period</name>
<value>600000</value>
</property>

<property>
<name>hbase.regionserver.lease.period</name>
<value>600000</value>
</property>

<property>
<name>phoenix.query.timeoutMs</name>
<value>600000</value>
</property>

<property>
<name>phoenix.query.keepAliveMs</name>
<value>600000</value>
</property>

<property>
<name>hbase.client.ipc.pool.type</name>
<value>RoundRobinPool</value>
</property>
<property>
<name>hbase.client.ipc.pool.size</name>
<value>10</value>
</property>


最终虽然配置生效了,但是还是报同样的错。已经将网上说的可能的配置项都配了还是无法解决超时问题。等增加了机器,查询时间变短,10亿数据的查询应该就没有超时问题了。



## 3. 特性

- 不可变索引默认支持,不需要另外配置;可变索引需要如上添加配置才能支持
- 创建不可变表:

CREATE TABLE TABLENAME (pk long PRIMARY KEY,col1 int) IMMUTABLE_ROWS=true;

- 创建索引有以下几种方式:

CREATE INDEX ind_name ON TABLENAME(COLUMN1);
CREATE INDEX ind_name ON TABLENAME(COLUMN1,COLUMN2);
CREATE INDEX ind_name ON TABLENAME(COLUMN1) INCLUDE(COLUMN2);

- 执行查询的时候,Phoenix查询优化器将选择合适的索引。可以使用explain plan进行查看

0: jdbc:phoenix:localhost> explain select ff3,if1 from testinput where ff3 >= 0.7 and ff3 < 0.9 order by if1;
+------------------------------------------+
| PLAN |
+------------------------------------------+
| CLIENT 1-CHUNK PARALLEL 1-WAY RANGE SCAN OVER IND_4 [0.7] - [0.9] |
| SERVER SORTED BY ["IF1"] |
| CLIENT MERGE SORT |
+------------------------------------------+

- 除非所有查询使用的列被索引或者覆盖列,否则二级索引不会被使用
- 建索引的时候不要包括primary key,否则索引不会被使用;可以单独对primary key建索引
- where条件里有primary key的时候会使用Range Scan,因为表本来就是按照primary key的顺序排列的
- primary key在插入时是自动排序的,插入完成后primary key保持有序(如果该表只有一个分区,则全局有序;如果有多个分区,则在每个分区内部有序,并非全局有序)
- 对某几个(1个或多个)列建索引,则会生成一张索引表,该表由创建索引的这几个列组成,并在最后一列添加primary key列。也就是说索引表也是一张表,只不过该表列数比原表少。
- 索引表的第一列是有序的
- upsert into一个跟之前一样的primary key,会将之前那个primary key的记录替换成新的。
- phoenix虽然不支持update语句,但是可以用upsert into tablename(id,columnname) values(id,newvalue)来实现同样的功能。
- local index 对应的索引表的分区跟表的分区在同一个region server上(索引表分区数必须跟表分区数一样)
- global index 对应的索引表的分区跟表的分区不一定在同一个region server上(索引表分区数必须跟表分区数一样)
- 对一张表建了多个local index,对于HBase来讲,其实只存了一张索引表。但是global index则不同。

## 4. 参考资料
- https://github.com/forcedotcom/phoenix/wiki/Secondary-Indexing
- http://phoenix.apache.org/language/index.html#create_index
- http://blog.csdn.net/jiangshouzhuang/article/details/52387718


![FullStackPlan](http://upload-images.jianshu.io/upload_images/1752522-2e4b0e5141927479.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
欢迎关注公众号: FullStackPlan 获取更多干货哦~
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容