Hadoop資料模型

今夕何夕-l發表於2020-09-24

Text

1.概念:文字檔案通常採用CSV、JSON等固度長度的純文字格式
2.優點:
①便於與其他應用程式(生成或分割檔案)或指令碼進行資料交換
②易讀性好,便於理解
3.缺點:
①資料儲存量非常龐大
②查詢效率不高
③不支援塊壓縮

SequenceFile

1.概念:
①SequenceFile按行儲存二進位制鍵值對資料,HDFS自帶
②二進位制檔案直接將<Key,Value>序列化到檔案中
③常用於在MapReduce作業之間傳輸資料
④可用作Hadoop中小檔案的打包存檔(小檔案合併)
⑤即使在壓縮資料時也支援分割
2.鍵值對型別
SequenceFile中的Key和Value可以是任意型別的Writable(org.apache.hadoop.io.Writable)
3.Java API

org.apache.hadoop.io.SequenceFile

4.儲存結構
①記錄結構:
在這裡插入圖片描述
②塊結構:
在這裡插入圖片描述

5.壓縮
①記錄級(record):
在這裡插入圖片描述

②塊級(block)
在這裡插入圖片描述
6.讀寫操作
①寫檔案(指定為塊壓縮):

SequenceFile.Writer

②讀檔案(讀取時能自動解壓):

SequenceFile.Reader

③檢視檔案內容:

hdfs dfs -text myseqfile.seq

7.hive中使用SequenceFile
①直接指定:

STORED AS sequencefile

②顯示指定:

STORED AS INPUTFORMAT   'org.apache.hadoop.mapred.SequenceFileInputFormat' 
OUTPUTFORMAT  'org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat'

Avro

1.概念:
Apache Avro是一個資料序列化系統,出自Hadoop之父Doug Cutting

2.Avro File:
①以JSON格式儲存資料定義(Schema)
②以二進位制格式儲存資料

3.特點:
①豐富的資料結構
②快速可壓縮的二進位制資料格式
③容器檔案用於持久化資料
④自帶遠端過程呼叫RPC
⑤動態語言可以方便地處理Avro資料

4.資料型別
①基本資料型別
null, boolean, int, long, float, double, bytes, string
②複雜資料型別
record,enum,array,map,union,fixed

5.avro-tools的應用
①使用schema+data生成avro檔案

java -jar avro-tools-1.8.2.jar fromjson --schema-file user.avsc user.json > user.avro
java -jar avro-tools-1.8.2.jar fromjson --codec snappy --schema-file user.avsc user.json > user.avro

②avro轉json

java -jar avro-tools-1.8.2.jar tojson user.avro
java -jar avro-tools-1.8.2.jar tojson user.avro --pretty

③獲取avro後設資料

java -jar avro-tools-1.8.2.jar getmeta user.avro

6.avro檔案儲存結構
從頭到尾:Header->Sync Marker->Block->Sync Marker->Block->Sync Marker
其中明細
①Header:
在這裡插入圖片描述
②Sync Marker:16 bytes ID
③Block:
在這裡插入圖片描述
7.在Hive中使用Avro

hive> create table CUSTOMERS 
> row format serde 'org.apache.hadoop.hive.serde2.avro.AvroSerDe' 
> stored as inputformat 'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat' 
> outputformat 'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat' 
> tblproperties ('avro.schema.literal'='{"name": "customer", "type": "record", "fields": [ 
> {"name":"firstName", "type":"string"}, {"name":"lastName", "type":"string"}, 
> {"name":"age", "type":"int"}, {"name":"salary", "type":"double"}, 
> {"name":"department", "type":"string"}, {"name":"title", "type":"string"},
> {"name": "address", "type": "string"}]}'); 
create external table user_avro_ext(name string,favorite_number int,favorite_color string) 
stored as avro location '/tmp/avro';

Parquet

1.概念:Apache Parquet是Hadoop生態系統中任何專案都可用的列式儲存格式,由Twitter和Cloudera合作開發
Parquet格式是Spark SQL預設資料來源(spark.sql.sources.default)

2.列式儲存優點:
①按需讀取列
②壓縮編碼可以降低磁碟儲存空間

