選單

FAQ系列之Phoenix

查詢有關 Apache Phoenix 及其部署的常見問題解答。

Phoenix 可以用於 ETL 用例嗎?

是的。Apache Phoenix 用於 OLTP(線上事務處理)用例,而不是 OLAP(線上分析處理)用例。不過,您可以將 Phoenix 用於實時資料攝取作為主要用例。

Phoenix 部署的典型架構是什麼?

典型的 Phoenix 部署具有以下內容:

應用

Phoenix 客戶端/JDBC 驅動程式

HBase 客戶端

Phoenix 客戶端/JDBC 驅動程式本質上是一個 Java 庫,您應該將其包含在您的 Java 程式碼中。Phoenix 使用 HBase 作為儲存,類似於 HBase 使用 HDFS 作為儲存的方式。但是,Phoenix 的抽象還沒有完成,例如為了實現訪問控制,您需要在包含 Phoenix 資料的底層 HBase 表上設定 ACL。

FAQ系列之Phoenix

是否有適用於 Phoenix JDBC 伺服器的大小指南?

對於 Phoenix 應用程式,您必須遵循與 HBase 相同的大小調整指南。有關 Phoenix 效能調優的更多資訊,請訪問 https://phoenix。apache。org/tuning_guide。html。

我可以管理對 Phoenix 伺服器的訪問嗎?

是的,您可以使用 Kerberos 進行身份驗證。您可以使用 HBase 授權配置授權。

我可以在 Phoenix 表中看到單個單元格的時間戳嗎?這是常用的東西嗎?

您可以將 HBase 的本機行時間戳對映到 Phoenix 列。透過這樣做,您可以利用 HBase 為儲存檔案的時間範圍提供的各種最佳化以及 Phoenix 內建的各種查詢最佳化功能。

有關更多資訊,請參閱https://phoenix。apache。org/rowtimestamp。html

如果 Phoenix 索引是非同步構建的,並且在索引期間將資料新增到表中怎麼辦?

Phoenix 在全域性索引維護期間執行本地索引以防止死鎖。:當索引更新失敗時,Phoenix 還會部分自動重建索引 ( PHOENIX-1112 )。

序列如何在Phoenix工作?

序列是一個標準的 SQL 特性,它允許生成通常用於形成 ID 的單調遞增數字。

有關更多資訊,請參閱https://phoenix。apache。org/sequences。html。

當 RegionServer 出現故障時,Phoenix 寫入會發生什麼?

寫入是持久的,永續性由提交到磁碟(在預寫日誌中)的 WRITE 定義。因此,在 RegionServer 發生故障的情況下,可以透過重放 WAL 來恢復寫入。“完整”寫入是已從 WAL 重新整理到 HFile 的寫入。任何失敗都將表示為異常。

我可以在 Phoenix 中進行批次資料載入嗎?

是的,您可以在 Phoenix 中進行批次插入。有關更多資訊,請參閱https://phoenix。apache。org/bulk_dataload。html。

我可以使用標準 HBase API 訪問 Phoenix 建立的表嗎?

是的,但不推薦或不支援。資料是由 Phoenix 編碼的,因此您必須對資料進行解碼才能讀取。直接寫入 HBase 表會導致 Phoenix 損壞。

我可以將 Phoenix 表對映到現有的 HBase 表上嗎?

是的,只要使用 Phoenix 資料型別。您必須使用非同步索引並手動更新它們,因為 Phoenix 不會知道任何更新。

Phoenix JDBC URL 語法是什麼?

Thick驅動器

Phoenix (Thick) Driver JDBC URL 語法如下(方括號中的元素是可選的):

最簡單的網址是:

jdbc:phoenix:localhost

而最複雜的 URL 是:

請注意,URL 中的每個可選元素都需要之前的所有可選元素。例如,以指定根HBase的Z序節點,動物園管理員埠必須也被指定。

此資訊最初包含在索引頁上。

Thin驅動器

Phoenix Thin Driver(與 Phoenix Query Server 一起使用)JDBC URL 語法如下:

有許多金鑰公開供客戶端使用。最常用的鍵是:url和serialization。該網址的關鍵是需要與Phoenix網查詢伺服器進行互動。

最簡單的網址是:

其中非常複雜的 URL 是:

有關瘦客戶端 JDBC URL 中受支援選項的完整列表,請參閱Apache Avatica 文件,或參閱查詢伺服器文件

有沒有辦法在Phoenix批次載入?

CSV

可以使用名為 psql 的內建實用程式批次載入 CSV 資料。典型的 upsert 速率是每秒 20K - 50K 行(取決於行的寬度)。

用法示例:

使用 psql 建立表$ psql。py [zookeeper] 。。/examples/web_stat。sql

Upsert CSV 批次資料$ psql。py [zookeeper] 。。/examples/web_stat。csv

如何將 Phoenix 表對映到現有的 HBase 表?

您可以透過 CREATE TABLE/CREATE VIEW DDL 語句在預先存在的 HBase 表上建立 Phoenix 表或檢視。在這兩種情況下,我們將保留 HBase 元資料原樣。對於 CREATE TABLE,我們將建立任何尚不存在的元資料(表、列族)。我們還將為每一行新增一個空鍵值,以便查詢按預期執行(無需在掃描期間投影所有列)。

另一個警告是位元組序列化的方式必須與 Phoenix 的位元組序列化方式相匹配。對於 VARCHAR、CHAR 和 UNSIGNED_* 型別,我們使用 HBase Bytes 方法。CHAR 型別只需要單位元組字元,UNSIGNED 型別需要大於或等於零的值。對於有符號型別(TINYINT、SMALLINT、INTEGER 和 BIGINT),Phoenix 將翻轉第一位,以便負值排在正值之前。因為 HBase 按字典順序對行鍵進行排序,負值的第一位是 1 而正值是 0,所以如果我們不翻轉第一位,負值就會“大於”正值。因此,如果您透過 HBase 本機 API 儲存整數並希望透過 Phoenix 訪問它們,請確保您的所有資料型別都是 UNSIGNED 型別。

我們的複合行鍵是透過簡單地將值連線在一起形成的,在可變長度型別之後使用一個零位元組字元作為分隔符。

如果您像這樣建立 HBase 表:

那麼你有一個名為“t1”的 HBase 表和一個名為“f1”的列族。請記住,在 HBase 中,您不會對可能的 KeyValues 或行鍵的結構進行建模。這是您在 Phoenix 中指定的超出表和列族的資訊。

因此,在 Phoenix 中,您將建立一個如下所示的檢視:

“pk”列宣告您的行鍵是 VARCHAR(即字串),而“f1”。val 列宣告您的 HBase 表將包含具有列族和列限定符“f1”:VAL 的鍵值,並且它們的值將是一個 VARCHAR。

請注意,如果您使用所有大寫名稱建立 HBase 表,則不需要雙引號(因為這是 Phoenix 透過大寫字母對字串進行規範化的方式)。例如,與:

你可以建立這個Phoenix檢視:

或者,如果您正在建立新的 HBase 表,只需讓 Phoenix 像這樣為您做所有事情(根本不需要使用 HBase shell。):

有沒有最佳化Phoenix的技巧?

使用

Salting

提高讀/寫效能 Salting 可以透過將資料預先拆分到多個區域來顯著提高讀/寫效能。儘管在大多數情況下加鹽會產生更好的效能。

例子:

注意:理想情況下,對於具有四核 CPU 的 16 個區域伺服器叢集,選擇 32-64 之間的鹽桶以獲得最佳效能。

每個拆分

表 Salting 會自動進行表拆分,但如果您想精確控制表拆分發生的位置而不新增額外位元組或更改行鍵順序,那麼您可以預先拆分表。

例子:

使用

多個列族

列族在單獨的檔案中包含相關資料。如果您查詢使用選定的列,那麼將這些列組合在一個列族中以提高讀取效能是有意義的。

例子:

下面的 create table DDL 將建立兩個列 faimiles A 和 B。

建立表測試(MYKEY VARCHAR NOT NULL PRIMARY KEY、A。COL1 VARCHAR、A。COL2 VARCHAR、B。COL3 VARCHAR)

使用

壓縮

磁碟壓縮可提高大型表的效能

例子:

如何在表上建立二級索引?

從 Phoenix 2。1 版開始,Phoenix 支援對可變和不可變資料進行索引。請注意,Phoenix 2。0。x 僅支援對不可變資料進行索引。不可變表的索引寫入效能指標比可變表稍快,但不可變表中的資料無法更新。

例子

建立表

不可變表:

可變表:

在 col2 上建立索引

在 col1 上建立索引並在 col2 上建立覆蓋索引

Upsert 這個測試表中的行,Phoenix 查詢最佳化器會選擇正確的索引來使用。如果 Phoenix 正在使用索引表,您可以在解釋計劃中看到。您還可以在 Phoenix 查詢中提示使用特定索引。

為什麼我的二級索引沒有被使用?

除非查詢中使用的所有列都在其中(作為索引或覆蓋的列),否則不會使用二級索引。構成資料表主鍵的所有列都將自動包含在索引中。

示例:

查詢:

在這種情況下不會使用索引,因為姓氏不是索引或覆蓋列的一部分。這可以透過檢視解釋計劃來驗證。要修復此建立具有索引的姓氏部分或覆蓋列的索引。示例:

Phoenix有多快?為什麼這麼快?

Phoenix很快。100M 行的全表掃描通常在 20 秒內完成(中型叢集上的窄表)。如果查詢包含鍵列上的過濾器,這個時間會減少到幾毫秒。對於非鍵列或非前導鍵列上的過濾器,您可以在這些列上新增索引,透過製作帶有索引列的表的副本作為鍵的一部分,從而獲得與對鍵列進行過濾等效的效能。

