应用的软件版本, 留神软件版本很重要, 很重要
apache-phoenix-5.0.0-HBase-2.0-bin.tar.gz
hadoop-2.9.2.tar.gz
hbase-2.0.5-bin.tar.gz
Hbase 中通过非 rowkey 查问数据查问速度会很慢
为什么须要二级索引
在 Hbase 中要想准确查问一条数据所以必须应用 rowkey, 如果不通过 rowkey 查问数据, 就必须逐行逐列的比拟 (即全表扫描), 效率很低. 理论业务中须要通过多个维度疾速查问数据. 例如查问用户的时候可能须要通过用户名, 姓名, 邮箱, 手机号查问, 然而把这种多维度的查问字段都放到 rowkey 中, 显然是不可能的 (灵活性不高,roekey 的长度也是有限度的), 因而二级索引的利用场景就应运而生,Phoenix 曾经提供了对 HBase 的二级索引反对反对。
二级索引分类
- Global indexing 全局索引, 实用于读多写少的场景
应用 Global indexing 在写数据的时候开销很大,因为所有对数据表的更新操作(DELETE, UPSERT VALUES and UPSERT SELECT),都会引起索引表的更新,而索引表是散布在不同的数据节点上的,跨节点的数据传输带来了较大的性能耗费。在读数据的时候 Phoenix 会抉择索引表来升高查问耗费的工夫。在默认状况下如果想查问的字段不是索引字段的话索引表不会被应用,也就是说不会带来查问速度的晋升。
- Local indexing 本地索引, 实用于写多的场景
与 Global indexing 一样,Phoenix 会主动断定在进行查问的时候是否应用索引。应用 Local indexing 时,索引数据和数据表的数据寄存在雷同的服务器中,这样防止了在写操作的时候往不同服务器的索引表中写索引带来的额定开销。应用 Local indexing 的时候即便查问的字段不是索引字段索引表也会被应用,这会带来查问速度的晋升,这点跟 Global indexing 不同。对于 Local Indexing,一个数据表的所有索引数据都存储在一个繁多的独立的可共享的表中。
- immutable indexing 不可变索引, 实用于数据只减少不更新, 而且按工夫程序先后循序存储.
不可变索引的存储形式是 write one,append only。当在 Phoenix 应用 create table 语句时指定 IMMUTABLE_ROWS = true 示意该表上创立的索引将被设置为不可变索引。Phoenix 默认状况下如果在 create table 时不指定 IMMUTABLE_ROW = true 时,示意该表为 mutable。不可变索引分为 Global immutable index 和 Local immutable index 两种。
- mutable indexing 可变索引, 实用于数据有增删的的场景
Phoenix 默认状况下创立的索引是可变索引, 除非指定 IMMUTABLE_ROW=true
开启 Hbase 对二级索引的反对
vim vim hbase-2.3.1/conf/hbase-site.xml
<property>
<name>hbase.regionserver.wal.codec</name>
<value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
</property>
user 表创立索引
>create table user1(id varchar(10) primary key,
f.name varchar(100),
f.pass varchar(100),
f.grp varchar(10),
f.type varchar(5),
f.types varchar(2),
f.code varchar(10),
f.uname varchar(20),
f.email varchar(20),
f.factory varchar(10),
f.depart varchar(10),
f.region varchar(10)
)column_encoded_bytes=0;
> create index user_name on user(name);
// 查问索引
> !indexes user
user 表删除索引
> drop index user_name on user;
实战
- create index user_name on user; // 默认可变索引
// 创立索引
> create index user_name on user;
//* 这样查问是不会走索引的
> select * from user where name='rumenz';
> explain select * from user where name='rumenz';
//FULL SCAN OVER USER SERVER FILTER BY F.NAME =
// 查问字段和索引字段保持一致就能够用到索引
> select name from user where name='rumenz';
> explain select name from user where name='rumenz';
//CLIENT 1-CHUNK PARALLEL 1-WAY ROUND ROBIN RANGE SCAN OVER USER_NAME SERVER FILTER BY FIRST KEY ONLY
- create local index user_name on user1(name); // 创立本地索引
//* 这样查问就会走索引
> select * from user where name='rumenz';
> explain select * from user where name='rumenz';
// 应用到了索引
//ROUND ROBIN RANGE SCAN OVER USER1
- converted index // 相当于一个联结索引
> create index user_name1 on user1(name) include(pass);
// 只有当 name,pass 在查问字段呈现时, 才会用到索引: 比方
//select name from user1 where name=''或者 pass='';
//select pass from user1 where name=''或者 pass='';
//select name,pass from user1 where name=''或者 pass='';
- 在 select 和 column_name 之间加上
/*+ Index(< 表名 > <index 名 >)*/
,通过这种形式强制应用索引。
> select /*+ index(user1,USER_NAME) */ pass from user1 where name='xxx';
//1. 如果 pass 是索引那么从索引表查问.
//2. 如果 pass 不是索引, 那么会进行全表扫描会很慢.
重建索引
> alter index USER_NAME on user1 rebuild;
索引性能调优
1. index.builder.threads.max
创立索引时,应用的最大线程数。默认值: 10。2. index.builder.threads.keepalivetime
创立索引的创立线程池中线程的存活工夫,单位:秒。默认值: 60
3. index.writer.threads.max
写索引表数据的写线程池的最大线程数。更新索引表能够用的最大线程数,也就是同时能够更新多少张索引表,数量最好和索引表的数量统一。默认值: 10
4. index.writer.threads.keepalivetime
索引写线程池中,线程的存活工夫,单位:秒。默认值:60
5. hbase.htable.threads.max
每一张索引表可用于写的线程数。默认值: 2,147,483,647
6. hbase.htable.threads.keepalivetime
索引表线程池中线程的存活工夫,单位:秒。默认值: 60
7. index.tablefactory.cache.size
容许缓存的索引表的数量。减少此值,能够在写索引表时不必每次都去反复的创立 htable,这个值越大,内存耗费越多。默认值: 10
8. org.apache.phoenix.regionserver.index.handler.count
解决全局索引写申请时,能够应用的线程数。默认值: 30