3.Parquet檔案結構
按照行將資料物理上劃分為多個組,每一個行組包含一定的行數,通常行組大小等於HDFS塊大小
①行組Row Group
②列塊Column Chunk
③頁Page
在這裡插入圖片描述
4.Parquet Schema

message User{
    required binary name (UTF8);
    required int32 age;
    repeated group family{
        repeated binary father (UTF8);
        repeated binary mother (UTF8);
        optional binary sister (UTF8);
    }
}

5.Parquet Java API
①ParquetWriter

MessageType schema=MessageTypeParser
                             .parseMessageType(schemaStr);
ParquetWriter<Group> writer=ExampleParquetWriter
                             .builder(file).withType(schema).build();
SimpleGroupFactory groupFactory 
                             = new SimpleGroupFactory(schema);
Group group1=groupFactory.newGroup();
group1.add("name","jason");
group1.add("age",9);
gropu1.addGroup("family").append("father","XXX")
                                                   .append("mother","XXX");
writer.write(group1);

②ParquetReader

ParquetReader<Group> reader = ParquetReader
                         .builder(new GroupReadSupport(), file)
                         .build();
SimpleGroup group =(SimpleGroup) reader.read();
System.out.println("schema:" +     
                                                     group.getType().toString());
System.out.println(group.toString());

6.在Hive中使用Parquet格式儲存

create external table parquet_table(name string,age int) 
stored as parquet 
location '/tmp/parquet';

儲存過程:
在這裡插入圖片描述

RC & ORC

1.RC(Record Columnar)
由Facebook開源
特點:
①儲存行集合,並在集合中以列格式儲存行資料
②引入輕量級索引,允許跳過不相關的行塊
③可分割:允許並行處理行集合
④可壓縮

2.ORC(Optimized Row Columnar)
RC優化版
3.RCFile儲存結構
①集行儲存與列儲存的優點於一身
②設計思想與Parquet類似,先按行水平切割為多個行組,再對每個行組內的資料按列儲存
在這裡插入圖片描述

4.ORCFile儲存結構
①Stripe
(1)每個ORC檔案首先會被橫向切分成多個Stripe
(2)每個stripe預設的大小是250MB
(3)每個stripe由多組(Row Groups)行資料組成
②IndexData
儲存了該stripe上資料的位置,總行數
③RowData
以stream的形式儲存資料
④Stripe Footer
包含該stripe統計結果:Max,Min,count等資訊
⑤FileFooter
(1)該表的統計結果
(2)各個Stripe的位置資訊
⑥Postscript
該表的行數,壓縮引數,壓縮大小,列等資訊
在這裡插入圖片描述

5.Java讀寫ORCFile
①TypeDescription

TypeDescription schema = TypeDescription.fromString("struct<name:string,age:int>");

②VectorizedRowBatch

public class VectorizedRowBatch implements Writable {
	public int numCols; // 列數
	public ColumnVector[] cols; // 每一列的列向量
	public int size; // 行數
...}
VectorizedRowBatch batch=schema.createRowBatch();

③BytesColumnVector

BytesColumnVector name =(BytesColumnVector) batch.cols[0];
name.setVal(0,"jason".getBytes());

④Writer

Writer writer = OrcFile.createWriter(file,OrcFile.writerOptions(conf).setSchema(schema));

⑤Read

Reader reader=OrcFile.createReader(file,OrcFile.readerOptions(conf));
RecordReader rows = reader.rows();
VectorizedRowBatch batch = reader.getSchema().createRowBatch();
while (rows.nextBatch(batch)) {...}

6.在Hive中使用ORCFile儲存格式

create external table user_orc_ext(
name string,
age int
) 
stored as orc 
location '/tmp/users/orc'

儲存過程:
在這裡插入圖片描述

儲存格式的選擇

1.寫
一般寫入時間並不是最重要
2.讀
①Avro——查詢隨時間變化的資料集
②Parquet ——適合在寬表上查詢少數列
③Parquet & ORC以犧牲寫效能為代價優化讀取效能
④TextFile讀起來很慢
3.Hive 查詢(快->慢)
ORC -> Parquet -> Text -> Avro -> SequenceFile
4.檔案儲存格式比較(總結)
在這裡插入圖片描述

相關文章