Hive文件與記錄格式


1. Hive文件與記錄格式

Create table 有多種用法,例如STORED AS SEQUENCEFILE, ROW FORMAT DELIMITED, SERDE, INPUTFORMAT, OUTPUTFORMAT 這些語法。

某些語法是其他語法的快捷用法,例如:

語法 STORED AS SEQUENCEFILE 的替代方式是:指定INPUTFORMAT org.apache.hadoop.mapred.SequenceFileInputFormat,並指定 OUTPUTFORMAT org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat

 

下面創建一些表,然后使用 DESCRIBE TABLE EXTENDED 語句查看下內部實際變化情況。首先創建一個簡單表:

> create table text(x int);

hive> describe extended text;

OK

x                       int

 

Detailed Table Information     

Table(tableName:text, dbName:default, owner:hadoop, createTime:1559016716, lastAccessTime:0, retention:0,

sd:StorageDescriptor(

cols:[FieldSchema(name:x, type:int, comment:null)],

location:hdfs://ip-10-0-2-70.cn-north-1.compute.internal:8020/user/hive/warehouse/text,

inputFormat:org.apache.hadoop.mapred.TextInputFormat,

outputFormat:org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat,

compressed:false,

numBuckets:-1,

serdeInfo:SerDeInfo(

name:null,

serializationLib:org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe,

parameters:{serialization.format=1}

),

bucketCols:[], sortCols:[], parameters:{},

skewedInfo:SkewedInfo(

skewedColNames:[], skewedColValues:[], skewedColValueLocationMaps:{}

),

storedAsSubDirectories:false),

partitionKeys:[], parameters:{totalSize=0, numRows=0, rawDataSize=0, COLUMN_STATS_ACCURATE={"BASIC_STATS":"true"}, numFiles=0, transient_lastDdlTime=1559016716},

viewOriginalText:null, viewExpandedText:null, tableType:MANAGED_TABLE, rewriteEnabled:false)

Time taken: 0.132 seconds, Fetched: 3 row(s)

 

然后再使用 STORED AS DEQUENCEFILE 語句創建一張表,用於對比:

> create table seq(x int) stored as sequencefile;

> describe extended seq;

OK

x                       int

 

Detailed Table Information     

Table(tableName:seq, dbName:default, owner:hadoop, createTime:1559017290, lastAccessTime:0, retention:0,

sd:StorageDescriptor(

cols:[FieldSchema(name:x, type:int, comment:null)],

location:hdfs://ip-10-0-2-70.cn-north-1.compute.internal:8020/user/hive/warehouse/seq,

inputFormat:org.apache.hadoop.mapred.SequenceFileInputFormat,

outputFormat:org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat,

compressed:false, numBuckets:-1,

serdeInfo:SerDeInfo(

name:null, serializationLib:org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe,

parameters:{serialization.format=1}

),

bucketCols:[], sortCols:[], parameters:{},

skewedInfo:SkewedInfo(

skewedColNames:[], skewedColValues:[], skewedColValueLocationMaps:{}

),

storedAsSubDirectories:false

),

partitionKeys:[], parameters:{totalSize=0, numRows=0, rawDataSize=0, COLUMN_STATS_ACCURATE={"BASIC_STATS":"true"}, numFiles=0, transient_lastDdlTime=1559017290}, viewOriginalText:null, viewExpandedText:null, tableType:MANAGED_TABLE, rewriteEnabled:false)

 

兩者差異很明顯:STORED AS SEQUENCEFILE 與默認的InputFormat OutputFormat的值不一樣:

inputFormat:org.apache.hadoop.mapred.TextInputFormat,

outputFormat:org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat,

 

inputFormat:org.apache.hadoop.mapred.SequenceFileInputFormat,

outputFormat:org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat,

 

在從表中讀取數據時,Hive 會使用InputFormat,在向表寫入數據時,會使用OutputFormatInputFormat會從文件中讀取key-value對。默認情況下,Hive會直接忽略掉key的內容,而是只有value中的數據。因為key來自於TextInputFormat,是每行的字節偏移量,並不是用戶的數據。

 

2.文件格式

Hive中最簡單的數據格式是文本文件格式,可以使用任意分隔符進行分割,同時它也是默認的文件格式,等價於:在創建時通過STORED AS TEXTFILE 語句指定使用文本存儲格式

文本文件便於與其他工具共享數據,也便於查看和編輯。不過,相對於二進制文件,文本文件存儲的空間要大。我們可以使用壓縮,但是如果使用二進制文件存儲格式的話,則既可以節約存儲空間,也可以提高I/O性能。

 

2.1 SequenceFile

其中一種存儲格式是SequenceFile文件存儲格式,在定義表結構時可以通過STORED AS SEQUENCEFILE 語句指定。SequenceFile Hadoop生態系統中支持的標准文件格式,可以在塊級別和記錄級別進行壓縮,這對於優化磁盤利用率和I/O來說非常有意義。同時仍然可以支持按照塊級別的文件分割,以方便並行處理。Hive 所支持的另一個高效二進制文件是RCFile

 

2.2 RCFile

大多數HadoopHive都是行式存儲的,大多數場景下,這是比較高效的。高效的原因有:

1.     大多數的表具有的字段個數都不大(一般120個字段)

2.     對文件按塊進行壓縮對於需要處理重復數據的情況比較高

3.     很多的處理和調試工具(例如moreheadawk)都可以很好地應用於行式存儲數據

但是對於某些特定類型的數據和應用,列式存儲會更適用。例如,表中有成百上千個字段,但是大多數查詢僅使用其中小部分字段,這時掃描所有的行和過濾掉大部分數據顯然是很浪費的。如果數據存儲是列式存儲,那么僅掃描需要的列數據就可以提高性能。

對於列式存儲,進行壓縮通常會非常高效,特別是在這列的數據具有較低計數的時候。同時,一些列式存儲並不需要物理存儲null值的列。

基於這些場景,Hive中設計了RCFile

Hive 另外一個優點是:可以很容易地在不同的存儲格式間轉換數據。對一個表執行一個SELECT查詢時,或是向表寫入執行INSERT操作時,Hive會使用這個表的metadata信息,自動執行轉換過程,而不需要額外的程序來對不同存儲格式進行轉換。

這里我們舉一個例子,首先使用ColumarSerDeRCFileInputFormatRCFileOutputFormat參數創建表:

> select * from a;

OK

4       5

3       2

 

> create table columnTable(key int, value int)

> ROW FORMAT SERDE

> 'org.apache.hadoop.hive.serde2.columnar.ColumnarSerDe'

> STORED AS

> INPUTFORMAT 'org.apache.hadoop.hive.ql.io.RCFileInputFormat'

> OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.RCFileOutputFormat';

OK

 

hive> FROM a INSERT OVERWRITE TABLE columnTable SELECT a.key, a.value;

 

對於 RCFile 來說,無法使用通常工具打開RCFile,也無法使用通常打開SequenceFile的工具打開。例如:

>cat 000000_0

RCF    hive.io.rcfile.column.number2Ч];E3:'c
     
  
4352

 

不過Hive 提供了一個rcfilecat工具,用於展示RCFile文件內容:

> hive --service rcfilecat /user/hive/warehouse/columntable/000000_0

4       5

3       2

 

3. 記錄格式:SerDe

SerDeSerializer/Deserializer的簡稱。一個SerDe允許Hive從一個表讀入數據,並以任意用戶定義的格式寫回HDFS。它包含了將一條記錄的非結構化數據轉化成Hive可以使用的一條記錄的過程。

Hive SerDe 庫在 org.apache.hadoop.hive.serde2 中(舊版本的SerDe 庫在 org.apache.hadoop.hive.serde中,已經被棄用),它本身包含了一些內置的SerDes,如:

1.     AvroHive 0.9.1 及之后版本)

2.     ORCHive 0.11 及之后版本)

3.     RegEx

4.     Thrift

5.     ParquetHive 0.13及之后版本)

6.     CSVHive 0.14及之后版本)

7.     JsonSerDeHive 0.12 及之后版本,在hcatalog-core中)

需要注意的是:在Hive 0.12 之前的發行版中,Amazon提供了一個JSON SerDe,位於s3://elasticmapreduce/samples/hive-ads/libs/jsonserde.jar

也有用戶定義的SerDes,不過需要用戶實現,或是使用第三方的SerDe

 

SerDe的用途與過程有以下三點:

·       Hive 使用SerDe(以及FileFormat)讀寫表中的行

·       HDFS文件 --> InputFormat --> <key, value> --> Deserializer --> Row object

·       Row object --> Serializer --> <key, value> --> OutputFormat --> HDFS files

這里需要注意的是:這里的key部分在讀入后是被忽略掉的(因為key來自於TextInputFormat,是每行的字節偏移量,並不是用戶的數據),基本上行對象是存在value中的。

 

在內部,Hive 引擎使用定義的InputFormat來讀取一行條目,然后此記錄會被傳遞給SerDe.Deserializer() 方法進行處理。

 

JSON SerDe為例,如果用戶想使用Hive 查詢JSON格式的數據。若是不使用SerDe,且每行為一個json“文件”的話,則可以在使用TextInputFormat 讀入,然后使用一個JSONSerDe JSON文檔作為一條記錄進行解析。例如:

   >  create external table messages(

    >    id int,

    >    message string

    >   )

    >   row format serde "org.apache.hive.hcatalog.data.JsonSerDe"

    >  location 's3://tang-emr/jsonserde/'

>  ;

 

JSON數據為:

{"id":1,"message":"yep"}

{"id":2,"message":"asdf"}

{"id":3,"message":"cddacddc","fa":"asf"}

 

hive> select * from messages;

OK

1       yep

2       asdf

3       cddacddc

 

 

References:

1. Hive 編程指南

2. https://cwiki.apache.org/confluence/display/Hive/SerDe
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM