phoenix全局索引和本地索引测试

news/2024/12/14 16:47:14/

##1.测试表说明
原hbase表是只有1个列族,算上rowkey一共6个字段的hbase表。
一共37个regions,数据量一共3亿6千4百万
hbase中表描述

数据样例

数据量

##2.建立索引
hbase的二级索引在phoenix中建立。
建索引的语句如下,建好索引之后,有数据的变更索引数据和原始数据会实时的同步更新

create index car_index_index1 on car(hphm)
1
因为这张表是已经存在的大表,而且数据量也不少,直接用上面的语句建立索引时间会很长,所以这里用批量建立索引的方式

#首先在phoenix中建立索引表信息
create index car_index_datehphm on "car"("f1"."date","f1"."hphm") include ("f1"."coorid","f1"."cx","f1"."ys") async;
#这里的建立索引语句加了async,异步建立索引。另外f1是hbase中原始的列族名,这张表是原始hbase表转过来的,为什么这么写就不解释了,"f1"."date"就代表一个字段。include是什么后面再解释

#下面启动批量建立索引的mr任务
${HBASE_HOME}/bin/hbase org.apache.phoenix.mapreduce.index.IndexTool \
--data-table "car" --index-table CAR_INDEX_DATEHPHM \
--output-path ASYNC_IDX_HFILES
1
2
3
4
5
6
7
8
3亿6千万的数据,批量建立索引时间为1小时10分钟
##3.索引测试
上面的建立的索引是两个字段的复合索引。可以分别对两个字段进行单独或者一起的条件过滤查询

##车牌查询
0: jdbc:phoenix:localhost:2181:/hbase> select * from "car" where "f1"."hphm" like '苏E3G%' limit 10;
+-------------------------+---------+------+-----------------+----------+-----+
|           ID            | coorid  |  cx  |      date       |   hphm   | ys  |
+-------------------------+---------+------+-----------------+----------+-----+
| 20170101005027_苏E3G2SA  | t    | 奔驰   | 20170101005027  | 苏E3G2SA  | 黄   |
| 20170101011949_苏E3GS62  | �    | 奥迪   | 20170101011949  | 苏E3GS62  | 银   |
| 20170101014325_苏E3G7S8  | �    | 丰田   | 20170101014325  | 苏E3G7S8  | 银   |
| 20170101022906_苏E3GPQB  | D    | 保时捷  | 20170101022906  | 苏E3GPQB  | 黄   |
| 20170101030015_苏E3G2SA  |     | 奔驰   | 20170101030015  | 苏E3G2SA  | 黄   |
| 20170101030157_苏E3G2SA  | �    | 奔驰   | 20170101030157  | 苏E3G2SA  | 黄   |
| 20170101033901_苏E3G117  | �    | 奥迪   | 20170101033901  | 苏E3G117  | 蓝   |
| 20170101040047_苏E3G7S8  |     | 丰田   | 20170101040047  | 苏E3G7S8  | 银   |
| 20170101040114_苏E3G8CW  | *    | 宝马   | 20170101040114  | 苏E3G8CW  | 黄   |
| 20170101041608_苏E3G6GH  | $    | 奔驰   | 20170101041608  | 苏E3G6GH  | 红   |
+-------------------------+---------+------+-----------------+----------+-----+
10 rows selected (1.767 seconds)
用时1.767秒,分析原因为车牌种类比较少,筛选出的速度会稍微慢点,如果建立二级索引第一个字段用车牌,速度应该会快很多。

## 日期查询
0: jdbc:phoenix:localhost:2181:/hbase> select * from "car" where "f1"."date">='20170110' and "f1"."date"<='20170210'  limit 10;
+-------------------------+---------+------+-----------------+----------+-----+
|           ID            | coorid  |  cx  |      date       |   hphm   | ys  |
+-------------------------+---------+------+-----------------+----------+-----+
| 20170110000000_京AM7BPF  | t    | 丰田   | 20170110000000  | 京AM7BPF  | 白   |
| 20170110000000_京C4SS4G  | �    | 大众   | 20170110000000  | 京C4SS4G  | 红   |
| 20170110000000_新D5AGEG  | �    | 宝马   | 20170110000000  | 新D5AGEG  | 黄   |
| 20170110000000_新DFMM96  |  
    | 奔驰   | 20170110000000  | 新DFMM96  | 黄   |
