Phoenix的二級索引


前言

  在Hbase中,只有一個單一的按照字典序排序的rowKey索引,當使用rowKey來進行數據查詢的時候速度較快,但是如果不使用rowKey來查詢的話就會使用filter來對全表進行掃描,很大程度上降低了檢索性能。而Phoenix提供了二級索引技術來應對這種使用rowKey之外的條件進行檢索的場景。

  Phoenix支持兩種類型的索引技術:Global Indexing和Local Indexing,這兩種索引技術分別適用於不同的業務場景(主要是偏重於讀還是偏重於寫)


Global Indexing

  Global indexing適用於多讀少寫的業務場景。使用Global indexing的話在寫數據的時候會消耗大量開銷,因為所有對數據表的更新操作(DELETE, UPSERT VALUES and UPSERT SELECT),會引起索引表的更新,而索引表是分布在不同的數據節點上的,跨節點的數據傳輸帶來了較大的性能消耗。在讀數據的時候Phoenix會選擇索引表來降低查詢消耗的時間。在默認情況下如果想查詢的字段不是索引字段的話索引表不會被使用,也就是說不會帶來查詢速度的提升。

配置hbase-site.xml

  使用Global Indexing的話需要配置hbase-site.xml,在HBase集群的每個regionserver節點的hbase-site.xml中加入如下配置並重啟HBase集群。

  

  
  
  
          
  1. <property>
  2. <name>hbase.regionserver.wal.codec</name>
  3. <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
  4. </property>

創建索引


創建lastname的索引 
   
   
   
           
  1. create index my_name on usertable (lastname);

Linux shell

 
Squirrel SQL
 
2個索引字段NAME和ID的值被合並為索引表MY_INDEX的rowKey,\x000是十六進制表示,轉換為字符串是空格。

正常的select ... where ... 是不會用到索引表的
要想用到索引表,必須查詢出的字段也是索引字段

三種方式使Phoenix使用二級索引

強制使用索引表

   
   
   
           
  1. select /*+ INDEX(USERTABLE MY_NAME) */ * from my_name where lastname = 'perl';
這樣的查詢語句會導致二次檢索數據表,第一次檢索是去索引表中查找符合name為 perl 的數據,
這時候發現 firstname 字段並不在索引字段中,會去usertable表中第二次掃描,
因此只有當用戶明確知道符合檢索條件的數據較少的時候才適合使用,否則會造成全表掃描,對性能影響較大。

創建covered index

  
  
  
          
  1. drop index my_name on usertable;
  2. create index my_name on USERTABLE(LASTNAME) include (FIRSTNAME)

使用這種方式創建的所有會導致address字段的值被拷貝到索引中,缺點就是會導致索引表大小有一定的增加。

 

使用Local Indexing創建索引

與Global Indexing不同,當使用Local Indexing的時候即使查詢的所有字段都不在索引字段中時也會用到索引進行查詢(這是由Local Indexing自動完成的)。

Local indexing適用於寫操作頻繁的場景。

與Global indexing一樣,Phoenix會自動判定在進行查詢的時候是否使用索引。使用Local indexing時,索引數據和數據表的數據是存放在相同的服務器中的避免了在寫操作的時候往不同服務器的索引表中寫索引帶來的額外開銷。

使用Local indexing的時候即使查詢的字段不是索引字段索引表也會被使用,這會帶來查詢速度的提升,這點跟Global indexing不同。

一個數據表的所有索引數據都存儲在一個單一的獨立的可共享的表中。在讀取數據的時候,標紅的那句話不會翻譯大意就是在讀數據的時候因為存儲數據的region的位置無法預測導致性能有一定損耗。

配置hbase-site.xml

每個regionServer的Hbase都要配置
    
    
    
            
  1. <property>
  2. <name>hbase.master.loadbalancer.class</name>
  3. <value>org.apache.phoenix.hbase.index.balancer.IndexLoadBalancer</value>
  4. </property>
  5. <property>
  6. <name>hbase.coprocessor.master.classes</name>
  7. <value>org.apache.phoenix.hbase.index.master.IndexMasterObserver</value>
  8. </property>

高能預警:
    如果使用的是Phoenix 4.3+的版本的話還需要在HBase集群的每個regionserver節點的hbase-site.xml中添加如下配置並重啟HBase集群。
    
    
    
            
  1. <property>
  2. <name>hbase.coprocessor.regionserver.classes</name>
  3. <value>org.apache.hadoop.hbase.regionserver.LocalIndexMerger</value>
  4. </property>

創建local index

    
    
    
            
  1. create local index local_index on usertable(lastname);

 
 3個索引字段_INDEX_ID、NAME和ID的值被合並為索引表的rowKey,其中_INDEX_ID並沒有值(\x000是十六進制表示,轉換為字符串是空格)

更新表

索引表自動更新


mutable 與 inmutable 

phoenix將其二級索引技術划分為global and local indexing 2種,但是如果繼續往下細分的話又分為

mutable global indexing、mutable local indexing、immutable global indexing、immutable local indexing

一共四種。

默認創建的二級索引為mutable的(mutable global ing或者mutable local indexing)。


immutable類型的索引主要針對的是數據一次入庫之后永不改變的場景(only written once and never updated)。


 

創建Inmutable表

   
   
   
           
  1. create table company_immutable(id varchar primary key, name varchar, address varchar) IMMUTABLE_ROWS=true;

創建索引與mutable一樣,只是更新數據時,索引表的數據並未被修改,而是追加。



  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM