1. Hive建表中ORC格式的使用
refer:https://blog.csdn.net/longshenlmj/article/details/51702343
#Hive建外部External表(外部表external table):
#
#添加分區並載入分區數據:
alter table table_name add partition (proc_date='${hivevar:pdate}') location '...'(不改變源數據存儲位置)
alter table table_name add if not exsit partition (proc_date='${hivevar:pdate}') location 'hdfs://hdfscluster/'
load data inpath '...' into table table_name partition(proc_date='${hivevar:pdate}');(會將源數據切到hive表指定的路徑下)
#刪除分區: alter table table_name drop if exists partition(proc_date='${hivevar:pdate}');
#TBLPROPERTIES
實際上就是table properties,TBLPROPERTIES允許開發者定義一些自己的鍵值對信息。可以對TBLPROPERTIES進行查看和修改(部分可修改)。在TBLPROPERTIES中有一些預定義信息,比如last_modified_user和last_modified_time,其他的一些預定義信息包括:
#tplproperties屬性參考
(1)comment:可以用來定義表的描述信息。
(2)hbase.table.name:hive通過 storage handler(暫放)將hive與各種工具聯系起來,這是是使用hive接入hbase時,設置的屬性(暫放)。
(3)immutable:顧名思義『不可變的』,當表的這個屬性為true時,若表中無數據時可以insert數據,但是當表已經有數據時,insert操作會失敗。不可變表用來防止意外更新,避免因腳本錯誤導致的多次更新,而沒有報錯。本人實際中還沒用到這個屬性。
(4)orc.compress:這是orc存儲格式表的一個屬性,用來指定orc存儲的壓縮方式(暫放)。
(5) transactional,NO_AUTO_COMPACTION,compactor.maprece.map.memory.mb,compactorthreshold.hive.compactor.delta.num.threshold,compactorthreshold.hive.compactor.delta.pct.threshold:這5個屬性與hive的事務支持有關,先不做了解。
(6)auto.purge:當設置為ture時,刪除或者覆蓋的數據會不經過回收站,直接被刪除。配置了此屬性會影響到這些操作: Drop Table, Drop Partitions, Truncate Table,Insert Overwrite。
(7)EXTERNAL:通過修改此屬性可以實現內部表和外部表的轉化。
#
2. 5種讓Hive查詢變快的方法
在過去幾年中,主要受到圍繞Stinger計劃的Hive社區創新的推動,Hive查詢時間得到了顯著改善,使Hive能夠以速度和規模支持批量和互動式工作負載。
但是,許多使用者仍然不熟悉以最快速度運行Hive查詢的基本技術和最佳實踐。本文中,將重點介紹一些常使用的簡單技術,以提高HIVE查詢的性能。
Hive可以使用Apache Tez執行引擎而不是Map-rece引擎。不會詳細介紹這里提到的使用Tez的許多好處; 相反,提出一個簡單的建議:如果在您的環境中默認情況下沒有打開它,請在Hive查詢的開頭使用Tez設置為「true」
Hive支持ORCfile,這是一種新的表存儲格式,通過謂詞下推,壓縮等技術實現極佳的速度提升。
對每個HIVE表使用ORCFile應該是一個明智的選擇,對於獲得HIVE查詢的快速響應時間非常有益。
作為一個例子,考慮兩個大表A和B(存儲為文本文件,這里沒有指定一些列),以及一個簡單的查詢 :
此查詢可能需要很長時間才能執行,因為表A和B都存儲為TEXT。將這些表轉換為ORCFile格式通常會顯著縮短查詢時間:
ORC支持壓縮存儲(使用ZLIB或如上所示使用SNAPPY),但也支持未壓縮存儲。
將基表轉換為ORC通常是取決於所在團隊獲取數據的職責,由於其他優先順序,可能需要一些時間來更改完整的獲取數據過程。ORCFile的好處是如此明顯,以至於推薦如上所示的自助式方法 - 將A轉換為A_ORC,將B轉換為B_ORC並以此方式進行連接,以便立即從更快的查詢中受益,而不依賴於其他團隊。
矢量化查詢執行通過一次批量執行1024行而不是每行一行來提高掃描,聚合,過濾器和連接等操作的性能。
這個功能在Hive 0.13中引入,顯著縮短了查詢執行時間,並且可以通過兩個參數設置輕松啟用:
在提交最終執行之前,Hive會優化每個查詢的邏輯和物理執行計劃。這些優化不是基於查詢的成本 - 也就是說,直到運行時。
最近添加到Hive,基於成本的優化,基於查詢成本執行進一步優化,從而導致可能不同的決策:如何訂購聯接,執行哪種類型的聯接,並行度等。
要使用基於成本的優化(也稱為CBO),請在查詢開頭設置以下參數
然後,通過運行Hive的「analyze」命令為CBO准備數據,以收集我們想要使用CBO的表的各種統計信息。
例如,在tweet數據表中,希望收集有關該表的統計信息以及大約2列:「sender」和「topic」:
使用HIVE 0.14(在HDP 2.2上),analyze命令的工作速度要快得多,而且您不需要指定每一列,因此只需如下:
現在使用此表執行查詢應該會導致不同的執行計劃由於成本計算和Hive創建的不同執行計劃而更快。
SQL是一種強大的聲明性語言。與其他聲明性語言一樣,編寫SQL語句的方法不止一種。盡管每個語句的功能都相同,但它可能具有截然不同的性能特徵
每條記錄代表一次點擊事件,希望找到每個sessionID的最新網址。
有人使用如下方式:
在上面的查詢中,構建一個子查詢來收集每個會話中最新事件的時間戳,然後使用內部聯接來過濾掉其餘的事件。
雖然查詢是一個合理的解決方案 - 從功能的角度來看 - 事實證明,有一種更好的方法來重寫這個查詢,如下所示
在這里,使用Hive的OLAP功能(OVER和RANK)來實現相同的功能,但沒有使用表連接。
顯然,刪除不必要的連接幾乎總能帶來更好的性能,而且當使用大數據時,這比以往任何時候都更重要。在很多情況下查詢不是最優的 - 所以仔細查看每個查詢並考慮重寫是否可以使它更好更快。
更多內容信息 https://blue-shadow.top
3. hive查詢時間復雜度
1、使用Tez引擎
Apache Tez Engine是一個可擴展的框架,用於構建高性能批處理和互動式數據處理。它由YARN在Hadoop中 調度。Tez通過提高處理速度和保持MapRece擴展到數PB數據的能力來改進MapRece job。
通過設置hive.execution.engine 為tez:可以在環境中啟用Tez引擎:
set hive.execution.engine=tez;
2、使用向量化
向量化通過在單個操作中獲取 1024 行而不是 每次只獲取單行來改善 scans, aggregations, filters 和 join 這類操作的性能。
我們可以通過執行以下命令在環境中啟用向量化:
set hive.vectorized.execution.enabled=true;
set hive.vectorized.execution.rece.enabled=true;
3、使用ORCFile
Hive 支持 ORCfile,這是一種新的表存儲格式,在讀取,寫入和處理數據時,ORCFile格式優於Hive文件格式,它通過 predicate push-down, compression 等技術來提高查詢速度。
在 HIVE 表中使用 ORCFile,將有益於獲得 HIVE 快速響應的查詢。
ORCFile 格式通過對原始數據存儲量壓縮75%,提供了高效的存儲 Hive 數據的方法。
舉例,考慮兩個大表 A 和 B(存儲為 TextFIle,這里沒有指定一些列),使用一個簡單的查詢,如:
SELECT A.customerID,
A.name,
A.age,
A.address
JOIN B.role,
B.department,
B.salary ON A.customerID=B.customerID;
由於表 A 和表 B 都存儲為 TextFile,因此執行此查詢可能需要很長時間。
將這些表存儲格式轉換為 ORCFile 格式通常會明顯減少查詢時間:
CREATE TABLE A_ORC (
customerID int,
name string,
age int,
address string
) STORED AS ORC tblproperties (「orc.compress" = 「SNAPPY」)
;
INSERT INTO TABLE A_ORC
SELECT *
FROM A
;
CREATE TABLE B_ORC (
customerID int,
ROLE string,
salary float,
department string
) STORED AS ORC tblproperties (「orc.compress" = 「SNAPPY」)
;
INSERT INTO TABLE B_ORC
SELECT *
FROM B
;
SELECT A_ORC.customerID,
A_ORC.name,
A_ORC.age,
A_ORC.address
JOIN B_ORC.role,
B_ORC.department,
B_ORC.salary ON A_ORC.customerID=B_ORC.customerID
;
ORC 支持壓縮存儲(使用 ZLIB 或如上所示使用 SNAPPY),但也支持不壓縮存儲。
4、使用分區
通過分區,數據存儲在 HDFS 上的單獨單個文件夾中。Hive 將查詢分區數據集,而不是 掃描表的所有數據集。
創建臨時表並將數據載入到臨時表中
CREATE TABLE Employee_Temp(
EmloyeeID int,
EmployeeName Varchar(100),
Address Varchar(100),
STATE Varchar(100),
City Varchar(100),
Zipcode Varchar(100)
) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE;
LOAD DATA INPATH '/home/hadoop/hive' INTO TABLE Employee_Temp;
創建分區表
Create Table Employee_Part(
EmloyeeID int,
EmployeeName Varchar(100),
Address Varchar(100),
State Varchar(100),
Zipcode Varchar(100))
PARTITIONED BY (City Varchar(100))
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;
啟用動態分區的命令
SET hive.exec.dynamic.partition = true;
SET hive.exec.dynamic.partition.mode = nonstrict;
從臨時表導入數據到分區表
INSERT Overwrite TABLE Employee_Part Partition(City)
SELECT EmployeeID,
EmployeeName,
Address,
STATE,
City,
Zipcode
FROM Emloyee_Temp;
5、使用 分桶
桶表介紹:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL+BucketedTables
舉例:https://blog.csdn.net/m0_37534613/article/details/55258928
Hive 表被劃分為多個分區,稱為 Hive分區。Hive分區進一步細分為集群或桶,稱為 bucket 或 Cluster。
Create Table Employee_Part(
EmloyeeID int,
EmployeeName Varchar(100),
Address Varchar(100),
State Varchar(100),
Zipcode Varchar(100))
PARTITIONED BY (City Varchar(100))
Clustered By (EmployeeID) into 20 Buckets
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;
6、CBO 查詢優化器
Hive CBO 是使用 Apache calcite 來處理的。
早期的 Hive 版本中(Hive-0.14 之前),在提交最終執行之前,Hive 會優化每個查詢的邏輯和物理執行計劃。 這些優化不是基於查詢的成本優化(Cost-based Optimizer) 。
直到 Hive-0.14 時才添加了 Cost-based optimization ,這時已經根據查詢的成本進行優化(例如要執行的連接類型,如何排序連接,並行度等)。
要使用基於成本的優化,需要在查詢開頭設置以下參數
set hive.cbo.enable=true;
set hive.compute.query.using.stats=true;
set hive.stats.fetch.column.stats=true;
set hive.stats.fetch.partition.stats=true;
如果要收集表信息,請使用 Analyze 命令。
7、寫好的 SQL
SQL是一種強大的聲明性語言。 與其他聲明性語言一樣,編寫SQL語句的方法不止一種。
盡管每個語句的功能都相同,但它可能具有截然不同的性能特徵。
我們來看一個例子。 考慮點擊流事件表:
CREATE TABLE clicks (
timestamp date, sessionID string, url string, source_ip string
) STORED as ORC tblproperties (「orc.compress」 = 「SNAPPY」);
每條記錄代表一次點擊事件,我們希望找到每個sessionID的最新網址。
有人可能會考慮以下方法:
SELECT clicks.* FROM clicks inner join
(select sessionID, max(timestamp) as max_ts from clicks
group by sessionID) latest
ON clicks.sessionID = latest.sessionID and
clicks.timestamp = latest.max_ts;
在上面的查詢中,我們構建一個子查詢來收集每個會話中最新事件的時間戳,然後使用 內聯接 來過濾掉其餘的事件。
雖然查詢是一個合理的解決方案, 但是從功能的角度來看 ,有一種更好的方法來重寫這個查詢,如下所示:
SELECT * FROM
(SELECT *, RANK() over (partition by sessionID,
order by timestamp desc) as rank
FROM clicks) ranked_clicks
WHERE ranked_clicks.rank=1;
在這里,我們使用 Hive 的 OLAP 窗口功能(OVER 和 RANK)來實現相同的功能。
顯然,刪除不必要的連接幾乎總能帶來更好的性能,而且當使用大數據時,這比以往任何時候都更重要。
我發現很多情況下查詢不是最優的 - 所以仔細查看每個查詢並考慮重寫是否可以使它更好更快。
————————————————
版權聲明:本文為CSDN博主「highfei2011」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/high2011/article/details/96271903
4. ORC文件格式
一、ORC文件格式
ORC文件也是以二進制方式存儲的,所以是不可以直接讀取,ORC文件也是自解析的,它包含許多的元數據,這些元數據都是同構ProtoBuffer進行序列化的。ORC的文件結構如下圖
在ORC文件中保存了三個層級的統計信息,分別為 文件級別、stripe級別和row group 級別的,他們都可以用來根據Search ARGuments( 謂詞下推條件 )判斷是否可以跳過某些數據,在統計信息中都包含成員數和是否有null值,並且對於不同類型的數據設置一些特定的統計信息。
(1)file level
在ORC文件的末尾會記錄文件級別的統計信息,會記錄整個文件中columns的統計信息。這些信息主要用於查詢的優化,也可以為一些簡單的聚合查詢比如max, min, sum輸出結果。
(2)stripe level
ORC文件會保存每個欄位stripe級別的統計信息,ORC reader使用這些統計信息來確定對於一個查詢語句來說,需要讀入哪些stripe中的記錄。比如說某個stripe的欄位max(a)=10,min(a)=3,那麼當where條件為a >10或者a <3時,那麼這個stripe中的所有記錄在查詢語句執行時不會被讀入。
(3)row level
為了進一步的避免讀入不必要的數據,在邏輯上將一個 column的index以一個給定的值(默認為10000,可由參數配置)分割為多個index組(也就是對每一列的分組數據建立索引,這樣能近一步減少不必要的查詢) 。以10000條記錄為一個組,對數據進行統計(比如min,max等)。Hive查詢引擎會將where條件中的約束傳遞給ORC reader,這些reader根據組級別的統計信息,過濾掉不必要的數據。如果該值設置的太小,就會保存更多的統計信息,用戶需要根據自己數據的特點權衡一個合理的值
詳細參考:https://www.cnblogs.com/ittangtang/p/7677912.html
5. Hive數據的序列化格式
1. TextFile
Hive數據表的默認格式,存儲方式:行存儲。
可使用Gzip,Bzip2等壓縮演算法壓縮,壓縮後的文件不支持split。
但在反序列化過程中,必須逐個字元判斷是不是分隔符和行結束符,因此反序列化開銷會比SequenceFile高幾十倍。
2. SequenceFile
Hadoop API提供的一種二進制文件,以的形式序列化到文件中,存儲方式:行存儲。
支持三種壓縮選擇:NONE,RECORD,BLOCK。
Record壓縮率低,一般建議使用BLOCK壓縮。
優勢是文件和hadoop api中的MapFile是相互兼容的。
3. RCFile
存儲方式:數據按行分塊,每塊按列存儲。結合了行存儲和列存儲的優點:
首先,RCFile 保證同一行的數據位於同一節點,因此元組重構的開銷很低;
其次,像列存儲一樣,RCFile 能夠利用列維度的數據壓縮,並且能跳過不必要的列讀取;
RCFile的一個行組包括三個部分:
第一部分是行組頭部的【同步標識】,主要用於分隔 hdfs 塊中的兩個連續行組
第二部分是行組的【元數據頭部】,用於存儲行組單元的信息,包括行組中的記錄數、每個列的位元組數、列中每個域的位元組數
第三部分是【表格數據段】,即實際的列存儲數據。在該部分中,同一列的所有域順序存儲。
從圖可以看出,首先存儲了列 A 的所有域,然後存儲列 B 的所有域等。
數據追加:RCFile 不支持任意方式的數據寫操作,僅提供一種追加介面,這是因為底層的 HDFS當前僅僅支持數據追加寫文件尾部。
行組大小:行組變大有助於提高數據壓縮的效率,但是可能會損害數據的讀取性能,因為這樣增加了 Lazy 解壓性能的消耗。而且行組變大會佔用更多的內存,這會影響並發執行的其他MR作業。 考慮到存儲空間和查詢效率兩個方面,Facebook 選擇 4MB 作為默認的行組大小,當然也允許用戶自行選擇參數進行配置。
4. ORCFile
存儲方式:數據按行分塊 每塊按照列存儲
壓縮快 快速列存取
效率比rcfile高,是rcfile的改良版本
5. 自定義格式
用戶可以通過實現inputformat和 outputformat來自定義輸入輸出格式。
6. 總結:
數據倉庫的特點:一次寫入、多次讀取,因此,整體來看, ORCFile 相比其他格式具有較明顯的優勢。
TextFile 默認格式,載入速度最快,可以採用Gzip、bzip2等進行壓縮,壓縮後的文件無法split,即並行處理
SequenceFile 壓縮率最低,查詢速度一般,三種壓縮格式NONE,RECORD,BLOCK
RCfile 壓縮率最高,查詢速度最快,數據載入最慢。
#
6. 為什麼大數據存儲都喜歡使用 ORC 格式,因為快,小
ORC File,它的全名是Optimized Row Columnar (ORC) file,其實就是對RCFile做了一些優化。據官方文檔介紹,這種文件格式可以提供一種高效的方法來存儲Hive數據。它的設計目標是來克服Hive其他格式的缺陷。運用ORC File可以提高Hive的讀、寫以及處理數據的性能。
在工作中,用的最多的地方是在 Hive 中。我們的數據存儲格式使用的 ORC 。
存儲數據除了考慮安全性, 所佔空間 以及 查詢效率 是直接關繫到我們的業務的。數據量不壓縮,對於大數據團隊來說,集群的磁碟很容易不夠用。數據存進去,我們是要用的,業務方提了一個小需求,你的任務跑了大半個小時,顯然也是不合理的。
這些問題都可以解決掉,但並不是完全解決。
如果我的文章對您有幫助,歡迎關注、轉發。您的支持就是我更新的最大動力。
7. Hive insert 欄位表錯位踩坑
往 Hive 表 insert 數據後,查詢時出現個別行欄位錯位,插入語句如下:
首先測試源表數據查詢:
查詢來的數據沒發現有什麼異常;照理說逐欄位查出來沒問題,再逐欄位插入應該不會錯位。實際上 hive 的 insert 跟想像中傳統的 insert 不太一樣。
由於不是全表錯位,而是個別行錯位,首先根據關鍵字查詢 hive 錯位那行數據,導出文本到本地。肉眼查看發現有部分"亂碼"(異常字元: ^M ,如果經驗豐富一眼就能看出這個是 \001 ,vim 下可以通過組合鍵 ctrl + a 輸出),懷疑是異常字元導致,通過 linux od 命令查看 16 進制編碼,如圖所示:有好幾個 \001 ,多麼眼熟的數字啊 - 這是 hive 默認欄位分隔符。
一般 insert A from select B 我們沒有關注 A 表的欄位分隔符,看到 \001 直覺跟 A 表的欄位分隔符有關:
查看 A 的表結構,欄位分隔符默認的 \001 。存儲類型: textfile 。
進一步分析:textfile 是 hive 默認的存儲結構,行存儲,存儲的實際數據結構跟表邏輯結構一致。導入數據時會直接把數據文件拷貝到 hdfs上不進行處理。源文件可以直接通過hadoop fs -cat 查看; 例如 text 欄位分隔符: \001 , 換行符: \n,表在 hdfs 實際存儲的格式為:
v1\001v2\001v3\n
v4\001v5\001v5
猜測欄位值缺失錯位的根源在於:文本中的不可見字元 \001 插入到表中,而表以 \001 作為欄位分隔符,導致查詢欄位錯位。
再來看這條 SQL:
我們可以還原這條 SQL 從插入到查詢異常的全流程:
第一種方式可行且更加合理;
第二種方式可行,一種補救方案,但是 orc 等格式不支持 load 操作
第三種方式臨時解決問題,不能根本上解決問題;
對 hive 的基礎知識了解不足,導致問題出現排查速度較慢。
數據源頭進行必要的數據 ETL 清洗,對欄位分隔符的處理必須謹慎。
Hive 表盡可能使用 orc parquet 這類存儲方式,空間佔用,查詢效率相對 textfile 有大幅提升,同時可以規避欄位分隔符,錯位等問題。
更深入一步 了解 hive orc 這類存儲方式實現原理。
8. hive的幾種文件格式
hive文件存儲格式包括以下幾類:
1、TEXTFILE
2、SEQUENCEFILE
3、RCFILE
4、ORCFILE(0.11以後出現)
其中TEXTFILE為默認格式,建表時不指定默認為這個格式,導入數據時會直接把數據文件拷貝到hdfs上不進行處理;
SEQUENCEFILE,RCFILE,ORCFILE格式的表不能直接從本地文件導入數據,數據要先導入到textfile格式的表中, 然後再從表中用insert導入SequenceFile,RCFile,ORCFile表中。
前提創建環境:
hive 0.8
創建一張testfile_table表,格式為textfile。
create table if not exists testfile_table( site string, url string, pv bigint, label string) row format delimited fields terminated by ' ' stored as textfile;
load data local inpath '/app/weibo.txt' overwrite into table textfile_table;
一、TEXTFILE
默認格式,數據不做壓縮,磁碟開銷大,數據解析開銷大。
可結合Gzip、Bzip2使用(系統自動檢查,執行查詢時自動解壓),但使用這種方式,hive不會對數據進行切分,
從而無法對數據進行並行操作。
示例:
總結:
相比TEXTFILE和SEQUENCEFILE,RCFILE由於列式存儲方式,數據載入時性能消耗較大,但是具有較好的壓縮比和查詢響應。數據倉庫的特點是一次寫入、多次讀取,因此,整體來看,RCFILE相比其餘兩種格式具有較明顯的優勢。
9. Hive優化之Hive的配置參數優化
Hive是大數據領域常用的組件之一,主要用於大數據離線數倉的運算,關於Hive的性能調優在日常工作和面試中是經常涉及的一個點,因此掌握一些Hive調優是必不可少的一項技能。影響Hive效率的主要因素有數據傾斜、數據冗餘、job的IO以及不同底層引擎配置情況和Hive本身參數和HiveSQL的執行等。本文主要從建表配置參數方面對Hive優化進行講解。
1. 創建一個普通表
table test_user1(id int, name string,code string,code_id string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
2. 查看這張表的信息
DESCRIBE FORMATTED test_user1;
我們從該表的描述信息介紹建表時的一些可優化點。
2.1 表的文件數
numFiles表示表中含有的文件數,當文件數過多時可能意味著該表的小文件過多,這時候我們可以針對小文件的問題進行一些優化,HDFS本身提供了解決方案:
(1)Hadoop Archive/HAR:將小文件打包成大文件。
(2)SEQUENCEFILE格式:將大量小文件壓縮成一個SEQUENCEFILE文件。
(3)CombineFileInputFormat:在map和rece處理之前組合小文件。
(4)HDFS Federation:HDFS聯盟,使用多個namenode節點管理文件。
除此之外,我們還可以通過設置hive的參數來合並小文件。
(1)輸入階段合並
需要更改Hive的輸入文件格式,即參數hive.input.format,默認值是org.apache.hadoop.hive.ql.io.HiveInputFormat,我們改成org.apache.hadoop.hive.ql.io.CombineHiveInputFormat。這樣比起上面對mapper數的調整,會多出兩個參數,分別是mapred.min.split.size.per.node和mapred.min.split.size.per.rack,含義是單節點和單機架上的最小split大小。如果發現有split大小小於這兩個值(默認都是100MB),則會進行合並。具體邏輯可以參看Hive源碼中的對應類。
(2)輸出階段合並
直接將hive.merge.mapfiles和hive.merge.mapredfiles都設為true即可,前者表示將map-only任務的輸出合並,後者表示將map-rece任務的輸出合並,Hive會額外啟動一個mr作業將輸出的小文件合並成大文件。另外,hive.merge.size.per.task可以指定每個task輸出後合並文件大小的期望值,hive.merge.size.smallfiles.avgsize可以指定所有輸出文件大小的均值閾值,默認值都是1GB。如果平均大小不足的話,就會另外啟動一個任務來進行合並。
2.2 表的存儲格式
通過InputFormat和OutputFormat可以看出表的存儲格式是TEXT類型,Hive支持TEXTFILE, SEQUENCEFILE, AVRO, RCFILE, ORC,以及PARQUET文件格式,可以通過兩種方式指定表的文件格式:
(1)CREATE TABLE ... STORE AS <file_format>:在建表時指定文件格式,默認是TEXTFILE
(2)ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT <file_format>:修改具體表的文件格式
如果要改變創建表的默認文件格式,可以使用set
hive.default.fileformat=<file_format>進行配置,適用於所有表。同時也可以使用set
hive.default.fileformat.managed = <file_format>進行配置,僅適用於內部表或外部表。
擴展:不同存儲方式的情況
TEXT,
SEQUENCE和
AVRO文件是面向行的文件存儲格式,不是最佳的文件格式,因為即便只查詢一列數據,使用這些存儲格式的表也需要讀取完整的一行數據。另一方面,面向列的存儲格式(RCFILE,
ORC, PARQUET)可以很好地解決上面的問題。關於每種文件格式的說明,如下:
(1)TEXTFILE
創建表時的默認文件格式,數據被存儲成文本格式。文本文件可以被分割和並行處理,也可以使用壓縮,比如GZip、LZO或者Snappy。然而大部分的壓縮文件不支持分割和並行處理,會造成一個作業只有一個mapper去處理數據,使用壓縮的文本文件要確保文件不要過大,一般接近兩個HDFS塊的大小。
(2)SEQUENCEFILE
key/value對的二進制存儲格式,sequence文件的優勢是比文本格式更好壓縮,sequence文件可以被壓縮成塊級別的記錄,塊級別的壓縮是一個很好的壓縮比例。如果使用塊壓縮,需要使用下面的配置:set
hive.exec.compress.output=true; set io.seqfile.compression.type=BLOCK
(3)AVRO
二進制格式文件,除此之外,avro也是一個序列化和反序列化的框架。avro提供了具體的數據schema。
(4)RCFILE
全稱是Record Columnar File,首先將表分為幾個行組,對每個行組內的數據進行按列存儲,每一列的數據都是分開存儲,即先水平劃分,再垂直劃分。
(5)ORC
全稱是Optimized Row Columnar,從hive0.11版本開始支持,ORC格式是RCFILE格式的一種優化的格式,提供了更大的默認塊(256M)
(6)PARQUET
另外一種列式存儲的文件格式,與ORC非常類似,與ORC相比,Parquet格式支持的生態更廣,比如低版本的impala不支持ORC格式。
配置同樣數據同樣欄位的兩張表,以常見的TEXT行存儲和ORC列存儲兩種存儲方式為例,對比執行速度。
TEXT存儲方式
總結: 從上圖中可以看出列存儲在對指定列進行查詢時,速度更快, 建議在建表時設置列存儲的存儲方式 。
2.3 表的壓縮
對Hive表進行壓縮是常見的優化手段,一些存儲方式自帶壓縮選擇,比如SEQUENCEFILE支持三種壓縮選擇:NONE,RECORD,BLOCK。Record壓縮率低,一般建議使用BLOCK壓縮;
ORC支持三種壓縮選擇:NONE,ZLIB,SNAPPY。我們以TEXT存儲方式和ORC存儲方式為例,查看錶的壓縮情況。
配置同樣數據同樣欄位的四張表,一張TEXT存儲方式,另外三張分別是默認壓縮方式的ORC存儲、SNAPPY壓縮方式的ORC存儲和NONE壓縮方式的ORC存儲,查看在hdfs上的存儲情況:
TEXT存儲方式
默認壓縮ORC存儲方式
SNAPPY壓縮的ORC存儲方式
NONE壓縮的ORC存儲方式
總結 :可以看到ORC存儲方式將數據存放為兩個block,默認壓縮大小加起來134.69M,SNAPPY壓縮大小加起來196.67M,NONE壓縮大小加起來247.55M,TEXT存儲方式的文件大小為366.58M,且默認block兩種存儲方式分別為256M和128M,ORC默認的壓縮方式比SNAPPY壓縮得到的文件還小,原因是ORZ默認的ZLIB壓縮方式採用的是deflate壓縮演算法,比Snappy壓縮演算法得到的壓縮比高,壓縮的文件更小。 ORC不同壓縮方式之間的執行速度,經過多次測試發現三種壓縮方式的執行速度差不多,所以建議採用ORC默認的存儲方式進行存儲數據。
2.4 分桶分區
Num Buckets表示桶的數量,我們可以通過分桶和分區操作對Hive表進行優化:
對於一張較大的表,可以將它設計成分區表,如果不設置成分區表,數據是全盤掃描的,設置成分區表後,查詢時只在指定的分區中進行數據掃描,提升查詢效率。要注意盡量避免多級分區,一般二級分區足夠使用。常見的分區欄位:
(1)日期或者時間,比如year、month、day或者hour,當表中存在時間或者日期欄位時,可以使用些欄位。
(2)地理位置,比如國家、省份、城市等
(3)業務邏輯,比如部門、銷售區域、客戶等等
與分區表類似,分桶表的組織方式是將HDFS上的一張大表文件分割成多個文件。分桶是相對分區進行更細粒度的劃分,分桶將整個數據內容按照分桶欄位屬性值得hash值進行區分,分桶可以加快數據采樣,也可以提升join的性能(join的欄位是分桶欄位),因為分桶可以確保某個key對應的數據在一個特定的桶內(文件),所以巧妙地選擇分桶欄位可以大幅度提升join的性能。通常情況下,分桶欄位可以選擇經常用在過濾操作或者join操作的欄位。
創建分桶表
create
table test_user_bucket(id int, name string,code string,code_id string )
clustered by(id) into 3 buckets ROW FORMAT DELIMITED FIELDS TERMINATED
BY ',';
查看描述信息
DESCRIBE FORMATTED test_user_bucket
多出了如下信息
查看該表的hdfs
同樣的數據查看普通表和分桶表查詢效率
普通表
分桶表
普通表是全表掃描,分桶表在按照分桶欄位的hash值分桶後,根據join欄位或者where過濾欄位在特定的桶中進行掃描,效率提升。
本文首發於: 數棧研習社
數棧是雲原生—站式數據中台PaaS,我們在github上有一個有趣的開源項目: FlinkX
FlinkX是一個基於Flink的批流統一的數據同步工具,既可以採集靜態的數據,比如MySQL,HDFS等,也可以採集實時變化的數據,比如MySQL
binlog,Kafka等,是全域、異構、批流一體的數據同步引擎,大家如果有興趣,歡迎來github社區找我們玩~
10. Hive支持的數據類型
#整型
TINYINT — 微整型,只佔用1個位元組,只能存儲0-255的整數。
SMALLINT– 小整型,佔用2個位元組,存儲范圍–32768 到 32767。
INT– 整型,佔用4個位元組,存儲范圍-2147483648到2147483647。
BIGINT– 長整型,佔用8個位元組,存儲范圍-2^63到2^63-1。
#布爾型
BOOLEAN — TRUE/FALSE
#浮點型
FLOAT– 單精度浮點數。
DOUBLE– 雙精度浮點數。
#字元串型
STRING– 不設定長度。
Structs:一組由任意數據類型組成的結構。比如,定義一個欄位C的類型為STRUCT {a INT; b STRING},則可以使用a和C.b來獲取其中的元素值;
Maps:和Java中的Map相同,即存儲K-V對的;
Arrays:數組;
復雜數據類型的聲明必須使用尖括弧指明其中數據欄位的類型。定義三列,每列對應一種復雜的數據類型,如下所示。
TEXTFILE //文本,默認值
SEQUENCEFILE // 二進制序列文件
RCFILE //列式存儲格式文件 Hive0.6以後開始支持
ORC //列式存儲格式文件,比RCFILE有更高的壓縮比和讀寫效率,Hive0.11以後開始支持
PARQUET //列出存儲格式文件,Hive0.13以後開始支持
#參考博客:
http://lxw1234.com/archives/2015/06/238.htm
http://www.cnblogs.com/zlslch/p/5659714.html
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types
#