Hadoop-Impala讓分區最優化的方法

1.1  Hadoop-Impala十大優化系列之(1)—分區表優化-8個方法讓分區最優化impala表分區


       默認情況下,表中的所有數據文件都位於一個目錄中。分區是在加載過程中基於從一個或多個列的值的物理上劃分數據的技術,以加快對這些列進行測試的查詢。例如,一個school_records表分區在年柱,各有不同的年值一個單獨的數據目錄,所有這一年的數據是存儲在目錄中的數據文件。一個查詢,其中包括一個條件,如 WHERE condition such as YEAR=1966, YEAR IN(1989,1999), or YEAR BETWEEN 1984 AND 1989 ,可以檢查只有從適當的目錄或目錄的數據文件,大大減少了數據讀取和測試。


以下幾個方面介紹分區使用和管理維護:
1)       什麼時候使用分區表
2)       對於分區表的SQL語句
3)       靜態和動態分區子句
4)       分區的子目錄的權限
5)       查詢的分區修剪
6)       分區鍵列
7)       設置分區的不同的文件格式
8)       管理分區


請參見附加外部分區表的HDFS目錄結構爲例,說明創建分區表的語法,基礎目錄結構在HDFS,和如何把分區表數據文件存儲的 Impala外其他地方在HDFS。 
Parquet 是 Impala表分區的流行格式是因爲它很適合處理海量的數據。看到Impala  表分區Parquet 表性能考慮查詢性能。 


1.1.1  什麼時候使用分區表      


分區通常是適合以下情況:
       表是非常大的,在讀取整個數據集需要一個不切實際的時間量。
       總是或幾乎總是在分區列上的條件查詢的表。在我們的一個表分區的例子,SELECT COUNT(*) FROM school_records WHERE year= 1985是有效的,只有對數據的一小部分;但SELECT COUNT(*) FROM school_records具有處理每年一個單獨的數據文件,從而更全面的工作比在非分區表。如果您經常查詢基於姓氏的表,學生證,等等,而不需要測試一年,你可能不會有這樣的劃分方式。


       有合理的基數列(不同值的數量)。如果一個列只有一個小的值,例如男性或女性,你沒有得到太多的效率,通過消除只有約50%的數據讀取每個查詢。如果一列只有幾行的匹配值,處理目錄的數量可以成爲一個限制因素,並在每個目錄中的數據文件可能太小,利用Hadoop的機制在多兆字節的數據分塊傳輸。例如,您可能會在一年內分區統計數據,通過年和月的存儲銷售數據,以及年、月和日的Web流量數據。(一些高容量的輸入數據的用戶甚至可能劃分到每小時和每分鐘。)


數據已通過提取、變換、和加載(ETL)管道。分區列的值從原始數據文件中剝離,並由目錄名錶示,因此將數據加載到分區表中涉及到某種形式的轉換或預處理。


1.1.2  對於分區表的SQL語句


      在Impala的SQL語法,分區影響這些語句: 

      createtable :您在創建表時指定了一個PARTITIONEDBY條件,以確定分區列的名稱和數據類型。這些列不包含在表的列中的主要列表中。
       在CDH 5.7 /Impala2.5及更高,你也可以使用分區在創建表的條款爲SELECT語句。此語法允許您使用一個語句來創建一個分區表,將數據複製到它,並基於插入的數據中的值創建新的分區。

       改變表:可以添加或刪除分區,可以使用一個龐大的數據集的不同部分工作。你可以爲一個特定的分區指定的HDFS目錄保存數據文件。通過日期值劃分的數據,您可能會“老化”不再相關的數據。

       注:如果您正在創建一個分區,並指定它的位置,爲最大效率,使用一個單一的更改表語句,包括添加分區和位置子句,而不是單獨的語句與添加分區和設置位置子句。


1.1.3  靜態和動態分區子句

      在SQL語句中指定的所有分區列稱爲靜態分配,因爲語句影響單個預測分區。例如,您使用靜態分區與一個改變表語句,隻影響一個分區,或與一個插入語句插入到同一個分區中的所有值:
