13-Hive分桶優化

Hive數據倉庫

Hive參數

hive 參數、變量

  • hive當中的參數、變量,都是以命名空間開頭

  • hive 參數設置方式

    • 1、修改配置文件 ${HIVE_HOME}/conf/hive-site.xml

    • 2、啓動hive cli時,通過–hiveconf key=value的方式進行設置

      • 例:hive --hiveconf hive.cli.print.header=true
    • 3、進入cli之後,通過使用set命令設置

  • hive set命令

    • 在hive CLI控制檯可以通過set對hive中的參數進行查詢、設置

    • set設置:

      • set hive.cli.print.header=true;
    • set查看

      • set hive.cli.print.header
    • hive參數初始化配置

      • 當前用戶家目錄下的.hiverc文件
      • 如: ~/.hiverc
      • 如果沒有,可直接創建該文件,將需要設置的參數寫到該文件中,hive啓動運行時,會加載改文件中的配置。
    • hive歷史操作命令集

      • ~/.hivehistory

Hive分桶

分區與分桶區別:

  • 分區控制多級目錄
  • 分桶控制多個文件

hive 分桶

  • 分桶表是對列值取哈希值的方式,將不同數據放到不同文件中存儲
  • 對於hive中每一個表、分區都可以進一步進行分桶
  • 由列的哈希值除以桶的個數來決定每條數據劃分在哪個桶中

開啓支持分桶

  • set hive.enforce.bucketing=true;
  • 默認:false;設置爲true之後,mr運行時會根據bucket的個數自動分配reduce task個數。(用戶也可以通過mapred.reduce.tasks自己設置reduce任務個數,但分桶時不推薦使用)
  • 注意:一次作業產生的桶(文件數量)和reduce task個數一致

往分桶表中加載數據

  • insert into table bucket_table select columns from tbl;
  • insert overwrite table bucket_table select columns from tbl;

適用場景:

  • 數據抽樣( sampling )

    • 桶表 抽樣查詢

      • 語句

        • select * from bucket_table tablesample(bucket 1 out of 4 on columns);
      • TABLESAMPLE語法:

        • TABLESAMPLE(BUCKET x OUT OF y)
        • x:表示從哪個bucket開始抽取數據
        • y:必須爲該表總bucket數的倍數或因子
      • 例:

        • 當表總bucket數爲32時

        • TABLESAMPLE(BUCKET 3 OUT OF 8),抽取哪些數據?

          • 共抽取2(32/16)個bucket的數據,抽取第2、第18(16+2)個bucket的數據
        • TABLESAMPLE(BUCKET 3 OUT OF 256),抽取哪些數據?

      • 實操:

        • 建表

          • CREATE TABLE psn31( id INT, name STRING, age INT)
            ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’;
        • 測試數據

          • 1,tom,11
            2,cat,22
            3,dog,33
            4,hive,44
            5,hbase,55
            6,mr,66
            7,alice,77
            8,scala,88
        • 創建分桶表

          • CREATE TABLE psnbucket( id INT, name STRING, age INT)
            CLUSTERED BY (age) INTO 4 BUCKETS
            ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’;
        • 加載數據:

          • insert into table psnbucket select id, name, age from psn31;
        • 抽樣

          • select id, name, age from psnbucket tablesample(bucket 2 out of 4 on age);

Hive Lateral View

Lateral View用於和UDTF函數(explode、split)結合來使用

首先通過UDTF函數拆分成多行,再將多行結果組合成一個支持別名的虛擬表

主要解決在select使用UDTF做查詢過程中,查詢只能包含單個UDTF,不能包含其他字段、以及多個UDTF的問題

語法:

  • LATERAL VIEW udtf(expression) tableAlias AS columnAlias (’,’ columnAlias)

實例:

  • 需求:統計人員表中共有多少種愛好、多少個城市?

  • 數據

  • SQL

    • select count(distinct(myCol1)), count(distinct(myCol2)) from psn2
      LATERAL VIEW explode(likes) myTable1 AS myCol1
      LATERAL VIEW explode(address) myTable2 AS myCol2, myCol3;

