Hive性能優化


1.為啥Hive需要優化?

(1)Hive的執行依賴於底層的MapReduce作業,因此對Hadoop作業的優化或者MapReduce作業的調整是提高Hive性能的基礎。

(2)如果沒有經過優化調整的Hive,那么很容易出現:即使查詢hive中的一個小表,有時也會耗時數分鍾或幾十分鍾才能得到結果,甚至很難得到結構,直接被卡死了。

(3)Hive對於OLAP類型的應用有很大的局限性,它不適合需要立即返回查詢結果的場景。

  忍不住了,要吐槽一下。在此筆者認為,hive本身只是一個上層應用上的執行類數據庫的某些語句而已,造成hive某些性能上的問題,其根本還是hadoop自身設計上的問題,

是其設計上存在缺陷造成了不適合於對實時性要求很高的應用。那種說hadoop只適合於大數據、批量、非實時性的應用,這只是為了掩蓋其本身的缺陷,誆騙世人的說辭。

至少筆者認為Hadoop是存在設計上的缺陷的,設計上的缺陷造成了對實時性要求高——低時延的應用支持不足,以及hive對事務上的支持不足。

筆者是不認可CAP理論的,這個理論聽起來似乎有道理,而且說的是客觀事實,但實際上造成這一客觀事實的源頭,卻正是Hadoop本身設計上的缺陷所導致的,

它無法克服和解決掉所存在的問題。筆者只是在此略微吐槽一下,只是給偶來之觀眾以思維上的啟迪。

在筆者沒有搞出新的大數據管理軟件,取代Hadoop這類工具之前,該學習別人的還是要學習的,何況乎筆者也是學習者之一。筆者雖對其有微詞,但也認可其中諸多優秀的設計理念,值得學習。

2.Hive優化方式:

2.1參數優化

2.1.1啟用壓縮

啟用壓縮可以使得磁盤上存儲的數據所占用空間變小,這樣可以使得I/O負載率降低進而提高查詢速度。

壓縮和解壓會消耗CPU資源,但Hive產生的MapReduce作業往往是I/O密集型的,通常CPU開銷不是問題,而內存空間才是問題的關鍵。

一個復雜的Hive查詢在提交后,通常被轉換為一系列中間階段的MapReduce作業,Hive引擎將這些作業串聯起來完成整個查詢。因此可以將這些中間數據進行壓縮。

這些中間數據是指上一個MapReduce作業的輸出,這些輸出將被下一個MapReduce作業作為輸入數據使用。

(1)查看Hive支持的壓縮編碼方式set  io.compress.codes,示例如下:

(2)參數優化說明:

表2.1.2-1 Hive啟用壓縮優化參數列表
參數 默認值 優化值 參數說明
hive.exec.compress.intermediate false true

該參數用於啟動MapReduce中間數據壓縮。

該參數值設置為“true”,即表示啟用中間結果壓縮。

hive.intermediate.compression.codec 空值 org.apache.hadoop.io.compress.SnappyCodec

該參數設置壓縮格式。可支持參數值如下:

org.apache.hadoop.io.compress.SnappyCodec

org.apache.hadoop.io.compress.GzipCodec

org.apache.hadoop.io.compress.BZip2Codec

org.apache.hadoop.io.compress.DeflateCodec

org.apache.hadoop.io.compress.Lz4Codec

org.apache.hadoop.io.compress.DefaultCodec

hive.intermediate.compression.type 空值 BLOCK 該參數設置為“BLOCK”,即數據以區塊進行壓縮。
hive.exec.compress.output false true

 該參數設置Hive輸出寫入到表中是,對輸出內容進行壓縮。

參數值設置為“true”,即表示啟用最終輸出壓縮。

(3)參數文件配置:

1)啟用中間結果壓縮參數配置示例(推薦該種方式必須設置):

<property>

<name>hive.exec.compress.intermediate</name>
<value>true</value>

<description>

This controls whether intermediate files produced by Hive between multiple map-reduce jobs are compressed.
The compression codec and other options are determined from Hadoop config variables mapred.output.compress*

  </description>
</property>
<property>
  <name>hive.intermediate.compression.codec</name>
  <value>org.apache.hadoop.io.compress.SnappyCodec</value>
  <description/>
</property>
<property>
  <name>hive.intermediate.compression.type</name>
  <value>BLOCK</value>
  <description/>
</property>

2)啟用最終結果壓縮示例(須同時設置壓縮格式和數據塊壓縮

<property>
  <name>hive.exec.compress.output</name>
  <value>true</value>
  <description>
  This controls whether the final outputs of a query (to a local/HDFS file or a Hive table) is compressed.
  The compression codec and other options are determined from Hadoop config variables mapred.output.compress*
  </description>
</property>

注:參數文件中,壓縮格式設置和數據塊壓縮,只需要設置一次即可。

2.1.2優化連接

(1)自動Map連接

當一個大表和一個小表進行連接時,配置自動Map連接是一個非常有用的特性。若啟用該特性,則小表將保存在每個節點的本地緩存中,並在Map階段與大表進行連接

開啟自動Map連接提供了兩個好處:

第一,將小表裝進緩存將節省每個數據節點上的讀取時間;

第二,避免了Hive查詢中的傾斜連接,每個數據塊的連接操作已經在Map階段就完成了。

1)參數優化說明:

表2.1.2-1 Hive啟用自動Map連接參數列表
參數 默認值 優化值 參數說明
hive.auto.convert.join true true

該參數用於是否啟用基於輸入文件的大小,將普通連接轉化為Map連接的優化機制。

該參數默認是開啟的。

hive.auto.convert.join.noconditionaltask true true

該參數用於是否啟用基於輸入文件的大小,將普通連接轉化為Map連接的優化機制。

假設參與連接的表(或分區)有N個,如果打開這個參數,並且有N-1個表(或分區)的大小總和小於hive.auto.convert.join.nonconditionaltask.size參數設定的值,那么會直接將連接轉化為Map連接。

該參數默認也是開啟的。

hive.auto.convert.join.noconditionaltask.size 10000000 10000000

hive.auto.convert.join.noconditionaltask是關閉的,該參數不起作用。

否則,如果參與連接的N個表(或分區)中的N-1個總大小小於該參數的值,那么則直接將連接轉化為Map連接。

該參數默認值為10MB。可根據實際情況進行調整。

hive.auto.convert.join.use.nonstaged false true

該參數用於對於條件連接時,如果從一個小的輸入流可以直接應用於join操作而不需要過濾或者投影,那么不需要通過MapReduce的本地任務表在分布式緩存中預存。

該參數在vectorization或tez執行引擎中不工作。

該參數默認是不開啟的。

2)參數文件配置:

啟用自動Map連接參數配置示例:

 <property>
  <name>hive.auto.convert.join</name>
  <value>true</value>
  <description>Whether Hive enables the optimization about converting common join into mapjoin based on the input file size</description>
</property>
<property>
  <name>hive.auto.convert.join.noconditionaltask</name>
  <value>true</value>
  <description>
  Whether Hive enables the optimization about converting common join into mapjoin based on the input file size.
  If this parameter is on, and the sum of size for n-1 of the tables/partitions for a n-way join is smaller than the
  specified size, the join is directly converted to a mapjoin (there is no conditional task).
  </description>
</property>

<property>
  <name>hive.auto.convert.join.noconditionaltask.size</name>
  <value>10000000</value>
  <description>
  If hive.auto.convert.join.noconditionaltask is off, this parameter does not take affect.
  However, if it is on, and the sum of size for n-1 of the tables/partitions for a n-way join is smaller than this size,
  the join is directly converted to a mapjoin(there is no conditional task). The default is 10MB
  </description>
</property>
<property>
  <name>hive.auto.convert.join.use.nonstaged</name>
  <value>true</value>
  <description>
  For conditional joins, if input stream from a small alias can be directly applied to join operator without
  filtering or projection, the alias need not to be pre-staged in distributed cache via mapred local task.
  Currently, this is not working with vectorization or tez execution engine.
  </description>
</property>

(2)傾斜鏈接

當兩個大表連接時,會先基於連接鍵分別對兩個表進行排序,然后對他們進行連接。Mapper將特定鍵值的所有行發送給同一個Reducer。

例如:對A表和B表進行連接,表A的id列有1、2、3、4四個值,而B表id列有1、2、3三個值,現有查詢語句如下:

select  A.id from A join B on A.id=B.id

上述語句,則會產生一系列的Mapper讀取表中的數據並基於鍵值發送給Reducer。如id=1行進入Reducer R1,id=2的行進入Reducer R2, id=3的行進入Reducer R3,id=4的行進入Reducer R4。