insertinto t1 partition(x=10,y='a') select c1 from some_other_table;

      當你指定分區鍵列在INSERT語句,但離開了價值,Impala決定插入哪個分區。這種技術被稱爲動態分區:

     
[Plain Text] 純文本查看 複製代碼
?
1
2
3
4
5
insert intot1 partition(x,y='b') select c1, c2 from some_other_table;
-- Createnew partition if necessary based on variable year, month, and day; insert asingle value.
insert intoweather partition(year, month, day) select'cloudy',2014,4,21;
-- Createnew partition if necessary for specified year and month but variable day;insert a single value.
insert intoweather partition(year=2014, month=04, day) select'sunny',22;


      在分區子句中指定的更重要的列,在“選擇列表”中需要的列數較少。在選擇列表中的尾隨列以順序替換沒有指定值的分區鍵列。



1.1.4  分區的子目錄的權限


      默認情況下,如果插入語句創建任何新的子目錄下面的分區表,這些子目錄分配權限的用戶默認的HDFS的權限。使每個子目錄具有相同的權限爲在HDFS的父目錄,指定--insert_inherit_permissions啓動選項的impalad守護。


1.1.5  查詢的分區精簡

      分區精簡指的是一個查詢可以跳過一個或多個分區對應的數據文件的機制。如果您可以安排查詢,從查詢執行計劃中刪除大量的不必要的分區,查詢使用更少的資源,因此比例更快,更可擴展性。


       例如,如果一個表是由列年,月,日,分區,然後在條款如年爲2013年,其中<2010,或1995和1998讓Impala跳過數據文件在指定範圍外的所有分區之間。同樣地,在一年的2013和1和3之間的一個月,可以精簡更多的分區,讀取數據文件只有一年的一部分。
      要檢查分區修剪對於查詢的有效性,在運行它之前檢查解釋輸出爲查詢的結果。例如,這個示例顯示了一個有3個分區的表,其中查詢只讀取其中的1個分區。符號#partitions=1/3在解釋計劃證實了impala可以做適當的分區修剪。

[Plain Text] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[localhost:21000]> insert into census partition (year=2010) values ('Smith'),('Jones');
[localhost:21000]> insert into census partition (year=2011) values('Smith'),('Jones'),('Doe');
[localhost:21000]> insert into census partition (year=2012) values ('Smith'),('Doe');
[localhost:21000]> select name from census where year=2010;
+-------+
| name  |
+-------+
| Smith |
| Jones |
+-------+
[localhost:21000]> explain select name from censuswhere year=2010;
+------------------------------------------------------------------+
| ExplainString                                                   |
+------------------------------------------------------------------+
| PLANFRAGMENT 0                                                 |
|   PARTITION: UNPARTITIONED                                       |
|                                                                  |
|   1:EXCHANGE                                                    |
|                                                                 |
| PLANFRAGMENT 1                                                  |
|   PARTITION: RANDOM                                              |
|                                                                 |
|   STREAM DATA SINK                                              |
|     EXCHANGE ID: 1                                               |
|     UNPARTITIONED                                               |
|                                                                 |
|   0:SCAN HDFS                                                   |
|      table=predicate_propagation.census#partitions=1/3 size=12B |
+------------------------------------------------------------------+


      對於在查詢的每個階段實際讀取和處理的數據量的報表,在運行查詢後立即檢查彙總命令的輸出。對於一個更詳細的分析,看配置文件命令的輸出;它包括在配置文件輸出的開始附近的這個相同的彙總報告。
1)       檢查是否對查詢進行分區修剪
2)       什麼SQL構造分區修剪工作
3)       動態分區修剪


1.1.5.1 檢查是否對查詢進行分區修剪


      要檢查分區修剪對於查詢的有效性,在運行它之前檢查解釋輸出爲查詢的結果。例如,這個示例顯示了一個有3個分區的表,其中查詢只讀取其中的1個分區。符號#分區= 1 / 3在解釋計劃證實了impala可以做適當的分區修剪。

[Plain Text] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[localhost:21000]> insert into census partition (year=2010) values ('Smith'),('Jones');
[localhost:21000]> insert into census partition (year=2011) values('Smith'),('Jones'),('Doe');
[localhost:21000]> insert into census partition (year=2012) values ('Smith'),('Doe');
[localhost:21000]> select name from census where year=2010;
+-------+
| name  |
+-------+
| Smith |
| Jones |
+-------+
[localhost:21000]> explain select name from censuswhere year=2010;
+------------------------------------------------------------------+
| ExplainString                                                  |
+------------------------------------------------------------------+
| PLANFRAGMENT 0                                                 |
|   PARTITION: UNPARTITIONED                                       |
|                                                                 |
|   1:EXCHANGE                                                    |
|                                                                 |
| PLANFRAGMENT 1                                                 |
|   PARTITION: RANDOM                                              |
|                                                                 |
|   STREAM DATA SINK                                              |
|     EXCHANGE ID: 1                                              |
|     UNPARTITIONED                                               |
|                                                                 |
|   0:SCAN HDFS                                                   |
|      table=predicate_propagation.census#partitions=1/3 size=12B |
+------------------------------------------------------------------+



      對於在查詢的每個階段實際讀取和處理的數據量的報表,在運行查詢後立即檢查彙總命令的輸出。對於一個更詳細的分析,看配置文件命令的輸出;它包括在配置文件輸出的開始附近的這個相同的彙總報告。


1.1.5.2 什麼SQL構造分區修剪工作 

     impala甚至可以做分區修剪的情況下,分區鍵列是不能直接比較恆定,通過傳遞性質的WHERE子句中的其他部分。這種技術被稱爲謂詞的傳播,並在impala1.2.2後來。在這個示例中,普查表包括另一列,該列指示當數據被收集時,發生在10年的時間間隔內。即使查詢並不比分區鍵列(年)到一個恆定值,impala可以推斷出,只有= 2010是必需的分區的一年,又一次只讀取了3個分區1。

[Plain Text] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[localhost:21000]> drop table census;
[localhost:21000]> create table census (name string, census_year int) partitioned by (yearint);
[localhost:21000]> insert into census partition (year=2010) values('Smith',2010),('Jones',2010);
[localhost:21000]> insert into census partition (year=2011) values('Smith',2020),('Jones',2020),('Doe',2020);
[localhost:21000]> insert into census partition (year=2012) values('Smith',2020),('Doe',2020);
[localhost:21000]> select name from census where year = census_year and census_year=2010;
+-------+
|name  |
+-------+
| Smith |
| Jones |
+-------+
[localhost:21000]> explain select name from censuswhere year = census_year andcensus_year=2010;
+------------------------------------------------------------------+
| ExplainString                                                  |
+------------------------------------------------------------------+
| PLANFRAGMENT 0                                                 |
|   PARTITION: UNPARTITIONED                                       |
|                                                                 |
|   1:EXCHANGE                                                     |
|                                                                 |
| PLANFRAGMENT 1                                                 |
|   PARTITION: RANDOM                                              |
|                                                                  |
|   STREAM DATA SINK                                              |
|     EXCHANGE ID: 1                                              |
|     UNPARTITIONED                                               |
|                                                                  |
|   0:SCAN HDFS                                                   |
|      table=predicate_propagation.census#partitions=1/3 size=22B |
|      predicates: census_year = 2010, year =census_year          |
+------------------------------------------------------------------+



      如果一個視圖適用於一個分區表,任何分區修剪都認爲在原始查詢和任何額外的謂詞在查詢中的語句,是指視圖的子句。impala1.4之前,只有在條款對原始查詢從創建視圖的語句進行分區修剪。
      在解析函數和分區表的查詢中,只發生在由解析函數調用的分區中命名的列的分區修剪。例如,如果一個解析函數查詢有一個條款,如在年= 2016,使查詢修剪所有其他年分區的方法是包括在解析函數調用劃分;例如,在(分區的一年,other_columns other_analytic_clauses)。


1.1.5.3 動態分區修剪

      原來的機制用於修剪分區是靜態分區修剪,在其中的條件,在條款進行分析,以確定提前哪些分區可以安全地跳過。在Impala 2.5 /CDH5.7及更高版本,impala可以執行動態分區修剪,在分區信息中查詢收集,和impala修剪不必要的分區方式是提前預測不切實際。
例如,如果分區鍵列進行比較的文字值WHERE子句中,impala可以執行靜態分區修剪規劃階段在閱讀相關的分區:


[Plain Text] 純文本查看 複製代碼
?
1
2
3
-- Thequery only needs to read 3 partitions whose key values are known ahead of time.
-- That'sstatic partition pruning.
SELECTCOUNT(*) FROM sales_table WHERE year IN (2005, 2010, 2015);


      動態分區修剪涉及使用信息只有在運行時,如查詢結果:

[Plain Text] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
createtable yy (s string) partitioned by (year int) stored as parquet;
insert intoyy partition (year) values ('1999', 1999), ('2000', 2000),
  ('2001', 2001), ('2010',2010);
computestats yy;
createtable yy2 (s string) partitioned by (year int) stored as parquet;
insert intoyy2 partition (year) values ('1999', 1999), ('2000', 2000),
  ('2001', 2001);
computestats yy2;
-- Thequery reads an unknown number of partitions, whose key values are only
-- known atrun time. The 'runtime filters' lines show how the information about
-- thepartitions is calculated in query fragment 02, and then used in query
-- fragment00 to decide which partitions to skip.
explainselect s from yy2 where year in (select year from yy where year between 2000and 2005);
+----------------------------------------------------------+
| ExplainString                                          |
+----------------------------------------------------------+
| EstimatedPer-Host Requirements: Memory=16.00MB VCores=2 |
|                                                          |
|04:EXCHANGE [UNPARTITIONED]                              |
| |                                                       |
| 02:HASHJOIN [LEFT SEMI JOIN, BROADCAST]                |
| |  hash predicates: year = year                          |
| |  runtime filters: RF000 <- year                       |
| |                                                       |
||--03:EXCHANGE [BROADCAST]                               |
| |  |                                                    |
| |  01:SCAN HDFS [dpp.yy]                                 |
| |     partitions=2/4 files=2 size=468B                   |
| |                                                       |
| 00:SCANHDFS [dpp.yy2]                                  |
|    partitions=2/3 files=2 size=468B                      |
|    runtime filters: RF000 -> year                       |
+----------------------------------------------------------+



      在這種情況下,impala評價子查詢,子查詢結果發送所有Impala節點參與查詢,然後每個impalad守護進程採用動態分區剪枝優化與相關鍵值只讀分區。

動態分區修剪是特別有效的查詢,涉及幾個大的分區表的聯接。評估聯接謂詞的子句,通常需要從某些表的所有分區中讀取數據。如果該查詢的WHERE子句中引用的分區鍵列,impala現在經常可以跳過閱讀許多的分區在評估條款。動態分區修剪優化減少了在查詢過程中的網絡存儲和傳輸的I / O和中間數據量的量。

      當溢出到磁盤功能是一個連接節點在查詢激活,impala不產生任何運行過濾器,主機上的連接操作。查詢中的其他連接節點不受影響。
      動態分區修剪是運行時過濾功能的一部分,它適用於其他類型的查詢,除了對分區表的查詢。看到運行的impala查詢有關此功能的詳細的過濾。