Hive 視圖

和關係型數據庫中的普通視圖一樣,hive也支持視圖

特點:

  • 不支持物化視圖
  • 只能查詢,不能做加載數據操作
  • 視圖的創建,只是保存一份元數據,查詢視圖時才執行對應的子查詢
  • view定義中若包含了ORDER BY/LIMIT語句,當查詢視圖時也進行ORDER BY/LIMIT語句操作,view當中定義的優先級更高
  • view支持迭代視圖

View語法

  • 創建視圖:

    • CREATE VIEW [IF NOT EXISTS] [db_name.]view_name
      [(column_name [COMMENT column_comment], …) ]
      [COMMENT view_comment]
      [TBLPROPERTIES (property_name = property_value, …)]
      AS SELECT … ;
  • 查詢視圖:

    • select colums from view;
  • 刪除視圖:

    • DROP VIEW [IF EXISTS] [db_name.]view_name;

Hive 索引

目的:

  • 優化查詢以及檢索性能

創建索引:

  • create index t1_index on table psn2(name)
    as ‘org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler’ with deferred rebuild
    in table t1_index_table;

    • as:指定索引器;
    • in table:指定索引表,若不指定默認生成在default__psn2_t1_index__表中
  • create index t1_index on table psn2(name)
    as ‘org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler’ with deferred rebuild;

查詢索引:

  • show index on psn2;

重建索引(建立索引之後必須重建索引才能生效):

  • ALTER INDEX t1_index ON psn REBUILD;

刪除索引:

  • DROP INDEX IF EXISTS t1_index ON psn2;

Hive 運行方式

命令行方式cli:控制檯模式

  • 與hdfs交互

    • 執行執行dfs命令
    • 例:dfs –ls /
  • 與Linux交互

    • !開頭
    • 例: !pwd

腳本運行方式(實際生產環境中用最多)

  • hive -e “”
  • hive -e “”>aaa
  • hive -S -e “”>aaa
  • hive -f file
  • hive -i /home/my/hive-init.sql
  • hive> source file (在hive cli中運行)

JDBC方式:hiveserver2

web GUI接口 (hwi、hue等)

  • web界面安裝:

    • 下載源碼包apache-hive-*-src.tar.gz

    • 將hwi war包放在$HIVE_HOME/lib/

      • 製作方法:將hwi/web/*裏面所有的文件打成war包
      • cd apache-hive-1.2.1-src/hwi/web
      • jar -cvf hive-hwi.war *
    • 複製tools.jar(在jdk的lib目錄下)到$HIVE_HOME/lib下

    • 修改hive-site.xml

    hive.hwi.listen.host
    0.0.0.0


    hive.hwi.listen.port
    9999


    hive.hwi.war.file
    lib/hive-hwi.war

    • 啓動hwi服務(端口號9999)

      • hive --service hwi
    • 瀏覽器通過以下鏈接來訪問

      • http://node3:9999/hwi/

Hive 權限管理

Hive 權限管理

  • 三種授權模型:

    • Storage Based Authorization in the Metastore Server

      • 基於存儲的授權 - 可以對Metastore中的元數據進行保護,但是沒有提供更加細粒度的訪問控制(例如:列級別、行級別)
    • SQL Standards Based Authorization in HiveServer2

      • 概要基於SQL標準的Hive授權 - 完全兼容SQL的授權模型,推薦使用該模式。
    • Default Hive Authorization (Legacy Mode)

      • hive默認授權 - 設計目的僅僅只是爲了防止用戶產生誤操作,而不是防止惡意用戶訪問未經授權的數據。
  • Hive - SQL Standards Based Authorization in HiveServer2

    • 完全兼容SQL的授權模型

    • 除支持對於用戶的授權認證,還支持角色role的授權認證

      • role可理解爲是一組權限的集合,通過role爲用戶授權
      • 一個用戶可以具有一個或多個角色
      • 默認包含另種角色:public、admin
    • 限制:

      • 1、啓用當前認證方式之後,dfs, add, delete, compile, and reset等命令被禁用
      • 2、通過set命令設置hive configuration的方式被限制某些用戶使用
      • (可通過修改配置文件hive-site.xml中hive.security.authorization.sqlstd.confwhitelist進行配置)
      • 3、添加、刪除函數以及宏的操作,僅爲具有admin的用戶開放
      • 4、用戶自定義函數(開放支持永久的自定義函數),可通過具有admin角色的用戶創建,其他用戶都可以使用
      • 5、Transform功能被禁用
    • 配置hive-site.xml

    hive.security.authorization.enabled
    true

    -
    hive.server2.enable.doAs
    false

    -
    hive.users.in.admin.role
    root

    -
    hive.security.authorization.manager
    org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory

    -
    hive.security.authenticator.manager
    org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator

    • 角色的添加、刪除、查看、設置:

      • CREATE ROLE role_name; – 創建角色
      • DROP ROLE role_name; – 刪除角色
      • SET ROLE (role_name|ALL|NONE); – 設置角色
      • SHOW CURRENT ROLES; – 查看當前具有的角色
      • SHOW ROLES; – 查看所有存在的角色
    • 角色的授予、移除、查看

    • 權限:

      • SELECT privilege – gives read access to an object.
      • INSERT privilege – gives ability to add data to an object (table).
      • UPDATE privilege – gives ability to run update queries on an object (table).
      • DELETE privilege – gives ability to delete data in an object (table).
      • ALL PRIVILEGES – gives all privileges (gets translated into all the above privileges).
    • 權限的授予、移除、查看

Hive優化

核心思想:把Hive SQL 當做Mapreduce程序去優化

以下SQL不會轉爲Mapreduce來執行:

  • select僅查詢本表字段
  • where僅對本表字段做條件過濾

Hive抓取策略

  • Hive中對某些情況的查詢不需要使用MapReduce計算

  • Set hive.fetch.task.conversion=none/more;

    • none:所有執行MR
    • more:不一定

Explain 顯示執行計劃

  • EXPLAIN [EXTENDED] query

Hive運行方式:

  • 本地模式

    • 開啓本地模式:

      • set hive.exec.mode.local.auto=true;
    • 注意:

      • hive.exec.mode.local.auto.inputbytes.max默認值爲128M
      • 表示加載文件的最大值,若大於該配置仍會以集羣方式來運行
  • 集羣模式(默)

並行計算

  • 通過設置以下參數開啓並行模式:

    • set hive.exec.parallel=true;
  • 注意:hive.exec.parallel.thread.number

    • (一次SQL計算中允許並行執行的job個數的最大值)

嚴格模式

  • 通過設置以下參數開啓嚴格模式:

    • set hive.mapred.mode=strict;
    • (默認爲:nonstrict非嚴格模式)
  • 查詢限制:

    • 1、對於分區表,必須添加where對於分區字段的條件過濾;
    • 2、order by語句必須包含limit輸出限制;
    • 3、限制執行笛卡爾積的查詢。

Hive排序

  • Order By - 對於查詢結果做全排序,只允許有一個reduce處理

    • (當數據量較大時,應慎用。嚴格模式下,必須結合limit來使用)
  • Sort By - 對於單個reduce的數據進行排序

  • Distribute By - 分區排序,經常和Sort By結合使用

  • Cluster By - 相當於 Sort By + Distribute By

    • (Cluster By不能通過asc、desc的方式指定排序規則;
    • 可通過 distribute by column sort by column asc|desc 的方式)

Hive Join

  • Join計算時,將小表(驅動表)放在join的左邊

  • Map Join:在Map端完成Join

    • 兩種實現方式:

      • 1、SQL方式,在SQL語句中添加MapJoin標記(mapjoin hint)

        • 語法:

          • SELECT /*+ MAPJOIN(smallTable) */ smallTable.key, bigTable.value
            FROM smallTable JOIN bigTable ON smallTable.key = bigTable.key;
      • 2、開啓自動的MapJoin

  • 自動的mapjoin

    • 通過修改以下配置啓用自動的mapjoin:

      • set hive.auto.convert.join = true;

        • (該參數爲true時,Hive自動對左邊的表統計量,如果是小表就加入內存,即對小表使用Map join)
  • 相關配置參數:

    • hive.mapjoin.smalltable.filesize;

      • (大表小表判斷的閾值,如果表的大小小於該值則會被加載到內存中運行)
    • hive.ignore.mapjoin.hint;

      • (默認值:true;是否忽略mapjoin hint 即mapjoin標記)
    • hive.auto.convert.join.noconditionaltask;

      • (默認值:true;將普通的join轉化爲普通的mapjoin時,是否將多個mapjoin轉化爲一個mapjoin)
    • hive.auto.convert.join.noconditionaltask.size;

      • (將多個mapjoin轉化爲一個mapjoin時,其表的最大值)
  • 儘可能使用相同的連接鍵(會轉化爲一個MapReduce作業)

  • 大表join大表

    • 空key過濾:有時join超時是因爲某些key對應的數據太多,而相同key對應的數據都會發送到相同的reducer上,從而導致內存不夠。此時我們應該仔細分析這些異常的key,很多情況下,這些key對應的數據是異常數據,我們需要在SQL語句中進行過濾。
    • 空key轉換:有時雖然某個key爲空對應的數據很多,但是相應的數據不是異常數據,必須要包含在join的結果中,此時我們可以表a中key爲空的字段賦一個隨機的值,使得數據隨機均勻地分不到不同的reducer上