這些Reducer進一步產生A、B的交集並輸出。其中Reducer R4只從A中獲取行,不會產生查詢結果。

現假設id=1的數據行是高度傾斜的,則R2和R3會很快完成,而R1需要很長的時間,將稱為整個查詢的瓶頸。因此配置傾斜連接的相關屬性可以優化傾斜連接。

1)參數優化說明:

表2.1.2-2 Hive啟用傾斜連接優化參數列表
參數 默認值 優化值 參數說明
hive.optimize.skewjoin false true

該參數用於是否為連接表中的傾斜鍵創建單獨的執行計划。

它是基於存儲在元數據中的傾斜鍵。

在編譯時,Hive為傾斜建和其他鍵值生成各自的查詢計划。

該參數默認是開啟的。

skewjoin的原理:

1)對於skewjoin.key,在執行job時,將它們存入臨時的HDFS目錄中,其他數據正常執行。

2)對於傾斜數據開啟map join操作,對非傾斜值采取普通join操作。

3)將傾斜數據集和非傾斜數據集進行合並操作。

hive.skewjoin.key 100000 100000

該參數決定如何確定連接中的傾斜建。

在連接操作中,如果同一鍵值所對應的數據行數超過該參數值,則認為是一個傾斜連接鍵。

hive.skewjoin.mapjoin.map.tasks 10000 10000

指定傾斜連接中,用於Map連接作業的任務數。

該參數應該與hive.skewjoin.mapjoin.min.split一起使用,執行細粒度的控制。

hive.skewjoin.mapjoin.min.split 33554432 33554432

通過指定最小split的大小,確定Map連接作業的任務數。

該參數應該與hive.skewjoin.mapjoin.map.tasks一起使用,執行細粒度的控制。

hive.optimize.skewjoin.compiletime false
true

該參數用於開啟數據傾斜的join編譯時優化。

基於存儲在元數據中的傾斜key,在編譯時給導致傾斜的key單獨創建執行計划,而其他key采用另外的執行計划進行join。然后對生成的兩個join執行后求並集。因此除非相同的傾斜key同時存在於這兩個join表中,否則會引起傾斜的key在join就會優化map-side join。

該參數與hive.optimize.skewjoin主要區別在於,該參數存儲在metastore中的傾斜信息在編譯時優化執行計划。如果元數據中沒有傾斜信息,則此參數無效。

如果建表語句元數據中指定了skew key,該參數開啟則開啟了skew join。

該參數默認未開啟,但推薦開啟 。

2)參數文件配置:

啟用傾斜連接優化參數配置示例:

<property>
  <name>hive.optimize.skewjoin</name>
  <value>true</value>
  <description>
  Whether to enable skew join optimization.
  The algorithm is as follows: At runtime, detect the keys with a large skew. Instead of processing those keys, store them temporarily in an HDFS directory.

       In a follow-up map-reduce job, process those skewed keys.

       The same key need not be skewed for all the tables, and so,the follow-up map-reduce job (for the skewed keys) would be much faster, since it would be a map-join.
  </description>
</property>

<property>
  <name>hive.optimize.skewjoin.compiletime</name>
  <value>true</value>
<description>
  Whether to create a separate plan for skewed keys for the tables in the join.
  This is based on the skewed keys stored in the metadata. At compile time, the plan is broken into different joins: one for the skewed keys,

       and the other for the remaining keys.

       And then,a union is performed for the 2 joins generated above.

       So unless the same skewed key is present in both the joined tables, the join for the skewed key will be performed as a map-side join.
  The main difference between this parameter and hive.optimize.skewjoin is that this parameter uses the skew information stored in the

        metastore to optimize the plan at compile time itself.
  If there is no skew information in the metadata, this parameter will not have any affect.
  Both hive.optimize.skewjoin.compiletime and hive.optimize.skewjoin should be set to true.
  Ideally, hive.optimize.skewjoin should be renamed as hive.optimize.skewjoin.runtime, but not doing so for backward compatibility.
  If the skew information is correctly stored in the metadata, hive.optimize.skewjoin.compiletime would change the query plan to take

       care of it, and hive.optimize.skewjoin will be a no-op.
  </description>
</property>

<property>
  <name>hive.skewjoin.mapjoin.map.tasks</name>
  <value>10000</value>
  <description>
  Determine the number of map task used in the follow up map join job for a skew join.
  It should be used together with hive.skewjoin.mapjoin.min.split to perform a fine grained control.
  </description>