| 20170110000000_沪HB1R23  | �    | 保时捷  | 20170110000000  | 沪HB1R23  | 银   |
| 20170110000000_沪IMARPP  | �    | 丰田   | 20170110000000  | 沪IMARPP  | 白   |
| 20170110000000_沪KR5QA2  | �    | 日产   | 20170110000000  | 沪KR5QA2  | 黑   |
| 20170110000000_浙KQDWM9  | �    | 日产   | 20170110000000  | 浙KQDWM9  | 黑   |
| 20170110000000_湘BMPWCM  | �    | 奔驰   | 20170110000000  | 湘BMPWCM  | 银   |
| 20170110000000_湘HHS4E9  | �    | 日产   | 20170110000000  | 湘HHS4E9  | 红   |
+-------------------------+---------+------+-----------------+----------+-----+
10 rows selected (0.049 seconds)
用时为49毫秒。

##日期车牌查询
0: jdbc:phoenix:localhost:2181:/hbase> select * from "car" where "f1"."date">='20170110' and "f1"."date"<='20170210' and "f1"."hphm" like '.E3G%' limit 10;
+-------------------------+---------+------+-----------------+----------+-----+
|           ID            | coorid  |  cx  |      date       |   hphm   | ys  |
+-------------------------+---------+------+-----------------+----------+-----+
| 20170110005537_苏E3GS62  | �    | 奥迪   | 20170110005537  | 苏E3GS62  | 银   |
| 20170110010344_苏E3G21Q  | K    | 讴歌   | 20170110010344  | 苏E3G21Q  | 黄   |
| 20170110013131_苏E3G21Q  | �    | 讴歌   | 20170110013131  | 苏E3G21Q  | 黄   |
| 20170110013318_苏E3G21Q  | �    | 讴歌   | 20170110013318  | 苏E3G21Q  | 黄   |
| 20170110013452_苏E3GQCF  | C    | 沃尔沃  | 20170110013452  | 苏E3GQCF  | 白   |
| 20170110034239_苏E3G7S8  | �    | 丰田   | 20170110034239  | 苏E3G7S8  | 银   |
| 20170110041044_苏E3G2SA  | 6    | 奔驰   | 20170110041044  | 苏E3G2SA  | 黄   |
| 20170110041829_苏E3GEM2  | m    | 讴歌   | 20170110041829  | 苏E3GEM2  | 蓝   |
| 20170110045503_苏E3G2SA  |     | 奔驰   | 20170110045503  | 苏E3G2SA  | 黄   |
| 20170110050616_苏E3GS62  | O    | 奥迪   | 20170110050616  | 苏E3GS62  | 银   |
+-------------------------+---------+------+-----------------+----------+-----+
10 rows selected (0.706 seconds)
用时700多毫秒
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
4.索引类型
phoenix的索引大致分为两类global index和local index,好像和星环有点类似,其实这是hbase二级索引解决方案里面广为人知的两种方案,侧重点不同,使用场景也不一样。

global index,global是默认的索引格式。官方文档翻译过来的:Global indexing适用于多读少写的业务场景。使用Global indexing的话在写数据的时候会消耗大量开销,因为所有对数据表的更新操作(DELETE, UPSERT VALUES and UPSERT SELECT),会引起索引表的更新,而索引表是分布在不同的数据节点上的,跨节点的数据传输带来了较大的性能消耗。在读数据的时候Phoenix会选择索引表来降低查询消耗的时间。在默认情况下如果想查询的字段不是索引字段的话索引表不会被使用,也就是说不会带来查询速度的提升。
Local index,适用于写操作频繁的场景。与Global index一样,Phoenix会自动判定在进行查询的时候是否使用索引。使用Local indexing时,索引数据和数据表的数据是存放在相同的服务器中的避免了在写操作的时候往不同服务器的索引表中写索引带来的额外开销。使用Local indexing的时候即使查询的字段不是索引字段索引表也会被使用,这会带来查询速度的提升,这点跟Global indexing不同。一个数据表的所有索引数据都存储在一个单一的独立的可共享的表中。
官方文档上写的太书面了,下面用几个例子就能明白这两种索引格式是怎么设计以及怎样运行原理了。

