Hive介紹與核心知識點

Hive介紹與核心知識點

Hive

Hive簡介

Facebook為了解決海量日誌數據的分析而開發了Hive,後來開源給了Apache軟件基金會。

官網定義:

The Apache Hive ™ data warehouse software facilitates reading, writing, and managing large datasets residing in distributed storage using SQL.

Hive是一種用類SQL語句來協助讀寫、管理那些存儲在分佈式存儲系統上大數據集的數據倉庫軟件。

Hive的幾個特點

  • Hive最大的特點是通過類SQL來分析大數據,而避免了寫MapReduce程序來分析數據,這樣使得分析數據更容易。
  • 數據是存儲在HDFS上的,Hive本身並不提供數據的存儲功能
  • Hive是將數據映射成數據庫和一張張的表,庫和表的元數據信息一般存在關係型數據庫上(比如MySQL)。
  • 數據存儲方面:它能夠存儲很大的數據集,並且對數據完整性、格式要求並不嚴格。
  • 數據處理方面:因為Hive語句最終會生成MapReduce任務去計算,所以不適用於實時計算的場景,它適用於離線分析。

Hive架構


Hive介紹與核心知識點


image.png

Hive的底層存儲

Hive的數據是存儲在HDFS上的。Hive中的庫和表可以看作是對HDFS上數據做的一個映射。所以Hive必須是運行在一個Hadoop集群上的。

Hive語句的執行過程

Hive中的執行器,是將最終要執行的MapReduce程序放到YARN上以一系列Job的方式去執行。

Hive的元數據存儲

Hive的元數據是一般是存儲在MySQL這種關係型數據庫上的,Hive和MySQL之間通過MetaStore服務交互。

Hive重要概念

外部表和內部表

內部表(managed table)

  • 默認創建的是內部表(managed table),存儲位置在hive.metastore.warehouse.dir設置,默認位置是/user/hive/warehouse。
  • 導入數據的時候是將文件剪切(移動)到指定位置,即原有路徑下文件不再存在
  • 刪除表的時候,數據和元數據都將被刪除
  • 默認創建的就是內部表create table xxx (xx xxx)

外部表(external table)

  • 外部表文件可以在外部系統上,只要有訪問權限就可以
  • 外部表導入文件時不移動文件,僅僅是添加一個metadata
  • 刪除外部表時原數據不會被刪除
  • 分辨外部表內部表可以使用DESCRIBE FORMATTED table_name命令查看
  • 創建外部表命令添加一個external即可,即create external table xxx (xxx)
  • 外部表指向的數據發生變化的時候會自動更新,不用特殊處理

分區表和桶表

分區(partioned)

  • 有些時候數據是有組織的,比方按日期/類型等分類,而查詢數據的時候也經常只關心部分數據,比方說我只想查2017年8月8號,此時可以創建分區,查詢具體某一天的數據時,不需要掃描全部目錄,所以會明顯優化性能
  • 一個Hive表在HDFS上是有一個對應的目錄來存儲數據,普通表的數據直接存儲在這個目錄下,而分區表數據存儲時,是再劃分子目錄來存儲的
  • 使用partioned by (xxx)來創建表的分區

[圖片上傳失敗...(image-15cd1e-1539162972641)]

分桶(clustered)

  • 分桶是相對分區進行更細粒度的劃分。分桶將整個數據內容安裝某列屬性值得hash值進行區分,按照取模結果對數據分桶。如取模結果相同的數據記錄存放到一個文件。
  • 桶表也是一種用於優化查詢而設計的表類型。創建通表時,指定桶的個數、分桶的依據字段,hive就可以自動將數據分桶存儲。查詢時只需要遍歷一個桶裡的數據,或者遍歷部分桶,這樣就提高了查詢效率。

具體說明分桶

  • clustered by (user_id) sorted by(leads_id) into 10 buckets
  • clustered by是指根據user_id的值進行哈希後模除分桶個數,根據得到的結果,確定這行數據分入哪個桶中,這樣的分法,可以確保相同user_id的數據放入同一個桶中。

  • sorted by 是指定桶中的數據以哪個字段進行排序,排序的好處是,在join操作時能獲得很高的效率。

  • into 10 buckets是指定一共分10個桶。

  • 在HDFS上存儲時,一個桶存入一個文件中,這樣根據user_id進行查詢時,可以快速確定數據存在於哪個桶中,而只遍歷一個桶可以提供查詢效率。

Hive文件格式

hive文件存儲格式包括以下幾類:

  1. TEXTFILE
  2. SEQUENCEFILE
  3. RCFILE
  4. ORCFILE(0.11以後出現)

其中TEXTFILE為默認格式,建表時不指定默認為這個格式,導入數據時會直接把數據文件拷貝到hdfs上不進行處理;SEQUENCEFILE,RCFILE,ORCFILE格式的表不能直接從本地文件導入數據,數據要先導入到textfile格式的表中, 然後再從表中用insert導入SequenceFile,RCFile,ORCFile表中。

列式存儲和行式存儲

首先我們看一下一張表的存儲格式


Hive介紹與核心知識點



行式存儲


Hive介紹與核心知識點



列式存儲



Hive介紹與核心知識點


列式存儲和行式存儲的比較

行式存儲

優點:

  • 相關的數據是保存在一起,比較符合面向對象的思維,因為一行數據就是一條記錄
  • 這種存儲格式比較方便進行INSERT/UPDATE操作

缺點:

  • 如果查詢只涉及某幾個列,它會把整行數據都讀取出來,不能跳過不必要的列讀取。當然數據比較少,一般沒啥問題,如果數據量比較大就比較影響性能
  • 由於每一行中,列的數據類型不一致,導致不容易獲得一個極高的壓縮比,也就是空間利用率不高
  • 不是所有的列都適合作為索引

列式存儲

優點:

  • 查詢時,只有涉及到的列才會被查詢,不會把所有列都查詢出來,即可以跳過不必要的列查詢
  • 高效的壓縮率,不僅節省儲存空間也節省計算內存和CPU
  • 任何列都可以作為索引

缺點:

  • INSERT/UPDATE很麻煩或者不方便
  • 不適合掃描小量的數據

TEXTFILE

默認格式,數據不做壓縮,磁盤開銷大,數據解析開銷大。

可結合Gzip、Bzip2使用(系統自動檢查,執行查詢時自動解壓),但使用這種方式,hive不會對數據進行切分,從而無法對數據進行並行操作。

SEQUENCEFILE

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

SequenceFile支持三種壓縮選擇:NONE,RECORD,BLOCK。Record壓縮率低,一般建議使用BLOCK壓縮。

RCFILE

RCFILE是一種行列存儲相結合的存儲方式。首先,其將數據按行分塊,保證同一個record在一個塊上,避免讀一個記錄需要讀取多個block。其次,塊數據列式存儲,有利於數據壓縮和快速的列存取。

  • RCFile保證同一的數據位於同一節點,因此元組重構代價較低(需要將分散的數據重新組織,比如一列數據散落在不同集群,查詢的時候,需要將各個節點的數據重新組織;但是如果數據都在一個機器上,那就沒有必要重新組織)
  • RCFile通過列進行數據壓縮,因為同一列都是相同的數據類型,所以壓縮比比較好
  • RCFile可以跳過不必要的列讀取

從以上幾點也可以看出它是兼顧了行式和列式存儲的部分優點。

ORC File

ORCFile存儲格式,就是Optimized RC File的縮寫。意指優化的RCFile存儲格式。

ORC File 和 RC File比較

  • 每一個任務只輸出單個文件,這樣可以減少NameNode的負載
  • 支持各種複雜的數據類型,比如datetime,decimal,以及複雜的struct,List,map等
  • 在文件中存儲了輕量級的索引數據
  • 基於數據類型的塊模式壓縮:比如Integer類型使用RLE(RunLength Encoding)算法,而字符串使用字典編碼(DictionaryEncoding)
  • 使用單獨的RecordReader並行讀相同的文件
  • 無需掃描標記就能分割文件
  • 綁定讀寫所需要的內存
  • 元數據存儲使用PB,允許添加和刪除字段

Hive ROW FORMAT

Serde是 Serializer/Deserializer的簡寫。hive使用Serde進行行對象的序列與反序列化。

你可以創建表時使用用戶自定義的Serde或者native Serde,如果 ROW FORMAT沒有指定或者指定了 ROW FORMAT DELIMITED就會使用native Serde。

hive已經實現了許多自定義的Serde,之前我們在介紹stored時也涉及到:

  • Avro (Hive 0.9.1 and later)
  • ORC (Hive 0.11 and later)
  • RegEx
  • Thrift
  • Parquet (Hive 0.13 and later)
  • CSV (Hive 0.14 and later)
  • JsonSerDe (Hive 0.12 and later)

Hive寫入數據的方式

和我們熟悉的關係型數據庫不一樣,Hive現在還不支持在insert語句裡面直接給出一組記錄的文字形式,也就是說,Hive並不支持INSERT INTO …. VALUES形式的語句。

從本地文件系統中導入數據到Hive表

load data local inpath 'xxx.txt' into table xxx;

從HDFS上導入數據到Hive表

load data inpath '/home/xxx/add.txt' into table xxx

alter table db.access_log add partition (dt='18-09-18') location 'hdfs://ns/hive/warehouse/access_log/dt=18-09-18';

從別的表中查詢出相應的數據並導入到Hive表中

insert overwrite table db.log_v2 partition(dt='18-09-26') select uid,model,key,value,time from db.log where dt='18-09-26';

在創建表的時候通過從別的表中查詢出相應的記錄並插入到所創建的表中

create table test4 as select id, name, tel from xxx;


歡迎關注 高廣超的簡書博客 與 收藏文章 !

個人介紹:

高廣超:多年一線互聯網研發與架構設計經驗,擅長設計與落地高可用、高性能、可擴展的互聯網架構。目前從事大數據相關研發與架構工作。

本文首發在 高廣超的簡書博客 轉載請註明!


分享到:


相關文章: