成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一文讀懂Hive底層數據存儲格式

大數據 數據分析
Parquet 表支持 Uncompress、Snappy、Gzip、Lzo 壓縮,默認不壓縮(Uncompressed)。其中 Lzo 壓縮是支持切分的,所以在表的單個文件較大的場景會選擇 Lzo 格式。

本文講解 Hive 的數據存儲,是 Hive 操作數據的基礎。選擇一個合適的底層數據存儲文件格式,即使在不改變當前 Hive SQL 的情況下,性能也能得到數量級的提升。這種優化方式對學過 MySQL 等關系型數據庫的小伙伴并不陌生,選擇不同的數據存儲引擎,代表著不同的數據組織方式,對于數據庫的表現會有不同的影響。

Hive 數據存儲常用的格式如下:

  • 行式存儲:文本格式(TextFile)二進制序列化文件 (SequenceFile)
  • 列式存儲:行列式文件(RCFile)優化的行列式文件(ORCFile)Apache Parquet

注:RCFile 和 ORCFile 并不是純粹的列式存儲,它是先基于行對數據表進行分組(行組),然后對行組進行列式存儲

我們看下這幾種存儲結構的優缺點:

水平的行存儲結構:

行存儲模式就是把一整行存在一起,包含所有的列,這是最常見的模式。這種結構能很好的適應動態的查詢。

比如:select a from tableA 和 select a, b, c, d, e, f, g from tableA這樣兩個查詢其實查詢的開銷差不多,都需要把所有的行讀進來過一遍,拿出需要的列。

而且這種情況下,屬于同一行的數據都在同一個 HDFS 塊上,重建一行數據的成本比較低。

但是這樣做有兩個主要的弱點:

  • 當一行中有很多列,而我們只需要其中很少的幾列時,我們也不得不把一行中所有的列讀進來,然后從中取出一些列。這樣大大降低了查詢執行的效率。
  • 基于多個列做壓縮時,由于不同的列數據類型和取值范圍不同,壓縮比不會太高。

垂直的列存儲結構:

列存儲是將每列單獨存儲或者將某幾個列作為列組存在一起。列存儲在執行查詢時可以避免讀取不必要的列。而且一般同列的數據類型一致,取值范圍相對多列混合更小,在這種情況下壓縮數據能達到比較高的壓縮比。

但是這種結構在重建行時比較費勁,尤其當一行的多個列不在一個 HDFS 塊上的時候。比如我們從第一個 DataNode 上拿到 column A,從第二個 DataNode 上拿到了 column B,又從第三個 DataNode 上拿到了 column C,當要把 A,B,C 拼成一行時,就需要把這三個列放到一起重建出行,需要比較大的網絡開銷和運算開銷。

混合的 PAX 存儲結構:

PAX 結構是將行存儲和列存儲混合使用的一種結構,主要是傳統數據庫中提高 CPU 緩存利用率的一種方法,并不能直接用到 HDFS 中。但是 RCFile 和 ORC 是繼承自它的思想,先按行存再按列存。

接下來我們看下在 Hive 中常用的幾種存儲格式:

本文重點講解最后兩種:Apache ORC 和 Apache Parquet,因為它們以其高效的數據存儲和數據處理性能得以在實際的生產環境中大量運用。

一、TextFile

TextFile 為 Hive 默認格式,建表時不指定則默認為這個格式,導入數據時會直接把數據文件拷貝到 hdfs 上不進行處理。

創建一個 TextFile 格式的 Hive 表:

create table if not exists textfile_table
(
    ueserid STRING,
    movieid STRING,
    rating STRING,
    ts STRING
)
row formated delimated fields terminated by '\t'
stored as textfile;  -- 可不指定(默認格式)

向 TextFile 表中加載數據:

load data local inpath "/root/rating.csv" overwrite into table textfile_table

TextFile 優缺點:

