背景:列式存儲和行式存儲,首先看一下表數據存儲格式:
字段A | 字段B | 字段C |
---|---|---|
A1 | B1 | C1 |
A2 | B2 | C2 |
A3 | B3 | C3 |
A4 | B4 | C4 |
A5 | B5 | C5 |
-
如果上述表數據存儲為列式存儲,存儲數據文件如下
A1B1C1 A2B2C2 A3B3C3 A4B4C4 A5B5C5
-
如果上述表數據存儲為行式存儲,存儲數據文件如下
A1A2A3A4A5 B1B2B3B4B5 C1C2C3C4C5
根據上述列式和行式數據存儲文件格式,優缺點對比如下
- 行式存儲
- 優點
- 相關的數據是保存在一起,比較符合面向對象的思維,因為一行數據就是一條記錄
- 這種存儲格式比較方便進行INSERT/UPDATE操作
- 缺點
- 如果查詢只涉及某幾個列,它會把整行數據都讀取出來,不能跳過不必要的列讀取。當然數據比較少,一般沒啥問題,如果數據量比較大就比較影響性能
- 由於每一行中,列的數據類型不一致,導致不容易獲得一個極高的壓縮比,也就是空間利用率不高
- 不是所有的列都適合作為索引
- 優點
- 列式存儲
- 優點
- 查詢時,只有涉及到的列才會被查詢,不會把所有列都查詢出來,即可以跳過不必要的列查詢
- 高效的壓縮率,不僅節省儲存空間也節省計算內存和CPU
- 任何列都可以作為索引
- 缺點
- INSERT/UPDATE很麻煩或者不方便
- 不適合掃描小量的數據
- 優點
hive文件存儲格式包含以下幾類:
- TEXTFILE
- SEQUENCEFILE
- RCFILE
- ORCFILE(0.11以后出現)
其中TEXTFILE為默認格式,建表時不指定默認為這個格式,導入數據時會直接把數據文件拷貝到hdfs上不進行處理;SEQUENCEFILE,RCFILE,ORCFILE格式的表不能直接從本地文件導入數據,數據要先導入到textfile格式的表中,然后再從表中用insert導入SequenceFile,RCFile,ORCFile表中。首先創建一張source_table表,格式為textfile。
create table source_table(id int,name string, age int) row format delimited fields terminated by ',' stored as textfile;
測試數據如下
1,user1,22
2,user2,28
3,user3,22
4,user4,23
5,user5,25
6,user6,24
7,user7,20
8,user8,18
9,user9,16
10,user10,18
導入測試數據到source_table表中
hadoop fs -put source_table.txt /tmp
load data inpath '/root/data/hive/source_table.txt' into table source_table;
TEXTFILE存儲格式
-
hive數據存儲默認文件格式;
-
存儲方式為行存儲;
-
數據不做壓縮,磁盤開銷大,數據解析資源消耗大;
-
可以結合Gzip、Bzip2使用(系統自動檢測,執行查詢時自動解壓),但是使用這種方式hive不會對數據進行切分,從而無法對數據進行並行操作。
create table if not exists textfile_table( id int, name string, age int) row format delimited fields terminated by ',' stored as textfile;
插入數據操作(map、reduce輸出壓縮),Gzip和Bzip2壓縮格式是Hadoop支持的壓縮格式,而且Linux本地的庫也支持這種壓縮和解壓。
set hive.exec.compress.output=true; set mapred.output.compress=true; set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec; set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec; insert overwrite table textfile_table select * from source_table;
SEQUENCEFILE存儲格式
-
Hadoop API提供的一種二進制文件,以key-value的形式序列化到文件中;
-
存儲方式為行存儲;
-
其具有使用方便、可分割、可壓縮的特點;
-
SequenceFile支持三種壓縮選擇:NONE,RECORD,BLOCK。Record壓縮率低,一般建議使用BLOCK壓縮。
-
壓縮數據文件可以節省磁盤空間,但Hadoop中有些原生壓縮文件的缺點之一就是不支持分割。支持分割的文件可以並行的有多個mapper程序處理大數據文件,大多數文件不支持可分割是因為這些文件只能從頭開始讀。Sequence File是可分割的文件格式,支持Hadoop的block級壓縮。
create table if not exists seqfile_table( id int, name string, age int) row format delimited fields terminated by ',' stored as sequencefile;
插入數據操作
set hive.exec.compress.output=true; set mapred.output.compress=true; set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec; set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec; SET mapred.output.compression.type=BLOCK; insert overwrite table seqfile_table select * from source_table;
RCFILE存儲格式
RCFile是一種行列存儲相結合的存儲方式。首先將數據按行分塊,保證同一個record在一個塊上,避免讀一個記錄需要讀取多個block;其次塊數據列式存儲,有利於數據壓縮和快速列存取。
create table if not exists rcfile_table(
id int,
name string,
age int)
row format delimited fields terminated by ','
stored as rcfile;
插入數據操作
set hive.exec.compress.output=true;
set mapred.output.compress=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;
insert overwrite table rcfile_table select * from source_table;
相比TEXTFILE和SEQUENCEFILE,RCFILE由於列式存儲方式,數據加載時性能消耗較大,但是具有較好的壓縮比和查詢響應。數據倉庫的特點是一次寫入、多次讀取,因此,整體來看,RCFILE相比其余兩種格式具有較明顯的優勢。
ORCFILE存儲格式
orcfile就是OptimizedRC File的縮寫。意指優化的RCFile存儲格式。hive/spark都支持這種存儲格式,它存儲的方式是采用數據按照行分塊,每個塊按照列存儲,其中每個塊都存儲有一個索引。特點是數據壓縮率非常高。