4.1 global index 测试
上面的测试例子用的是global index,后面的例子为了快,就建立一些测试表。

##建立表
create table test_global(id varchar primary key,f1 varchar,f2 varchar);
##建立global index
create index test_global_index on test_global(f1) include(f2);
##插入两条数据
upsert into test_global values('1','2','3');
upsert into test_global values('4','5','6');
##查看索引表数据(注意这里查的是索引表数据,不是原始表。创建global index会生成一个索引表)
select * from test_global_index;
+-------+------+-------+
| 0:F1  | :ID  | 0:F2  |
+-------+------+-------+
| 2     | 1    | 3     |
| 5     | 4    | 6     |
+-------+------+-------+
2 rows selected (0.037 seconds)
##查看hbase表上面的数据(注意这里查的是索引表在hbase中的数据)
scan 'TEST_GLOBAL_INDEX'
hbase(main):002:0> scan 'TEST_GLOBAL_INDEX'
ROW                                                       COLUMN+CELL                                                                                                                                                           
 2\x001                                                   column=0:\x00\x00\x00\x00, timestamp=1501489856443, value=\x00\x00\x00\x00                                                                                            
 2\x001                                                   column=0:\x80\x0B, timestamp=1501489856443, value=3                                                                                                                   
 5\x004                                                   column=0:\x00\x00\x00\x00, timestamp=1501489860185, value=\x00\x00\x00\x00                                                                                            
 5\x004                                                   column=0:\x80\x0B, timestamp=1501489860185, value=6                                                                                                                   
2 row(s) in 0.0620 seconds
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
global index
1.以上可以看出global index的设计方式,会单独写一张索引表,列族为include字段,rowkey的设计方位是:
二级索引字段1+"\x00"+二级索引字段2(复合索引)…+"\x00"+原表rowkey
2.查询的时候,会直接定位到索引表,通过rowkey查到位置,然后从索引表中带出数据
3.因为建立索引的时候还要多写一份include字段,读的时候直接从索引表定位并读出信息。所以这种表的应用场景定位是写的慢,读得快

4.2 local index 测试
##建立表
create table test_local(id varchar primary key,f1 varchar,f2 varchar);
##建立local index
create local index test_local_index on test_local(f1);
##插入两条数据
upsert into test_local values('1','2','3');
upsert into test_local values('4','5','6');
##注意:local index 并不会创建新的表,而是在原来的表里面写入索引数据
##查看hbase表中数据
hbase(main):014:0> scan 'TEST_LOCAL'
ROW                                                       COLUMN+CELL                                                                                                                                                           
 \x00\x002\x001                                           column=L#0:\x00\x00\x00\x00, timestamp=1501491310774, value=\x00\x00\x00\x00                                                                                          
 \x00\x005\x004                                           column=L#0:\x00\x00\x00\x00, timestamp=1501491315118, value=\x00\x00\x00\x00                                                                                          
 1                                                        column=0:\x00\x00\x00\x00, timestamp=1501491310774, value=x                                                                                                           
 1                                                        column=0:\x80\x0B, timestamp=1501491310774, value=2                                                                                                                   
 1                                                        column=0:\x80\x0C, timestamp=1501491310774, value=3                                                                                                                   
 4                                                        column=0:\x00\x00\x00\x00, timestamp=1501491315118, value=x                                                                                                           
 4                                                        column=0:\x80\x0B, timestamp=1501491315118, value=5                                                                                                                   
 4                                                        column=0:\x80\x0C, timestamp=1501491315118, value=6                                                                                                                   
4 row(s) in 0.0250 seconds
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
local index
1.以上可以看出local index的设计方式,索引数据直接写在原表rowkey中,列族不写任何实际信息,local index的rowkey的设计方位是:
原数据region的start key+"\x00"+二级索引字段1+"\x00"+二级索引字段2(复合索引)…+"\x00"+原rowkey
第一条信息"原数据region的start key",这样做的目的是保证索引数据和原数据在一个region上,定位到二级索引后根据原rowkey就可以很快在本region上获取到其它信息,减少网络开销和检索成本。
2.查询的时候,会在不同的region里面分别对二级索引字段定位,查到原rowkey后在本region上获取到其它信息
3.因为这种索引设计方式只写索引数据,省了不少空间的占用,根据索引信息拿到原rowkey后再根据rowkey到原数据里面获取其它信息。所以这种表的应用场景定位是写的快,读得慢