Map-Side聚合

  • 通過設置以下參數開啓在Map端的聚合:

    • set hive.map.aggr=true;
  • 相關配置參數:

    • hive.groupby.mapaggr.checkinterval:

      • map端group by執行聚合時處理的多少行數據(默認:100000)
    • hive.map.aggr.hash.min.reduction:

      • 進行聚合的最小比例(預先對100000條數據做聚合,若聚合之後的數據量/100000的值大於該配置0.5,則不會聚合)
    • hive.map.aggr.hash.percentmemory:

      • map端聚合使用的內存的最大值
    • hive.map.aggr.hash.force.flush.memory.threshold:

      • map端做聚合操作是hash表的最大可用內容,大於該值則會觸發flush
    • hive.groupby.skewindata

      • 是否對GroupBy產生的數據傾斜做優化,默認爲false

合併小文件

  • 文件數目小,容易在文件存儲端造成壓力,給hdfs造成壓力,影響效率

  • 設置合併屬性

    • 是否合併map輸出文件:hive.merge.mapfiles=true
    • 是否合併reduce輸出文件:hive.merge.mapredfiles=true;
    • 合併文件的大小:hive.merge.size.per.task=25610001000
  • 去重統計

    • 數據量小的時候無所謂,數據量大的情況下,由於COUNT DISTINCT操作需要用一個Reduce Task來完成,這一個Reduce需要處理的數據量太大,就會導致整個Job很難完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替換

控制Hive中Map以及Reduce的數量

  • Map數量相關的參數

    • mapred.max.split.size

      • 一個split的最大值,即每個map處理文件的最大值
    • mapred.min.split.size.per.node

      • 一個節點上split的最小值
    • mapred.min.split.size.per.rack

      • 一個機架上split的最小值
  • Reduce數量相關的參數

    • mapred.reduce.tasks

      • 強制指定reduce任務的數量
    • hive.exec.reducers.bytes.per.reducer

      • 每個reduce任務處理的數據量
    • hive.exec.reducers.max

      • 每個任務最大的reduce數

Hive - JVM重用

  • 適用場景:

    • 1、小文件個數過多
    • 2、task個數過多
  • 通過 set mapred.job.reuse.jvm.num.tasks=n; 來設置

    • (n爲task插槽個數)
  • 缺點:設置開啓之後,task插槽會一直佔用資源,不論是否有task運行,直到所有的task即整個job全部執行完成時,纔會釋放所有的task插槽資源

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