</property>
<property>
  <name>hive.skewjoin.mapjoin.min.split</name>
  <value>33554432</value>
  <description>
  Determine the number of map task at most used in the follow up map join job for a skew join by specifying
  the minimum split size. It should be used together with hive.skewjoin.mapjoin.map.tasks to perform a fine grained control.
  </description>
</property>

(3)桶Map連接

如果連接中存在桶表,即表是按特定列進行分桶的,那么可以開啟桶Map連接提升性能。

1)參數優化說明:

表2.1.2-3 Hive啟用桶Map傾斜連接優化參數列表
參數 默認值 優化值 參數說明
hive.optimize.bucketmapjoin false true

該參數用於嘗試桶Map連接。

該參數默認是關閉的。

hive.optimize.bucketmapjoin.sortedmerge false true

該參數嘗試在Map連接中使用歸並排序。

該參數默認是關閉的。

2)參數文件配置:

啟用桶Map連接優化參數配置示例:

<property>
  <name>hive.optimize.bucketmapjoin</name>
  <value>true</value>
  <description>Whether to try bucket mapjoin</description>
</property>
<property>
  <name>hive.optimize.bucketmapjoin.sortedmerge</name>
  <value>true</value>
  <description>Whether to try sorted bucket merge map join</description>
</property>

2.1.3更換計算執行引擎

Hive支持MR、Tez、Spark三種計算執行引擎,其中MR是默認的計算引擎,即使用MapReduce引擎

通常使用tez和spark兩種計算引擎性能都優於MR,但需要額外配置相關的參數和相應的工具安裝、配置

(1)使用Tez作為計算執行引擎

 

(2)使用Spark作為計算執行引擎

 

2.1.4啟動並行執行

每條Hive語句的執行,都將被轉化為一個或多個執行階段,可能是一個MapReduce階段、采樣階段、歸並階段、限制階段等。

默認Hive在任意時刻只能執行其中一個階段。如果組成一個特定作業的多個執行階段是彼此獨立的,那么他們就可以並行執行,從而使得整個作業得以更快速完成。

(1)參數優化說明:

表2.1.4-1 Hive啟用並行優化參數列表
參數 默認值 優化值 參數說明
hive.exec.parallel false true

該參數用於啟動並行執行作業

強烈建議開啟。

hive.exec.parallel.thread.number 8 10

該參數用於設置最多可以並行執行的作業數

該值的設置應當根據CPU核數和線程數進行合理設置。

(2)參數文件配置:

啟用桶Map連接優化參數配置示例:

  <property>
    <name>hive.exec.parallel</name>
    <value>true</value>
    <description>Whether to execute jobs in parallel</description>
  </property>
  <property>
    <name>hive.exec.parallel.thread.number</name>
    <value>10</value>
    <description>How many jobs at most can be executed in parallel</description>
  </property>

2.1.5控制並行Reduce任務

Hive通過將查詢划分成一個或多個MapReduce任務達到並行的目的。確定最佳的mapper個數和reducer取決於多個變量,例如:輸入的數據量,以及對這些數據執行的操作類型等。

如果太多的mapper和reducer任務,會導致啟動、調度和運行作業過程中產生過多的開銷,而如果設置的數量太少,那么就可能沒有充分利用好集群內在的並行性

因此,對於一個Hive查詢,Hive提供相應的參數可進行優化控制並行reduce任務的個數

(1)參數優化說明:

表2.1.5-1 Hive控制並行Reduce任務數的優化參數列表
參數 默認值 優化值 參數說明
hive.exec.reducers.bytes.per.reducer 256000000 256000000

該參數用於設置每個reducer的字節數。

Hive是按照輸入的數據量大小來確定reducer個數的。例如輸入1GB的數據,將使用4個reducer。

該參數默認值為256MB。

hive.exec.reducers.max 1009 1009

該參數設置可能會使用的最大reducer個數

(2)參數文件配置:

啟用桶Map連接優化參數配置示例:

  <property> 
    <name>hive.exec.reducers.bytes.per.reducer</name>
    <value>256000000</value>
    <description>size per reducer.The default is 256Mb, i.e if the input size is 1G, it will use 4 reducers.</description>
  </property> 
  <property>
    <name>hive.exec.reducers.max</name> 
    <value>1009</value>  
    <description> 
      max number of reducers will be used. If the one specified in the configuration parameter mapred.reduce.tasks is
      negative, Hive will use this one as the max number of reducers when automatically determine number of reducers.
    </description>
  </property>