4.3 local index和global index比较
1.索引数据

global index单独把索引数据存到一张表里,保证了原始数据的安全,侵入性小
local index把数据写到原始数据里面,侵入性强,原表的数据量=原始数据+索引数据,使原始数据更大
2.性能方面

global index要多写出来一份数据,写的压力就大一点,但读的速度就非常快
local index只用写一份索引数据,节省不少空间,但多了一步通过rowkey查找数据,写的速度非常快,读的速度就没有直接取自己的列族数据快。
4.4其它
phoenix大的方面分为这两种索引,细的方面可以分为4种。phoenix还另外加了一种配置,根据索引是否可变,意思就是为了减少写入的压力,索引表只建立一次不会更改。

5.总结
用phoenix只是用hbase自身实现了hbase自己的二级索引,用hbase自己rowkey查询的特点来设计索引数据的rowkey,性能方面完全要靠一次检索索引数据的数据量大小了,所以具体业务具体分析。


http://www.ppmy.cn/news/748408.html

相关文章

怎么制作真人qq秀_NBA赛事最震撼的开场秀

2020年10月12日&#xff0c;NBA总决赛G6&#xff0c;全场比赛落下帷幕&#xff0c;湖人106-93赢下热火&#xff0c;大比分4-2拿下总决赛&#xff01; 金戈铁马&#xff0c;气吞万里如虎&#xff0c;是时候喊出那五个字了&#xff1a;湖人总冠军&#xff01;黄沙百战穿金甲&…

集合类

集合类 1、前言2、集合框架3、Collection接口4、区分Collection和Collections5、List集合5.1、List接口5.2、ArrayList实现类5.3、LinkedList实现类5.4、Vector实现类 6、Set集合6.1、Set接口6.2、HashSet实现类6.3、TreeSet实现类6.4、LinkedHashSet实现类 7、Map集合7.1、Map…

奥迪宝马爆奔驰?

毫无疑问&#xff0c;OLED&#xff08;Organic Light-Emitting Diode&#xff09;有机发光二极管&#xff0c;目前已经被公认为下一代革命显示技术&#xff0c;它拥有LCD技术所无法比拟的的物理优势。由于其自发光特性、色彩真实、零延迟、无限对比度、结构简单、柔性显示等特性…

Vue2.0-3.0 入门到实战 - 初始及插件安装

1 创建view实例,初始化渲染 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><div id"app">{{ msg }} </div><script type&…

list容器语法

文章目录 listlist基本概念list的优点&#xff1a;list的缺点&#xff1a;重要性质 list 的使用方法list构造函数list 赋值和交换list 长度/大小操作list 插入元素和删除元素访问list 反转和排序sort链表排序案例forward_list&#xff08;C11&#xff09;forward_list 的使用方…

2008游戏服务器系统下,梦幻西游永恒的传奇 2008服务器一览 17173.com网络游戏:《梦幻西游》专区...

2008顾名思义&#xff0c;是趁着北京奥运会2008年8月8日开区的3年区。这也是梦幻西游的一个传奇,一个开区3年,永远爆满,天天爆红.在这里有着梦幻西游最高的物价,有着数不尽的装备和召唤兽,在2008服务器里,只要你有钱&#xff0c;“一切皆有可能”&#xff0c;下面就是2008服务器…

C++罕见的纯虚函数调用异常(_purecall abort)

现象 笔者最近遇到了一个诡异的BUG&#xff0c;析构函数执行期间crash&#xff08;VS2022调试器下表现为abort&#xff09;&#xff0c;调用堆栈最后一级是调用虚函数&#xff0c;所有指针变量正常。 更深层的原因和特征隐藏在虚函数表中。abort发生时&#xff0c;虚函数表中…

从《梦幻西游》看网游玩家分类

前言《梦幻西游》&#xff08;以下简称梦幻&#xff09;&#xff0c;是目前国内最成功的大型多人在线网络游戏了&#xff0c;作为一款成功的作品&#xff0c;导致其成功的条件是很多的&#xff0c;本文也不想对方方面面的成功条件做详细的汇总和分析&#xff0c;毕竟那是记者和…