1.1.6  分區鍵列

      您選擇的列作爲分區鍵應該是經常用於篩選查詢結果的重要的大型查詢。流行的例子是一些組合的一年,一個月,和一天的數據有相關的時間值,和地理區域的數據時,與一些地方。

      基於時間的數據,分離出獨立的部分納入自己的欄目,因爲impala不能劃分一個時間戳列。

      該分區列的數據類型不具有對存儲要求的效果顯著,因爲從這些列的值不存儲在數據文件中,而他們是在HDFS目錄名稱的字符串。

      在CDH 5.7 /impala2.5及更高版本,可以使optimize_partition_key_scans查詢選項來加快查詢的速度,僅指分區鍵列,如選擇最大(年)。默認情況下,此設置沒有啓用,因爲如果表中包含沒有實際數據的分區目錄,則查詢的行爲將略有不同。看到optimize_partition_key_scans查詢詳情。

      分區表可以包含複雜的類型列。所有分區鍵列必須爲標量類型。

      記住,當impala查詢存儲在HDFS的數據,它是最有效的使用多字節的文件利用HDFS塊大小。實木複合地板表,塊的大小(和數據文件大小是理想)2 256 MB,後來impala。因此,避免指定太多的分區鍵列,這可能會導致單個分區只包含少量的數據。例如,如果你每天收到1個數據,你可能會被一年一個月,一天一天;而如果你每分鐘收到5個數據,你可能會被一年、一個月、一天、一小時、一分鐘劃分。如果你與一個地理成分的數據,你可能會劃分郵政編碼,如果您有許多兆字節的每個郵政編碼數據,但如果沒有的話,你可能會被一些大的區域,如城市、州或國家劃分。狀態

      如果你經常運行彙總等功能min(),max(),計數(不同的)分區鍵列,考慮啓用optimize_partition_key_scans查詢優化查詢。這一特徵在CDH 5.7 /impala2.5及更高版本可用。看到optimize_partition_key_scans查詢選項,這個選項適用於查詢的種類,和輕微的差異如何分區進行評估時,該查詢選項啓用。


1.1.7  設置分區的不同的文件格式 

     分區表有靈活性,使用不同的分區使用不同的文件格式。(關於不同的文件格式支持背景信息看,impala、impala和Hadoop文件格式。)例如,如果你在文本格式最初收到數據,然後接收新的數據格式,並最終開始RCFile,拼花格式接收數據,這些數據可以駐留在同一個表的查詢。您只需要確保表的結構,以便使用不同的文件格式的數據文件駐留在單獨的分區中。
      例如,這裏是你如何可以從文本到地板的數據你不同年接收數據:

[Plain Text] 純文本查看 複製代碼
?
1
2
3
4
5
6
[localhost:21000]> create table census (name string) partitioned by (year smallint);
[localhost:21000]> alter table census add partition (year=2012); -- Text format;
[localhost:21000]> alter table census add partition (year=2013); -- Text format switches toParquet before data loaded;
[localhost:21000]> alter table census partition (year=2013) set fileformat parquet;
[localhost:21000]> insert into census partition (year=2012) values ('Smith'),('Jones'),('Lee'),('Singh');
[localhost:21000]> insert into census partition (year=2013) values('Flores'),('Bogomolov'),('Cooper'),('Appiah');


      在這一點上,HDFS目錄 year=2012包含一個文本格式的數據文件,而HDFS目錄 year=2013包含一個複合數據文件。和總是一樣,當加載不平凡的數據時,您將使用插入…選擇或加載數據以大批量導入數據,而不是插入…值,產生小的文件,是低效的現實世界的查詢。
       對於其他類型的文件,impala不能創造本身,你可以切換到蜂巢的問題修改表…設置文件格式報表和報表數據插入或負載有。切換回Impala後,發出聲明,刷新table_nameImpala承認任何分區或新添加的數據通過hive。


1.1.8  管理分區


      你可以添加,刪除,設定預期的文件格式,或一組數據文件HDFS位置個別分區impala表內。有關語法細節的更改表語句,並在包含分區的分區的管理表上設置不同的文件格式的不同的文件格式。


      注:如果您正在創建一個分區,並指定它的位置,爲最大效率,使用一個單一的更改表語句,包括添加分區和位置子句,而不是單獨的語句與添加分區和設置位置子句。


      當一個分區被刪除時,數據文件會發生什麼,取決於分區表是否被指定爲內部或外部的。對於內部(託管)表,數據文件已被刪除。例如,如果分區表中的數據是存儲在其他地方的原始數據文件的副本,則可以通過刪除不再需要的舊分區來保存磁盤空間,知道原始數據在需要時仍然可用。對於一個外部表,數據文件將被單獨留下。例如,刪除一個分區沒有刪除相關的文件讓impala考慮更小的分區,提高查詢效率和減少表的DDL操作的開銷;如果數據再次需要後,你可以再添加分區。看到的細節和例子的impala表概述。




作者:DBA_Hadoop
來源:blog.csdn
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章