2.1.6啟用向量化

Hive可通過查詢執行向量化,使Hive從單行處理數據改為批量處理方式具體來說是一次處理1024行而不是每次只處理1行。

這大大地提升了指令流水線和緩存的利用率,從而提高了表掃描、聚合、過濾和連接等操作的性能

(1)參數優化說明:

表2.1.6-1 Hive控制並行Reduce任務數的優化參數列表
參數 默認值 優化值 參數說明
hive.vectorized.execution.enabled true true

該參數用於開啟查詢執行的向量模式

hive.vectorized.execution.reduce.enabled true true

該參數用於開啟查詢執行reduce端的向量模式

hive.vectorized.execution.reduce.groupby.enabled true true

該參數用於開啟查詢執行reduce端group by操作的向量模式

(2)參數文件配置:

啟用桶Map連接優化參數配置示例:

  <property>
    <name>hive.vectorized.execution.enabled</name>
    <value>true</value>
    <description>
      This flag should be set to true to enable vectorized mode of query execution.
      The default value is true to reflect that our most expected Hive deployment will be using vectorization.
    </description>
  </property>
  <property>
    <name>hive.vectorized.execution.reduce.enabled</name>
    <value>true</value>
    <description>
      This flag should be set to true to enable vectorized mode of the reduce-side of query execution.
      The default value is true.
    </description>
  </property>

  <property>
    <name>hive.vectorized.execution.reduce.groupby.enabled</name>
    <value>true</value>
    <description>
      This flag should be set to true to enable vectorized mode of the reduce-side GROUP BY query execution.
      The default value is true.
    </description>
  </property>

2.1.7啟用基於成本的優化器

Hive提供了基於的成本優化器(CBO),其特性是可以根據查詢成本指定執行計划。

例如:確定表連接的順序、以何種方式執行連接、使用的並行度等。

(1)參數優化說明:

表2.1.6-1 Hive控制並行Reduce任務數的優化參數列表
參數 默認值 優化值 參數說明
hive.cbo.enable true true

該參數用於控制是否啟用基於成本的優化器

Hive的CBO使用Apache Calcite框架實現。

該參數默認是開啟的。

hive.compute.query.using.stats true true

該參數用於Hive在執行某些查詢時,只需要利用元數據存儲中保存的狀態信息返回結果。

為了收集基本狀態信息,需要將hive.stats.autogather參數值設為true

為了收集更多的狀態信息,需要運行analyze table查詢命令。

hive.stats.autogather true true

該參數用於開啟表、分區的統計信息自動收集。

但是,對於一個新表或者分區,只有在執行INSERT OVERWRITE/INTO語句時,才會自動收集統計信息執行LOAD操作時,不會自動收集統計信息。

該參數默認是開啟的。

hive.stats.fetch.partition.stats true true

該參數用於操作樹種所標識的統計信息,需要分區級別的基本統計,如每個分區的行數、數據量大小和文件大小等 。分區統計信息從元數據存儲中獲取。

如果存在很多分區,要為每一個分區收集統計信息可能會消耗大量的資源。

這個標志可被用於禁止從元數據存儲中獲取分區統計。

當該標志設置為false時,Hive從文件系統獲取文件大小,並根據表結構估算行數。

該參數已於Hive3.0.0開始,被移除了。

hive.stats.fetch.column.stats false true

該參數用於操作樹種所標識的統計信息,需要列統計。

列統計信息從元數據存儲中獲取。

如果存在很多列,要為每一個列收集統計信息可能會消耗大量的資源。

這個標識可被用於禁止從元數據存儲中獲取列統計。

該參數默認是關閉的,推薦將其關閉,即參數值為false

(2)參數文件配置:

啟用桶Map連接優化參數配置示例:

  <property>
    <name>hive.vectorized.execution.enabled</name>
    <value>true</value>
    <description>
      This flag should be set to true to enable vectorized mode of query execution.
      The default value is true to reflect that our most expected Hive deployment will be using vectorization.
    </description>
  </property>
  <property>
    <name>hive.vectorized.execution.reduce.enabled</name>
    <value>true</value>
    <description>
      This flag should be set to true to enable vectorized mode of the reduce-side of query execution.
      The default value is true.
    </description>
  </property>

  <property>
    <name>hive.vectorized.execution.reduce.groupby.enabled</name>
    <value>true</value>
    <description>
      This flag should be set to true to enable vectorized mode of the reduce-side GROUP BY query execution.
      The default value is true.
    </description>
  </property>

