⑴ hive建表-指定文件類型和壓縮類型以及欄位分隔符
ORC文件--包含snappy、zlib兩種壓縮格式,不需要配置compress參數
CREATE EXTERNAL TABLE tbl_orc_snappy_comma (
str string,
int1 string)
ROW FORMAT delimited fields terminated by ','
stored as orc tblproperties("orc.compress"="SNAPPY")
⑵ hive 中的壓縮格式 rcfile,textfile,sequencefile 各有什麼區別
TextFile:
Hive默認格式,數據不做壓縮,磁碟開銷大,數據解析開銷大。
可結合Gzip、Bzip2、Snappy等使用(系統自動檢查,執行查詢時自動解壓),但使用這種方式,hive不會對數據進行切分,從而無法對數據進行並行操作。
⑶ 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社區找我們玩~
⑷ 數據倉庫-Hive基礎(七) Hive 的壓縮優化
一般用orc或者parquet
orc
結尾加上 STORED AS orc ,同理,用Parquet模式我們加上 STORED AS PARQUET ;
一般SNAPPY壓縮和解壓縮比比較高,所以一般如果壓縮就用snappy,結尾加上 tblproperties ("orc.compress"="SNAPPY"); 即可
在實際的項目開發當中,hive表的數據存儲格式一般選擇:orc或parquet。壓縮方式一般選 擇snappy。
⑸ hive啟用snappy壓縮為什麼對動態分區表不起效
在桌面上找到「計算機」右鍵單擊,選擇「管理」打開之後,在「存儲」下面有個「磁碟空間管理」然後在下方,磁碟那,你選擇,比如說你要分d盤吧,然後右擊d盤,選擇壓縮卷,然後你自行選擇想壓縮多少空間,點擊壓縮就好了。
⑹ 「Hive進階篇」詳解存儲格式及壓縮方式
hive優化除了有hql語句邏輯優化,hql參數調優等等,還有一個不起眼的細節容易被忽視掉, 那便是hive數倉模型表的存儲格式和壓縮方式 ,hive底層數據是依託在hadoop,以HDFS文件存儲在集群上的, hive數倉模型表選擇一個合適的存儲格式和壓縮方式也是hive優化的一點 。
本篇就來聊一聊這塊知識點吧。😄
hive主要有textfile、sequencefile、orc、parquet 這四種存儲格式,其中sequencefile很少使用,常見的主要就是orc和parquet這兩種,往往也搭配著壓縮方式合理使用。
建表聲明語句是: stored as textfile/orc/parquet
行式存儲,這是hive表的默認存儲格式,默認不做數據壓縮,磁碟開銷大,數據解析開銷大,數據不支持分片(即代表著會帶來無法對數據進行並行操作)
行列式存儲,將數據按行分塊,每個塊按列存儲,其中每個塊都存儲著一個索引,支持none和zlib和snappy這3種壓縮方式,默認採用zlib壓縮方式,不支持切片,orc存儲格式能提高hive表的讀取寫入和處理的性能。
列式存儲,是一個面向列的二進制文件格式(不可直接讀取),文件中包含數據和元數據,所以該存儲格式是自解析的,在大型查詢時效率很快高效,parquet主要用在存儲多層嵌套式數據上提供良好的性能支持,默認採用uncompressed不壓縮方式。
行存儲引擎 :同一條數據的不同欄位都在相鄰位置,所以當要查找某一條記錄所有數據時行存儲查詢速度比較快
列存儲引擎 :以列來聚集數據,相同欄位的值聚集在一起,所以當查詢某一個指定列的所有數據時,列存儲查詢速度比較快
hive主要支持gzip、zlib、snappy、lzo 這四種壓縮方式。
壓縮不會改變元數據的分割性,即壓縮後原來的值不變。
建表聲明語句是: tblproperties("orc.compress"="SNAPPY")
壓縮方式的評判標准主要有以下幾點:
針對壓縮方式做一個小結對比:
⑺ hive使用parquet及壓縮數據大小前後對比
這里提醒一下,是不是說pzrquet加lzo可以把數據壓縮到這個地步,因為我的測試數據存在大量重復。所以下面使用parquet和lzo的壓縮效果特別好。
不可以將txt數據直接載入到parquet的表裡面,需要創建臨時的txt存儲格式的表
然後在創建parquet的表
載入數據
可以看到這里生成了兩個文件,加起來5.52M,可見大大的將原始的txt進行了壓縮
載入數據到emp_parquet_lzo
數據相比較於僅僅使用parquet,數據被進一步的壓縮了。但是這里提醒一下,是不是說pzrquet加lzo可以把數據壓縮到這個地步,因為我的測試數據存在大量重復。
txt文本文件,在使用parquet加壓縮格式,相比較於僅僅使用parquet,可以更進一步的將數據壓縮。
parquet格式支持有四種壓縮,分別是lzo,gzip,snappy,uncompressed,在數據量不大的情況下,四種壓縮的區別也不是太大。
也就是分區下面還可以有分區的,如上面的 partitioned by (dt string,hour string) 在插入數據的時候使用逗號分隔,partition(dt='2020-01-01',hour='01')
首先要聲明一下,我的hive使用的執行引擎是tez,替換了默認的maprece執行引擎。
我們看一下執行頁面,這里可以看到形成了兩個map,這里是map-only,一般數據的載入操作都是map-only的,所以,有多少的map,就會產生幾個文件。
可以是hadoop的maprece不是128M的splitsize嗎,這個文件才74M,為什麼會產出兩個map,這里我們看看tez的執行日誌
從圖片可以看出,這里是tez把74M的文件分成了兩個,這里的52428800是50M,也就是這里的splitsize不是hadoop的mr的默認的128M,而是這里的50M,所以,74M的文件會被分為兩個,一個是50M,一個是24M,.然後我們看上面的emp_parquet的文件,一個式3.7M,也是1.8M,正好和50M和24M的比例是對應的。
⑻ hive 外部表和內部表 數據壓縮上有區別嗎
Hive中內部表與外部表的區別:
Hive
創建內部表時,會將數據移動到數據倉庫指向的路徑;若創建外部表,僅記錄數據所在的路徑,不對數據的位置做任何改變。在刪除表的時候,內部表的元數據和數據會被一起刪除,而外部表只刪除元數據,不刪除數據。這樣外部表相對來說更加安全些,數據組織也更加靈活,方便共享源數據。
需要注意的是傳統資料庫對表數據驗證是
schema
on
write(寫時模式),而
Hive
在load時是不檢查數據是否符合schema的,hive
遵循的是
schema
on
read(讀時模式),只有在讀的時候hive才檢查、解析具體的數據欄位、schema。
讀時模式的優勢是load
data
非常迅速,因為它不需要讀取數據進行解析,僅僅進行文件的復制或者移動。
寫時模式的優勢是提升了查詢性能,因為預先解析之後可以對列建立索引,並壓縮,但這樣也會花費要多的載入時間。
⑼ 大數據開發工程師Hive(Hive如何進行優化)
1數據存儲及壓縮優化
針對hive中表的存儲格式通常有textfile和orc,壓縮格式一般使用snappy。相比於 textfile格式存儲,orc佔有更少的存儲。因為hive底層使用MR計算架構,數據流是hdfs到磁碟再到hdfs,而且會有很多次IO讀寫操作,所以使用orc數據格式和snappy壓縮策略可以降低IO讀寫,還能降低網路傳輸量,這樣在一定程度上可以節省存儲空間,還能提升hql的執行效率;
2 Hive Job優化
①調節Jvm參數,重用Jvm;
②合理設置Map個數;
③合理設置Rece個數;
3 Sql語法優化
① 建表優化 :
1) Hive創建表的時候,可以建分區表,分桶表;
2) Hive創建表的時候,可以指定數據存儲格式:TextFile、SequenceFile、RCfile 、ORCfile;
② 查詢時優化 :
1) 列裁剪,在查詢時只讀取需要的列,避免全列掃描,不要使用select * from table;
2) 分區裁剪:在查詢時只讀取需要分區的數據,避免全表掃描;
3) 開啟謂詞下推:set hive.optimize.ppd = true,默認是true:
a. 將Sql語句中的where謂詞邏輯都盡可能提前執行,減少下游處理的數據量;
4) 大表join小表:
a. 開啟MapJoin:set hive.auto.convert.join=true:
b. MapJoin是將Join雙方比較小的那個表直接分發到各個Map進程的內存中,在 Map進程中進行Join操作, 這樣就不用進行Rece步驟 ,從而提高了速度( 大表left join小表才有效 ,小表left join大表會失效);
5) 大表join大表:
a. SMB Join :Sort Merge Bucket Join(數據不僅分桶了,而且每個桶數據是排好序了);
b. 開啟SMB Join之後,底層是根據兩個表join欄位進行分桶存儲,這樣的話,兩張表就變為了基於桶之間join關聯查詢,而不是基於整張表的join,減少了笛卡爾積;
6) 少用in,用left semi join替代in:
a. 原始寫法:select a.id, a.name from a where a.id in (select b.id from b);
b. 用join改寫:select a.id, a.name from a join b on a.id = b.id;
c. left semi join改寫:select a.id, a.name from a left semi join b on a.id = b.id;
7) 用union all代替union,因為union all不需要去重,也不需要排序,效率高於union;
(每天1小題,進步1點點)
⑽ hive下導入數據,生成表後的壓縮率大致有多大
hive不做壓縮的,只是在hdfs中移動數據,或是從本地文件系統移動到hdfs。原來是多大就是多大。
如果要壓縮,可以先壓縮好再導入,hive是不會替你做這步的。hive支持gz格式和lzo格式。gz格式原生支持。lzo格式需要某個特殊的serde。