Phoenix中不得不吐槽的兩大特徵

Phoenix是什麼?看看官網就知道了,我就不細說了。關於它的優點,官網也是列了一大堆,我也不復述了。

下面只談談截止Phoenix4.2.1,我認爲初學者應該注意的兩個特徵:

1. 完全喪失了HBase的多版本特徵

HBases至少也是三維結構(row、cf:cq、timestamp)的數據模型,Phoenix將其映射爲二維的關係模型後,便面對着損失信息精度的尷尬場面。這種尷尬具體表現在Phoenix使用的兩個方面:

a. 不能爲一個cell指定任意的timestamp

作爲HBase的第三維特徵,timestamp的重要性不言而喻。由於絕大部分數據應用場景都離不開時間維度,所以我們經常會將數據中的某個時間字段映射到timestamp,也就無需在CF中存儲該字段了。這樣的好處是:既節約了存儲空間,也可以使用timestamp相關的API(例如Get#setTimeRange)進行查詢。
遺憾的是,Phoenix並不能讓我們像HBase一樣指定任意的timestamp。雖然Phoenix在F.A.Q.中煞有其事的提出了貌似這個問題的解決方案。但是深究之後你會發現這是一個比較坑爹的方案。理由如下:

  • 首先,該方案貌似可以指定任意的timestamp,但是需要在應用程序中頻繁的創建和關閉Connection,雖然他們還專門強調這不是一個“昂貴”的操作(is not an expensive operation),但是這樣的代碼風格估計會讓很多人無語。
  • 其次,該方案的任意timestamp其實是有條件的,即必須大於表的創建時間,否則,會出現“Table undefined”的異常。
需要說明的是,Phoenix可以Upsert重複的記錄,每條記錄的timestamp是不一樣的。這樣來看,雖然timestamp不是我期待的,但是多版本是不是已經實現了呢?看到下面的一點你應經就明白了。。。。。。

b. 不能獲取一個cell的多個版本
Phoenix總是獲取cell的最新版本,有沒有辦法去獲取其它版本呢?
我曾經受F.A.Q.中CurrentSCN屬性的啓發,自以爲想到一個方法:不管三七二十一,先去拿一次,拿到的肯定是最新版本了。取其timestamp賦給PhoenixRuntime.CURRENT_SCN_ATTRIB後再去拿,這樣就拿到次新版本了。以此類推,每次拿一個版本,直到拿不到而已。雖然這種方法有點笨,但是我想着總是可以解決問題的。但是後來突然發現一個致命的缺陷:如何取結果中的timestamp呢?呵呵,看來這個方法不單單是“有點笨”了......
相信這個問題也困擾了許多人,並引發了許多人的思考。PHOENIX-590便是專門針對這個問題,遺憾的是,雖然提出了一些解決思路,但是至今仍然沒有實質性的進展。

變通方案
PHOENIX-590提出了一種解決方案,其實也和我們想的一樣。。。。。。就是將timestamp作爲Phoenix表的單獨一列,並且和其它字段作爲組合主鍵。這樣的本質是row和timestamp二維合成一維,反映在HBase裏面,其實是將timestamp的值附加在row後面了。這樣可以解決使用timestamp查詢的問題,缺點是浪費了一些存儲空間。

2. 二級索引設計比較粗糙
CREATE  INDEX  idx_name  ON  TAB_NAME(IDX_FIELD);
SELECT OtherField FROM TAB_NAME WHERR IDX_FIELD='';
我以爲這樣就可以利用索引了,但是其實不然,必須要
CREATE  INDEX  idx_name  ON  TAB_NAME(IDX_FIELD) INCLUDE(OtherField);
因爲二級索引創建了一個新的索引表,沒有INICLUDE時,索引表中的value爲空,上述查詢將不會利用索引表,而是Full Scan主表。INCLUDE時,會將OtherField字段寫入索引表的value中,上述查詢將會利用索引表進行Range Sacn。
這種做法讓人不得不吐糟,雖然說存儲不值錢,但是也不能這麼浪費吧。
不過細想一下,這也是Phoenix的無奈之舉:因爲它不能保證主表和索引表對應Region的本地化,所以也就無法根據索引表的結果再去查主表了。

變通方案
a. 客戶端自己解決:先查索引表獲取Primary Key,然後根據Primary Key二次查詢主表;
b. 使用其他索引方案......
針對目前Phoenix的二級索引方案,我個人建議一定要謹慎使用。鑑於其無與倫比的膨脹性,我建議只考慮使用在比較小的表上,並且對該表是寫少讀多。



發佈了66 篇原創文章 · 獲贊 6 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章