TextFile 格式因為不對導入的數據文件做處理,所以可以直接使用 load 方式加載數據,其他存儲格式則不能使用 load 直接導入數據文件。所以 TextFile 的加載速度是最高的。

TextFile 格式雖然可以使用 Gzip 壓縮算法,但壓縮后的文件不支持 split。在反序列化過程中,必須逐個字符判斷是不是分隔符和行結束符,因此反序列化開銷會比 SequenceFile 高幾十倍。

二、SequenceFile

SequenceFile 是 Hadoop API 提供的一種二進制文件支持,其具有使用方便、可分割、可壓縮的特點。

SequenceFIle 的內部格式取決于是否啟用壓縮,如果是壓縮,則又可以分為記錄壓縮和塊壓縮。

無壓縮(NONE):如果沒有啟用壓縮(默認設置)那么每個記錄就由它的記錄長度(字節數)、鍵的長度,鍵和值組成。長度字段為 4 字節。

記錄壓縮(RECORD):記錄壓縮格式與無壓縮格式基本相同,不同的是值字節是用定義在頭部的編碼器來壓縮。注意:鍵是不壓縮的。

塊壓縮(BLOCK):塊壓縮一次壓縮多個記錄,因此它比記錄壓縮更緊湊,而且一般優先選擇。當記錄的字節數達到最小大小,才會添加到塊。該最小值由 io.seqfile.compress.blocksize 中的屬性定義。默認值是 1000000 字節。格式為記錄數、鍵長度、鍵、值長度、值。Record 壓縮率低,一般建議使用 BLOCK 壓縮。

創建一個 SequenceFile 格式的 Hive 表:

create table if not exists seqfile_table
(
    ueserid STRING,
    movieid STRING,
    rating STRING,
    ts STRING
)
row format delimited
fields terminated by '\t'
stored as sequencefile;

設置壓縮格式為塊壓縮:

set mapred.output.compression.type=BLOCK;

向 SequenceFile 表中加載數據:

insert overwrite table seqfile_table select * from textfile_table;

SequenceFile 優點:

  • 支持基于記錄(Record)或塊(Block)的數據壓縮。
  • 支持 splitable,能夠作為 MapReduce 的輸入分片。
  • 修改簡單:主要負責修改相應的業務邏輯,而不用考慮具體的存儲格式。

SequenceFile 的缺點:

  • 需要一個合并文件的過程,且合并后的文件不方便查看。

三、RCFile

RCFile 文件格式是 FaceBook 開源的一種 Hive 的文件存儲格式,首先將表分為幾個行組,對每個行組內的數據進行按列存儲,每一列的數據都是分開存儲,正是先水平劃分,再垂直劃分的理念。

圖片圖片

首先對表進行行劃分,分成多個行組。一個行組主要包括:

  • 16 字節的 HDFS 同步塊信息,主要是為了區分一個 HDFS 塊上的相鄰行組;
  • 元數據的頭部信息主要包括該行組內的存儲的行數、列的字段信息等等;
  • 數據部分我們可以看出 RCFile 將每一行,存儲為一列,將一列存儲為一行,因為當表很大,我們的字段很多的時候,我們往往只需要取出固定的一列就可以。

在一般的行存儲中 select a from table,雖然只是取出一個字段的值,但是還是會遍歷整個表,所以效果和 select * from table 一樣,在 RCFile 中,像前面說的情況,只會讀取該行組的一行。

創建一個 RCFile 的表:

create table if not exists rcfile_table
(
    ueserid STRING,
    movieid STRING,
    rating STRING,
    ts STRING
)
row format delimited fields terminated by '\t'
stored as rcfile;

在存儲空間上:

RCFile 是行劃分,列存儲,采用游程編碼,相同的數據不會重復存儲,很大程度上節約了存儲空間,尤其是字段中包含大量重復數據的時候。

懶加載:

數據存儲到表中都是壓縮的數據,Hive 讀取數據的時候會對其進行解壓縮,但是會針對特定的查詢跳過不需要的列,這樣也就省去了無用的列解壓縮。

