這是CDP中Apache Hive3用戶指南系列之一,之前的文章請參考<CDP的Hive3系列之Hive Metastore介紹>,<CDP中的Hive3系列之Apache Hive3的特性>,<CDP中的Hive3系列之啟動Apache Hive3>,<CDP中的Hive3系列之Hive3使用指南>,<CDP中的Hive3系列之管理Hive3>,<CDP中的Hive3系列之管理Hive的工作負載>和<CDP中的Hive3系列之配置Apache Hive3>和<CDP中的Hive3系列之保護Hive3>.
1 性能調優的最佳實踐
查看與配置集群、存儲數據和編寫查詢相關的某些性能調優指南,以便您可以保護集群和相關服務、自動擴展資源以處理查詢等。
1.1 最佳實踐
· 使用 Ranger 安全服務來保護您的集群和依賴服務。
· 使用 ORC 文件格式存儲數據。其他的,例如 Parquet 也受支持,但對於 Hive 查詢沒有那麼快。
· 通過檢查解釋計劃確保查詢完全矢量化。
2 ORC 文件格式
您可以通過多種方式節省存儲空間,但使用優化行列式 (ORC) 文件格式來存儲 Apache Hive 數據最為有效。ORC 是 Hive 數據的默認存儲。
出於以下原因,推薦用於 Hive 數據存儲的 ORC 文件格式:
· 高效壓縮:存儲為列並進行壓縮,從而減少磁盤讀取。列格式也是 Tez 中矢量化優化的理想選擇。
· 快速讀取:ORC 具有內置索引、最小值/最大值和其他聚合,這些聚合會導致在讀取過程中跳過整個條帶。此外,謂詞下推將過濾器推送到讀取中,以便讀取最少的行。布隆過濾器進一步減少了返回的行數。
在大規模部署中得到驗證:Facebook 使用 ORC 文件格式進行 300+ PB 部署。
ORC 總體上提供了最佳的 Hive 性能。另外,要指定存儲格式,還可以為表指定壓縮算法,如下例所示:
CREATE TABLE addresses ( name string, street string, city string, state string, zip int ) STORED AS orc TBLPROPERTIES ("orc.compress"="Zlib");
通常不需要設置壓縮算法,因為您的 Hive 設置包括默認算法。使用 ORC 高級屬性,您可以為點查找中經常使用的列創建布隆過濾器。
Hive 支持 Parquet 和其他格式用於僅插入的 ACID 表和外部表。您還可以編寫自己的 SerDes(Serializers、Deserializers)接口來支持自定義文件格式。
2.1 高級 ORC 屬性
通常,您不需要修改優化行列式 (ORC) 屬性,但偶爾,Cloudera支持建議進行此類更改。查看可以配置 ORC 以滿足您的需要的屬性鍵、默認值和描述。
2.1.1 屬性鍵和默認值
您可以使用 Cloudera Manager 中的安全閥功能來更改 ORC 屬性。
鍵值 |
默認設置 |
描述 |
orc.compress |
ZLIB |
壓縮類型(NONE、ZLIB、SNAPPY)。 |
orc.compress.size |
262,144 |
每個壓縮塊中的字節數。 |
orc.stripe.size |
268,435,456 |
每個條帶中的字節數。 |
orc.row.index.stride |
10,000 |
索引條目之間的行數 (>= 1,000)。 |
orc.create.index |
true |
設置是否創建行索引。 |
orc.bloom.filter.columns |
-- |
必須為其創建布隆過濾器的以逗號分隔的列名稱列表。 |
orc.bloom.filter.fpp |
0.05 |
布隆過濾器的誤報概率。必須大於 0.0 且小於 1.0。 |
3 使用分區提高性能
您必須瞭解什麼是分區修剪、如何啟用動態分區以及批量加載數據所需的配置,以確保顯著提高性能。您可以使用分區來顯著提高性能。您可以設計 Hive 表和物化視圖分區以映射到文件系統/對象存儲上的物理目錄。例如,按日期-時間分區的表可以組織每天加載到 Hive 中的數據。
大型部署可以有數以萬計的分區。當 Hive 在查詢處理期間發現分區鍵時,會間接進行分區修剪。例如,加入維度表後,分區鍵可能來自維度表。查詢按分區過濾列,限制對一個或幾個匹配分區進行的掃描。當 WHERE 子句中存在分區鍵時,會直接進行分區修剪。分區列是虛擬的,不會寫入主表,因為這些列對於整個分區是相同的。
您不需要指定動態分區列。如果啟用動態分區,Hive 會生成分區規範。
加載1到9個分區的配置:
SET hive.exec.dynamic.partition.mode=nonstrict; SET hive.exec.dynamic.partition=true;
要將數據批量加載到分區 ORC 表中,您可以使用以下屬性,優化數據加載到 10 個或更多分區的性能。
加載 10 個或更多分區的配置:
hive.optimize.sort.dynamic.partition=true
4 Hive 中的分桶表
如果您將數據從較早的 Apache Hive 版本遷移到Hive 3,您可能需要處理影響性能的分桶表。查看 CDP 如何簡化處理存儲桶。您將瞭解處理動態功能的最佳實踐。
您可以將表或分區劃分為桶,桶的存儲方式如下:
· 作為表目錄中的文件。
· 如果表已分區,則作為分區目錄。
沒有必要在 Hive 3 表中指定桶。在 CDP 中,Hive 3 隱式存儲數據,並且不像早期版本(ACID V1)那樣需要用戶密鑰或用戶提供的存儲桶編號。例如:
V1:
CREATE TABLE hello_acid (load_date date, key int, value int) CLUSTERED BY(key) INTO 3 BUCKETS STORED AS ORC TBLPROPERTIES ('transactional'='true');
V2:
CREATE TABLE hello_acid_v2 (load_date date, key int, value int);
ACID V2 表的性能與使用桶的非 ACID 表相當。ACID V2 表與原生雲存儲兼容。
在從早期版本遷移的表中使用存儲桶的一個常見挑戰是在工作負載或數據向上或向下擴展時保持查詢性能。例如,您可能擁有一個使用 16 個存儲桶以支持 1000 個用戶的平穩運行的環境,但是如果您不及時調整存儲桶和分區,用戶數量在一兩天內激增至 100,000 會產生問題。由於在您構建了一個包含存儲桶的表之後,必須重新加載包含存儲桶數據的整個表以減少、添加或刪除存儲桶,因此調整存儲桶很複雜。
在使用 Tez 的 CDP 中,您只需要處理最大表的桶。如果工作負載需求快速變化,較小表的桶會動態變化以完成表 JOIN。
您執行以下與存儲桶相關的任務:
· 設置hive-site.xml以啟用存儲桶
SET hive.tez.bucket.pruning=true
· 分區和分桶的批量加載表:
將數據加載到分區和分桶的表中時,請設置以下屬性以優化過程:
如果您在 user_id 數據上有 20 個存儲桶,則以下查詢僅返回與 user_id = 1 關聯的數據: SELECT * FROM tab WHERE user_id = 1;
為了最好地利用 Tez 上表桶的動態能力,請採用以下做法:
· 對最大表的桶使用單個鍵。
· 通常,您需要按最大維度表對主表進行分桶。例如,銷售表可能按客戶分類,而不是按商品或商店分類。但是,在這種情況下,銷售表按商品和商店排序。
· 通常,不要對同一列進行分桶和排序。
存儲區文件多於行數的表表明您應該重新考慮表的存儲區劃分方式。