在HBase中,只有一个单一的按照字典序排序的rowKey索引,当使用rowKey来进行数据查询的时候速度较快,但是如果不使用rowKey来查询 的话就会使用filter来对全表进行扫描,查询速度非常慢,我测试查询8万条简单数据用了268秒。而Phoenix提供了二级索引技术可以解决这种查询速度慢的问题。
Phoenix提供两种类型的索引技术:注重提升读性能的Global Indexing和注重提升写性能的Local Indexing。下面分别对这两种索引技术简单使用一下。
在HBase集群的master节点的hbase-site.xml中添加如下配置
<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> <property> <name>hbase.region.server.rpc.scheduler.factory.class</name> <value>org.apache.hadoop.hbase.ipc.PhoenixRpcSchedulerFactory</value> </property> <property> <name>hbase.rpc.controllerfactory.class</name> <value>org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory</value> </property>
在HBase集群的每个regionserver节点的hbase-site.xml中添加如下配置
<property> <name>hbase.coprocessor.regionserver.classes</name> <value>org.apache.hadoop.hbase.regionserver.LocalIndexMerger</value> </property>
可能会报错:
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=MY_INDEX (state=42Y88,code=1029)
于是,按照错误提示在HBase集群的每个regionserver节点的hbase-site.xml中再次添加如下配置
<property> <name>hbase.regionserver.wal.codec</name> <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value> </property>
重启hbase集群:
xyhadoop/hbase-1.0.1.1/bin/stop-hbase.sh xyhadoop/hbase-1.0.1.1/bin/start-hbase.sh
测试建立Phoenix Global index 和 Local index索引:
create table company(id varchar primary key, name varchar, address varchar); create index global_index on company(name); create local index local_index on company(name); !indexes company
看到类似如下信息,说明成功:
Connected to: Phoenix (version 4.7) Driver: PhoenixEmbeddedDriver (version 4.7) Autocommit status: true Transaction isolation: TRANSACTION_READ_COMMITTED Building list of tables and columns for tab-completion (set fastconnect to true to skip)... 115/115 (100%) Done Done sqlline version 1.1.8 0: jdbc:phoenix:localhost> !indexes company +------------+--------------+-------------+-------------+------------------+-------------+-------+-------------------+----------+ | TABLE_CAT | TABLE_SCHEM | TABLE_NAME | NON_UNIQUE | INDEX_QUALIFIER | INDEX_NAME | TYPE | ORDINAL_POSITION | COLUMN_N | +------------+--------------+-------------+-------------+------------------+-------------+-------+-------------------+----------+ | | | COMPANY | true | | MY_INDEX | 3 | 1 | _INDEX_I | | | | COMPANY | true | | MY_INDEX | 3 | 2 | 0:NAME | | | | COMPANY | true | | MY_INDEX | 3 | 3 | :ID | +------------+--------------+-------------+-------------+------------------+-------------+-------+-------------------+----------+ 0: jdbc:phoenix:localhost>
测试性能对比
导入了250万数据。采用global index时写入速度慢,读取速度在0.1秒左右;采用local index时,写入速度快,读取速度在4秒左右。可见global index和local index在读取的时候有40倍的差距,在写入的时候差距没这么大,都用了很久。
参考链接:
http://www.aboutyun.com/forum.php?mod=viewthread&tid=15570
http://phoenix.apache.org/secondary_indexing.html
http://www.icaijing.org/hot/article4940159