如:

select c from table where a>1;

針對行組來說,會對一個行組的 a 列進行解壓縮,如果當前列中有 a>1 的值,然后才去解壓縮 c。若當前行組中不存在 a>1 的列,那就不用解壓縮 c,從而跳過整個行組。

四、ORCFile

1. ORC相比較 RCFile 的優點

ORC 是在一定程度上擴展了 RCFile,是對 RCFile 的優化:

  1. ORC 擴展了 RCFile 的壓縮,除了 Run-length(游程編碼),引入了字典編碼和 Bit 編碼。
  2. 每個 task 只輸出單個文件,這樣可以減少 NameNode 的負載;
  3. 支持各種復雜的數據類型,比如:datetime,decimal,以及一些復雜類型(struct, list, map,等);
  4. 文件是可切分(Split)的。在 Hive 中使用 ORC 作為表的文件存儲格式,不僅節省 HDFS 存儲資源,查詢任務的輸入數據量減少,使用的 MapTask 也就減少了。

采用字典編碼,最后存儲的數據便是字典中的值,及每個字典值的長度以及字段在字典中的位置;采用 Bit 編碼,對所有字段都可采用 Bit 編碼來判斷該列是否為 null, 如果為 null 則 Bit 值存為 0,否則存為 1,對于為 null 的字段在實際編碼的時候不需要存儲,也就是說字段若為 null,是不占用存儲空間的。

2. ORC的基本結構

ORCFile 在 RCFile 基礎上引申出來 Stripe 和 Footer 等。每個 ORC 文件首先會被橫向切分成多個 Stripe,而每個 Stripe 內部以列存儲,所有的列存儲在一個文件中,而且每個 stripe 默認的大小是 250MB,相對于 RCFile 默認的行組大小是 4MB,所以比 RCFile 更高效。

下圖是 ORC 的文件結構示意圖:

圖片圖片

ORC 文件結構由三部分組成:

  • 條帶(stripe):ORC 文件存儲數據的地方。
  • 文件腳注(file footer):包含了文件中 stripe 的列表,每個 stripe 的行數,以及每個列的數據類型。它還包含每個列的最小值、最大值、行計數、 求和等聚合信息。
  • postscript:含有壓縮參數和壓縮大小相關的信息。

stripe 結構同樣可以分為三部分:index data、rows data 和 stripe footer:

  • index data:保存了所在條帶的一些統計信息,以及數據在 stripe 中的位置索引信息。
  • rows data:數據存儲的地方,由多個行組構成,數據以流(stream)的形式進行存儲。
  • stripe footer:保存數據所在的文件目錄。

rows data 存儲兩部分的數據,即 metadata stream 和 data stream:

  • metadata stream:用于描述每個行組的元數據信息。
  • data stream:存儲數據的地方。

ORC 在每個文件中提供了 3 個級別的索引:

  • 文件級:這一級的索引信息記錄文件中所有 stripe 的位置信息,以及文件中所存儲的每列數據的統計信息。
  • 條帶級別:該級別索引記錄每個 stripe 所存儲數據的統計信息。
  • 行組級別:在 stripe 中,每 10000 行構成一個行組,該級別的索引信息 就是記錄這個行組中存儲的數據的統計信息。

程序可以借助 ORC 提供的索引加快數據查找和讀取效率。程序在查詢 ORC 文件類型的表時,會先讀取每一列的索引信息,將查找數據的條件和索引信息進行對比,找到滿足查找條件的文件。

接著根據文件中的索引信息,找到存儲對應的查詢條件數據 stripe,再借助 stripe 的索引信息讀文件中滿足查詢條件的所有 stripe 塊。

之后再根據 stripe 中每個行組的索引信息和查詢條件比對的結果,找到滿足要求的行組。

通過 ORC 這些索引,可以快速定位滿足查詢的數據塊,規避大部分不滿足查詢條件的文件和數據塊,相比于讀取傳統的數據文件,進行查找時需要遍歷全部的數據,使用 ORC 可以避免磁盤和網絡 I/O 的浪費,提升程序的查找效率,提升整個集群的工作負載。

3. ORC 的數據類型

Hive 在使用 ORC 文件進行存儲數據時,描述這些數據的字段信息、字段 類型信息及編碼等相關信息都是和 ORC 中存儲的數據放在一起的。

ORC 中每個塊中的數據都是自描述的,不依賴外部的數據,也不存儲在 Hive 的元數據庫中。

ORC 提供的數據數據類型包含如下內容:

  • 整型:包含 boolean(1bit)、tinyint(8bit)、smallint(16bit)、int(32bit)、bigint(64bit)。
  • 浮點型:包含 float 和 double。
  • 字符串類型:包含 string、char 和 varchar。
  • 二進制類型:包含 binary。
  • 日期和時間類型:包含 timestamp 和 date。·
  • 復雜類型:包含 struct、list、map 和 union 類型。

目前 ORC 基本已經兼容了日常所能用到的絕大部分的字段類型。另外,ORC 中所有的類型都可以接受 NULL 值。

4. ORC 的 ACID 事務的支持

在 Hive 0.14 版本以前,Hive 表的數據只能新增或者整塊刪除分區或表,而不能對表的單個記錄進行修改。

在 Hive 0.14 版本后,ORC 文件能夠確保 Hive 在工作時的原子性、一致性、隔離性和持久性的 ACID 事務能夠被正確地得到使用,使得對數據更新操作成為可能。

Hive 是面向 OLAP 的,所以它的事務也和 RDMBS 的事務有一定的區別。Hive 的事務被設計成每個事務適用于更新大批量的數據,而不建議用事務頻繁地更新小批量的數據。

創建 Hive 事務表的方法:

  1. 設置 hive 環境參數:
--開啟并發支持,支持插入、刪除和更新的事務
set hive.support.cnotallow=true;

--支持ACID事務的表必須為分桶表
set hive.enforce.bucketing=true;

--開啟事物需要開啟動態分區非嚴格模式
set hive.exec.dynamic.partition.mode=nonstrict;

--設置事務所管理類型為org.apache.hive.ql.lockmgr.DbTxnManager
--原有的org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager不支持事務
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;

--開啟在相同的一個meatore實例運行初始化和清理的線程
set hive.compactor.initiator.notallow=true;

--設置每個metastore實例運行的線程數
set hive.compactor.worker.threads=1;
  1. 創建表:
create table student_txn
(id int,
 name string
)
clustered by (id) into 2 buckets --必須支持分桶
stored as orc TBLPROPERTIES ('transactional'='true'); --在表屬性中添加支持事務
  1. 插入數據:
--插入id為1001,名字為'student_1001
insert into table student_txn values('1001','student_1001');
  1. 更新數據:
update student_txn
set name='student_lzh'
where id='1001';
  1. 查看表的數據,最終會發現 id 為 1001 被改為 sutdent_lzh;
5. ORC 相關的 Hive 配置

表的屬性配置項有如下幾個:

  • orc.compress:表示 ORC 文件的壓縮類型,可選的類型有 NONE、ZLIB 和 SNAPPY,默認值是 ZLIB。
  • orc.compress.size:表示壓縮塊(chunk)的大小,默認值是 262144(256KB)。
  • orc.stripe.size:寫 stripe,可以使用的內存緩沖池大小,默認值是 67108864(64MB)。
  • orc.row.index.stride:行組級別索引的數據量大小,默認是 10000,必須要設置成大于等于 10000 的數。
  • orc.create.index:是否創建行組級別索引,默認是 true。
  • orc.bloom.filter.columns:需要創建布隆過濾的組。
  • orc.bloom.filter.fpp:使用布隆過濾器的假正(False Positive)概率,默認值是 0.05。

注:在 Hive 中使用布隆(bloom)過濾器,可以用較少的文件空間快速判定數據是否存在于表中,但是也存在將不屬于這個表的數據判定為屬于這個這表的情況,這個情況稱之為假正概率,可以手動調整該概率,但概率越低,布隆過濾器所需要的空間越多。

五、Parquet

Parquet 是另外的一種高性能行列式的存儲結構,可以適用多種計算框架,被多種查詢引擎所支持,包括 Hive、Impala、Drill 等。

1. Parquet 基本結構:

在一個 Parquet 類型的 Hive 表文件中,數據被分成多個行組,每個列塊又被拆分成若干的頁(Page),如下圖所示:

Parquet的文件結構Parquet的文件結構

Parquet 在存儲數據時,也同 ORC 一樣記錄這些數據的元數據,這些元數據也同 Parquet 的文件結構一樣,被分成多層文件級別的元數據、列塊級別的元數據及頁級別的元數據。

文件級別的元數據(fileMetadata)記錄主要如下:

  • 表結構信息(Schema);
  • 該文件的記錄數;
  • 該文件擁有的行組,以及每個行組的數據總量,記錄數;
  • 每個行組下,列塊的文件偏移量。

列塊的元數據信息如下:

  • 記錄該列塊的未壓縮和壓縮后的數據大小和壓縮編碼;
  • 數據頁的偏移量;
  • 索引頁的偏移量;
  • 列塊的數據記錄數。

頁頭的元數據信息如下:

  • 該頁的編碼信息;
  • 該頁的數據記錄數。

程序可以借助 Parquet 的這些元數據,在讀取數據時過濾掉不需要讀取的大部分文件數據,加快程序的運行速度。

同 ORC 的元數據一樣,Parquet 的這些元數據信息能夠幫助提升程序的運行速度,但是 ORC 在讀取數據時又做了一定的優化,增強了數據的讀取效率。在查詢時所消耗的集群資源比 Parquet 類型少。

Parquet 在嵌套式結構支持比較完美,而 ORC 多層級嵌套表達起來比較復雜,性能損失較大。

2. Parquet 的相關配置:

可以根據不同場景需求進行適當的參數調整,實現程序優化。

  • parquet.block.size:默認值為 134217728byte,即 128MB,表示 RowGroup 在內存中的塊大小。該值設置得大,可以提升 Parquet 文件的讀取效率,但是相應在寫的時候需要耗費更多的內存。
  • parquet.page.size:默認值為 1048576byte,即 1MB,表示每個頁 (page)的大小。這個特指壓縮后的頁大小,在讀取時會先將頁的數據進行解壓。頁是 Parquet 操作數據的最小單位,每次讀取時必須讀完一整頁的數據才能訪問數據。這個值如果設置得過小,會導致壓縮時出現性能問題。
  • parquet.compression:默認值為 UNCOMPRESSED(不壓縮),表示頁的壓縮式。可以使用的壓縮方式有 UNCOMPRESSED、SNAPPY、GZIP 和 LZO。
  • parquet.enable.dictionary:默認為 true,表示是否啟用字典編碼。
  • parquet.dictionary.page.size:默認值為 1048576byte,即 1MB。在使用字典編碼時,會在 Parquet 的每行每列中創建一個字典頁。使用字典編碼,如果存儲的數據頁中重復的數據較多,能夠起到一個很好的壓縮效果,也能減少每個頁在內存的占用。
3. 使用Spark引擎時 Parquet 表的壓縮格式配置:

Spark 天然支持 Parquet,并為其推薦的存儲格式(默認存儲為parquet)。

對于 Parquet 表的壓縮格式分以下兩種情況進行配置:

對于分區表:

需要通過 Parquet 本身的配置項 parquet.compression 設置 Parquet 表的數據壓縮格式。如在建表語句中設置:"parquet.compression"="snappy"。

對于非分區表:

需要通過 spark.sql.parquet.compression.code 配置項來設置 Parquet 類型的數據壓縮格式。直接設置parquet.compression 配置項是無效的,因為它會讀取 spark.sql.parquet.compression.codec 配置項的值。

當 spark.sql.parquet.compression.codec 未做設置時默認值為 snappy,parquet.compression 會讀取該默認值。

因此,spark.sql.parquet.compression.codec 配置項只適用于設置非分區表的 Parquet 壓縮格式。

4. Parquet 和 ORC 壓縮格式對比:

表類型

默認壓縮

支持的壓縮格式

描述

ORC

Zlib

None、Zlib、Snappy

ORC 可以選擇Zlib或Snappy壓縮,Snappy需要額外安裝

Parquet

Uncompressed

Uncompressed、Snappy、Gzip、Lzo

Parquet使用Gzip壓縮率最高,使用 Lzo、Snappy效率高

ORC 表支持 None、Zlib、Snappy 壓縮,默認為 ZLIB 壓縮。但這 3 種壓縮格式不支持切分,所以適合單個文件不是特別大的場景。使用 Zlib 壓縮率高,但效率差一些;使用 Snappy 效率高,但壓縮率低。

Parquet 表支持 Uncompress、Snappy、Gzip、Lzo 壓縮,默認不壓縮(Uncompressed)。其中 Lzo 壓縮是支持切分的,所以在表的單個文件較大的場景會選擇 Lzo 格式。Gzip 方式壓縮率高,效率低;而 Snappy、Lzo 效率高,壓縮率低。

責任編輯:武曉燕 來源: 五分鐘學大數據
相關推薦

2021-12-16 14:45:09

https架構服務端

2022-10-20 08:01:23

2021-05-07 14:03:36

大數據存儲接口CSI

2020-05-20 09:55:42

Git底層數據

2022-08-27 10:37:48

電子取證信息安全

2023-12-22 19:59:15

2021-08-04 16:06:45

DataOps智領云

2017-06-02 15:32:09

大數據數據可視化

2023-06-19 13:57:00

數據系統

2018-04-03 13:08:31

2022-05-04 17:43:28

元數據大數據

2018-09-28 14:06:25

前端緩存后端

2022-09-22 09:00:46

CSS單位

2025-04-03 10:56:47

2022-11-06 21:14:02

數據驅動架構數據

2023-11-27 17:35:48

ComponentWeb外層

2023-05-20 17:58:31

低代碼軟件

2022-07-05 06:30:54

云網絡網絡云原生

2022-07-26 00:00:03

語言模型人工智能

2021-12-29 18:00:19

無損網絡網絡通信網絡
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄色一级在线播放 | 精品一区二区三区中文字幕 | 欧美精品一区在线 | 一区二区成人 | 四虎网站在线观看 | 91精品国产乱码久久久久久久久 | 国产一区二区 | 日本久久久一区二区三区 | 91黄在线观看 | 成人国产午夜在线观看 | 久久国产精品-久久精品 | 久草成人 | 亚洲精品在线看 | 午夜精品在线观看 | 欧洲色综合 | 91伊人 | 久久精品一二三影院 | aaaaa毛片| 夜夜爆操 | 99久久精品国产麻豆演员表 | 成人午夜免费视频 | 一区二区三区国产好 | 中国毛片免费 | 久久综合一区 | 成人免费视频网站在线看 | 成人在线中文字幕 | 81精品国产乱码久久久久久 | 欧美成人免费在线视频 | 一级黄色大片 | 精品乱码一区二区三四区 | 色吧久久 | 在线观看www视频 | 精品日韩一区二区 | 国产特级毛片aaaaaa | 久久精品国产一区 | 欧美一区在线视频 | 九九九视频在线观看 | 91在线电影 | 日韩在线中文字幕 | 免费天天干 | 欧美色999 |