2.2語句優化

筆者認為下面涉及到語句優化方式很是雞肋,但很重要,需要使用者注意和防范的。

2.2.1避免使用order by全局排序

Hive中使用order by子句實現全局排序。order by只用一個Reducer產生結果,對於大多數據集,這種做法效率很低。

如果不需要全局排序,則可以使用sort by子句,該子句為每一個reducer生成一個排好序的文件。

如果需要控制一個特定數據行流向哪個reducer,可以使用distribute by子句。

例子:

select id,name,salary,dept from employee distribute by dept sort by id asc,name desc;

即:屬於一個dept的數據會分配到同一個reducer進行處理,同一個dept的所有記錄按照id、name進行列排序。最終的結果集是全局有序的。

2.2.2優化limit操作

默認時limit操作是執行整個查詢,然后返回限定的行數。但某些情況下,這種處理方式很是浪費,因此可以進行優化,hive提供了這樣參數優化方式。

(1)參數優化說明:

表2.1.6-1 Hive控制並行Reduce任務數的優化參數列表
參數 默認值 優化值 參數說明
hive.limit.optimize.enable false true

該參數用於是否啟用limit優化

當使用limit語句時,對源數據進行抽樣。

該參數默認是關閉的。

hive.limit.row.max.size 100000 100000

該參數用於在使用limit做數據的子集查詢時保證的最小行數數據量。

hive.limit.optimize.limit.file true 10

該參數用於在使用limit做數據子集查詢時,采樣的最大文件數。

hive.limit.optimize.fetch.max true 50000

該參數用於當使用簡單limit數據抽樣時,允許的最大行數。

(2)參數文件配置:

啟用桶Map連接優化參數配置示例:

  <property>
    <name>hive.limit.optimize.enable</name>
    <value>true</value>
    <description>Whether to enable to optimization to trying a smaller subset of data for simple LIMIT first.</description>
  </property>
  <property>
    <name>hive.limit.row.max.size</name>
    <value>100000</value>
    <description>When trying a smaller subset of data for simple LIMIT, how much size we need to guarantee each row to have at least.
  </description>
  </property>
  <property>
    <name>hive.limit.optimize.limit.file</name>
    <value>10</value>
    <description>When trying a smaller subset of data for simple LIMIT, maximum number of files we can sample.
  </description>
  </property>

  <property>
    <name>hive.limit.optimize.fetch.max</name>
    <value>50000</value>
    <description>
      Maximum number of rows allowed for a smaller subset of data for simple LIMIT, if it is a fetch query.
      Insert queries are not restricted by this limit.
    </description>
  </property>

2.2.3啟用MapReduce嚴格模式

Hive提供了一個嚴格模式,可以防止用戶執行那些可能產生負面影響的查詢。Hive提供了參數可進行約束,即啟用MapReduce嚴格模式

對此,筆者認為沒有必要啟用該參數,而應該養成良好地寫sql語句的習慣應當在每一次寫sql語句時,時刻提醒自己防止災難發生的可能。

此外,一旦該參數啟用嚴格模式,會影響到其他參數的性能。因此不建議從配置文件配置該參數。

(1)參數優化說明:

表2.1.6-1 Hive控制並行Reduce任務數的優化參數列表
參數 默認值 優化值 參數說明
hive.mapred.mode 為空 strict

該參數用於是否啟用MapReduce嚴格模式

當使用limit語句時,對源數據進行抽樣。

推薦該參數值配置成nonstrict

該參數默認是關閉的。

(2)參數文件配置:

啟用桶Map連接優化參數配置示例:

  <property>
    <name>hive.mapred.mode</name>
    <value>strict</value>
    <description>Deprecated; use hive.strict.checks.* settings instead.</description>
  </property>

注:嚴格模式禁止3種類型的查詢:

1)對於分區表,where子句中不包含分區字段過濾條件的查詢語句不允許執行(很扯淡的限制)。

2)對於使用了order by子句的查詢,要求必須使用limit子句(這是很雞肋的做法),否則不允許執行。

3)限制笛卡爾積查詢。(該種查詢有時候是必須的,但應該盡量避免,繞道而行。)

2.3存儲格式選擇優化

Hive所支持的存儲格式有:TextFile、SequenceFile、RCFile、Avro Files、ORC Files、Parquet

(1)Hive所支持的存儲格式說明

1)TextFile:    

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

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

2)SequenceFile:

SequenceFile是Hadoop API 提供的一種二進制文件,它將數據以<key,value>的形式序列化到文件中。

這種二進制文件內部使用Hadoop 的標准的Writable 接口實現序列化和反序列化它與Hadoop API中的MapFile 是互相兼容的。

Hive 中的SequenceFile 繼承自Hadoop API 的SequenceFile,不過它的key為空,使用value 存放實際的值, 這樣是為了避免MR 在運行map 階段的排序過程

3)RCFile

RCFile是Hive推出的一種專門面向列的數據格式。 它遵循“先按列划分,再垂直划分”的設計理念。

當查詢過程中,針對它並不關心的列時,它會在IO上跳過這些列。

需要說明的是,RCFile在map階段從 遠端拷貝仍然是拷貝整個數據塊,並且拷貝到本地目錄后RCFile並不是真正直接跳過不需要的列,並跳到需要讀取的列,

而是通過掃描每一個row group的頭部定義來實現的,但是在整個HDFS Block 級別的頭部並沒有定義每個列從哪個row group起始到哪個row group結束。

所以在讀取所有列的情況下,RCFile的性能反而沒有SequenceFile高。

4)ORC File

ORCFile代表了優化排柱狀的文件格式

ORC文件格式提供了一種將數據存儲在Hive表中的高效方法。

這個文件系統實際上是為了克服其他Hive文件格式的限制而設計的。

Hive從大型表讀取,寫入和處理數據時,使用ORC文件可以提高性能。

5)Parquet

Parquet是一個面向列的二進制文件格式。

Parquet對於大型查詢的類型是高效的。

對於掃描特定表格中的特定列的查詢,Parquet特別有用。

Parquet使用壓縮Snappy,gzip;目前Snappy默認。

6)Avro Files

AVRO是開源項目,為Hadoop提供數據序列化和數據交換服務。

可以在Hadoop生態系統和以任何編程語言編寫的程序之間交換數據。

Avro是基於大數據Hadoop的應用程序中流行的文件格式之一。

(2)存儲格式對比

1)對比1

表2.2-1 存儲格式對比
存儲格式 存儲方式 特點
TextFile 行存儲

存儲空間消耗比較大,並且壓縮的text 無法分割和合並。

查詢的效率最低,可以直接存儲,加載數據的速度最高。

SequenceFile 行存儲

存儲空間消耗最大,壓縮的文件可以分割和合並。

查詢效率高,需要通過text文件轉化來加載。

RCFile

數據按行分塊,

每塊按照列存儲

存儲空間最小,

查詢的效率最高 ,

需要通過text文件轉化來加載,

加載的速度最低。

壓縮快 快速列存取。

讀記錄盡量涉及到的block最少 。

讀取需要的列只需要讀取每個row group 的頭部定義。

讀取全量數據的操作 性能可能比sequencefile沒有明顯的優勢。

ORCFile

數據按行分塊,

每塊按照列存儲

壓縮快,快速列存取 ,效率比rcfile高,是rcfile的改良版本。
Parquet 列存儲

相對於PRC,Parquet壓縮比較低,查詢效率較低,

不支持update、insert和ACID.但是Parquet支持Impala查詢引擎。

2)對比2

如果僅僅是在HIve中存儲和查詢,建議使用ORC格式,如果在Hive中存儲,而使用Impala查詢,建議使用Parquet。

3)對比3

     
對比項

Parquet:http://parquet.apache.org

Orc:http://orc.apache.org

發展狀態 目前是Apache開源的頂級項目,列式存儲引擎 目前是Apache開源的頂級項目,列式存儲引擎
開發語言 Java Java
主導公司 Twitter/Cloudera Hortonworks

 ACID

不支持 支持ACID事務

修改操作

(update,delete)

不支持 支持

支持索引

(統計信息)

粗粒度索引

block/group/chunk級別統計信息

粗粒度索引

file/stripe/row級別統計信息,

不能精確到列建立索引

支持的查詢引擎 Apache Drill、Impala Apache Hive
查詢性能 Orc性能更高一點 Orc性能更高一點
壓縮比 Orc壓縮比更高 Orc壓縮比更高
列編碼 支持多種編碼,字典,RLE,Delta等 支持主流編碼,與Parquet類似


免責聲明!

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



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