phoenix客戶端在成功提交乙個操作並且得到成功響應後,就代表你所做的操作已經成功應用到原表和相關的索引表中。換句話說,索引表的維護和處理原表資料是同步的,並且各自是強一致性保證的。但是因為索引表和原表是在不同的表中,根據表的屬性和索引的型別,當服務端崩潰導致一次提交失敗時,原表和索引表中的資料就會有一些變化。所以在使用二級索引的時候,就要根據需求個用例充分考慮。
下面列出了一些不同級別的一致性保證供你選擇。
1. 事務表
如果把錶定義成事務表(transactional),你將獲得最高端別的一致性保證。原表的操作和索引表的操作完全就是乙個原子操作。如果提交失敗,原表和索引表的資料都不會被更新,如果啟用了這種級別的一致性,你的原表和索引表永遠都保持同步。目前這個功能還是beta版本階段,它是實現依賴於另乙個apache專案apache tephra。它是乙個分布式事務框架。
那為什麼不把所有的表都設定能事務的呢?特別是一些被宣告了是不可變的表(只寫一次,不修改的表),因為這個時候事務的損耗是非常小的。但是一旦你的表中的資料會變化,那麼你就要承擔一些衝突檢測和事務管理器的開銷;同時做事務表中建二級索引,會潛在的降低系統的可用性,因為原表和二級索引表都必須可用行,不然都會失敗。
2. 不可變表
不可變表中的資料之寫入一次,之後就再也不會被更新了。對於這種表,phoenix會做特別的優化,降低寫入的損耗和增量維護的損耗。這類資料通常就是一些時間序列的資料,比如日誌、事件、或者感測器的週期資料等等。這類表結構需要在見表的時候加上 immutable_rows=true 語句,這樣資料表就會被優化。預設建表是可變的。
createtable hao2 (k varchar
primary
key, v varchar) immutable_rows=true;
在不可變表上面建的所有的索引都是不可變的。對於全域性的不可變索引來說,索引全部由客戶端來維護,原表的資料變化會觸發索引的修改。本地索引在服務端維護。需要注意的是,phoenix沒有強制在一張申明了不可變的原表上修改資料,索引將不再與原表同步。
altertable hao2 set immutable_rows = false;
另外,非事務性、不可變表的索引沒有自動處理提交失敗的機制。保持表和索引之間的一致性留給客戶端處理。因為更新是冪等的,最簡單的解決方案是客戶端不斷嘗試直到成功。
3. 易變的表
對於非事務的可變表,我們通過新增索引更新到原表的wal日誌裡來維護索引資訊的更新。只有當wal同步後,才會去真的更新索引或原表。phoenix寫索引檔案是並行的,這樣有助於效能的提高,吞吐量增大。如果我們正在更新索引的時候,伺服器掛了,我們會找到對應的wal,重新執行所有的更新。更新的冪等性保證了資料的準確性。
不過需要注意一下幾點:
1. 由於是非事務表,有時候也可能出現原表和索引表的資料不同步。
2. 就像上文所說,phoenix是有可能在很短暫的時間裡資料和索引不一致的,但是這是乙個很短的過程,一般來說不會有影響。
3. hbase保證了每乙個資料行或索引行都保證要麼寫入,要麼丟失,你不可能看到一條資料有部分列寫入而部分列沒有寫入。
4. 資料是先入hbase原表,然後再插入索引表。
為了保證易變的表和索引同步,phoenix主要提供三種級別:
1. 如果不一致,禁止原表寫入
這是最高端別的一致性級別,需要也別設定。當索引表更新出錯的時候,原表會暫時禁用,不能寫或更新資料。這個時候索引會自動重建,等索引和原表同步後,索引和原表才能恢復使用。
主要有兩個配置項配置在服務端:
2. 如果不一致,禁用索引表
這是phoenix的預設級別。如果寫入索引表失敗,索引表會標記成失效並且禁用索引,然後啟動後台任務重建部分索引,等到完成之後再次啟用索引。這種級別下,索引的失效和重建不會影響hbase原表的操作,只是在查詢的時候索引不能使用了。
主要有二個服務端配置項:
3. 如果不一致,需要人工重建索引
這是最低級別的同步策略。如果寫入索引失敗,phoenix不會自動重建,而是需要人工命令重建索引。
服務端配置如下:
phoenix的索引重建是把索引表清空後重新裝配資料。入上文所說,重建有可能是某個操作失敗後系統後台自動的行為,也可以是人工來重建。人工重建的語法如下:
alterindex index1_local on hao1 rebuild;
一般來說,索引已經很快了,不需要特別的優化。這裡也提供了一些方法,讓你在面對特定的環境和負載的時候可以進行一些調優。下面的這些需要在hbase-site.xml檔案中設定,針對所有的伺服器。
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
Phoenix系列 二級索引
phoenix使用hbase作為後端儲存,對於hbase來說,我們通常使用字典序的rowkey來快速訪問資料,除此之外,也可以使用自定義的filter來搜尋資料,但是它是基於全表掃瞄的。而phoenix提供的二級索引是可以避開全表掃瞄,是在hbase中快速查詢或批量檢索資料的另乙個選擇。下面的例子使...
Phoenix二級索引建立
全域性索引是phoenix的重要特性,合理的使用二級索引能降低查詢延時,讓集群資源得以充分利用。本文將講述如何高效的設計和使用索引。全域性索引的根本是通過單獨的hbase表來儲存資料表的索引資料。我們通過如下示例看索引資料和主表資料的關係。建立資料表create table data table a...
CDH HBASE二級索引
a 對於已存在的表,每個需要建立索引的列簇都需要設定 replication scope 命令如下 b 新建表,用如下命令 c 生成實體配置檔案 d 編輯 home bigdata xuhailiu solr web collection conf schema.xml 檔案。為方便除錯,取出了檔案...