為什麼即使進行全掃描,Phoenix 也很快:

Phoenix 使用區域邊界將您的查詢分塊,並使用可配置的執行緒數在客戶端上並行執行它們

聚合將在伺服器端的協處理器中完成,合併返回給客戶端的資料量,而不是全部返回。

如何連線到安全的 HBase 叢集?

檢視 Anil Gupta 的精彩帖子http://bigdatanoob。blogspot。com/2013/09/connect-phoenix-to-secure-hbase-cluster。html

如何連線在 Hadoop-2 上執行的 HBase?

Hadoop-2 配置檔案存在於 Phoenix pom。xml 中。

phoenix 是否可以像 HBase API 一樣靈活地處理具有任意時間戳的表?

預設情況下,Phoenix 讓 HBase 管理時間戳,並只顯示所有內容的最新值。然而,Phoenix 也允許使用者提供任意時間戳。為此,您需要在連線時指定“CurrentSCN”,如下所示:

以上相當於使用 HBase API 執行此操作:

透過指定 CurrentSCN,您告訴 Phoenix 您希望在該時間戳完成該連線的所有操作。請注意,這也適用於在連線上完成的查詢 - 例如,上面 myTable 上的查詢不會看到它剛剛插入的資料,因為它只能看到在其 CurrentSCN 屬性之前建立的資料。這提供了一種執行快照、閃回或時間點查詢的方法。

請記住,建立新連線並不是一項昂貴的操作。相同的底層 HConnection 用於到同一個叢集的所有連線,因此它或多或少類似於例項化一些物件。

為什麼我的查詢不進行範圍掃描?

RANGE SCAN 意味著只會掃描表中行的一個子集。如果您使用主鍵約束中的一個或多個前導列,則會發生這種情況。未過濾前導 PK 列的查詢,例如。select * from test where pk2=‘x’ and pk3=‘y’; 將導致完全掃描,而以下查詢將導致範圍掃描select * from test where pk1=‘x’ and pk2=‘y’; 。 請注意,您可以在“pk2”和“pk3”列上新增二級索引,這將導致對第一個查詢(透過索引表)進行範圍掃描。

DEGENERATE SCAN 意味著查詢不可能返回任何行。如果我們可以在編譯時確定這一點,那麼我們甚至不必費心執行掃描。

FULL SCAN 意味著將掃描表的所有行(如果您有 WHERE 子句,則可能會應用過濾器)

SKIP SCAN 意味著將掃描表中的一個子集或所有行,但是它會根據過濾器中的條件跳過大組行。有關更多詳細資訊,請參閱此部落格。如果前導主鍵列沒有過濾器,我們不會執行 SKIP SCAN,但您可以使用 /+ SKIP_SCAN/ 提示強制執行 SKIP SCAN 。在某些情況下,即當您的前導主鍵列的基數較低時,它會比 FULL SCAN 更有效。

我應該池化 Phoenix JDBC 連線嗎?

不,沒有必要將 Phoenix JDBC 連線池化。

由於底層的 HBase 連線,Phoenix 的 Connection 物件與大多數其他 JDBC Connection 不同。Phoenix Connection 物件被設計為一種建立成本低的薄物件。如果重複使用 Phoenix Connections,則底層 HBase 連線可能不會始終處於前一個使用者的健康狀態。最好建立新的 Phoenix Connections 以確保避免任何潛在問題。

為 Phoenix 實現池化可以簡單地透過建立一個委託 Connection 來完成,該連線在從池中檢索時例項化一個新的 Phoenix 連線,然後在將其返回到池中時關閉連線(參見PHOENIX-2388)。

為什麼 Phoenix 在執行 upsert 時會新增一個空的/虛擬的 KeyValue?

需要空的或虛擬的 KeyValue(列限定符為 _0)以確保給定的列可用於所有行。

您可能知道,資料作為 KeyValues 儲存在 HBase 中,這意味著為每個列值儲存完整的行鍵。這也意味著除非儲存了至少一列,否則根本不儲存行鍵。

現在考慮具有整數主鍵的 JDBC 行和幾個全為空的列。為了能夠儲存主鍵,需要儲存一個 KeyValue 以表明該行完全存在。此列由您注意到的空列表示。這允許執行“SELECT * FROM TABLE”並接收所有行的記錄,即使是那些非 pk 列為空的記錄。

即使某些(或所有)記錄只有一列為空,也會出現同樣的問題。Phoenix 上的掃描將包括空列,以確保僅包含主鍵(並且所有非鍵列都為 null)的行將包含在掃描結果中。

https://docs。cloudera。com/cdp-private-cloud-base/7。1。6/phoenix-faq/topics/phoenix-faq。html