【Hive三】Hive理論

1. Hive基礎

<!-- TOC -->java

<!-- /TOC -->node

Hive基本概念

引入緣由:

  • – 對存在HDFS上的文件或HBase中的表進行查詢時,是要手工寫一堆MapReduce碼
  • – 對於統計任務,只能由動MapReduce的程序員才能搞定
  • – 耗時耗力,更多精力沒有有效的釋放出來

Hive是什麼

  • Hive基於一個統一的查詢分析層,經過SQL語句的方式對HDFS上的數據進行查詢、統計和分析程序員

  • Hive是一個SQL解析引擎,將SQL語句轉譯成MR而後再Hadoop平臺上運行,達到快速開發的目的sql

  • Hive中的表是 純邏輯 表,就只是表的定義等,即表的元數據。本質就是Hadoop的目錄/文件,達到了元數據與數據存儲分離的目的數據庫

  • Hive自己不存儲數據,它徹底依賴HDFS和MapReduce。apache

  • Hive的內容是讀多寫少,不支持對數據的改寫和刪除(0.14版本以後,Hive支持更新刪除功能,但須要手動進行配置 )服務器

  • Hive中沒有定義專門的數據格式,由用戶指定,須要指定三個屬性:分佈式

    • 列分隔符oop

      • \n****
    • 行分隔符優化

      • 空格、\t、\001
    • 讀取文件數據的方法

      • TextFileSequenceFile(二進制,是hadoop提供的一種二進制文件,<key,value>形式序列化到文件中,java writeable接口進行序列化和反序列化)、RCFile(是Hive專門推出的一種面向列的數據格式)
  • 爲何選擇Hive

    由於簡單!!

    select word, count(*)
    from (
    select
    explode(split(sentence, ' ')) as word
    from article
    ) t
    group by word
  • Hsql與傳統sql區別

    Hsql sql
    數據存儲 HDFS、 Hbase Local FS
    數據格式 用戶自定義 系統決定
    數據更新 不支持(把以前的數據覆蓋) 支持
    索引 有(0.8版以後增長)
    執行 MapReduce Executor
    執行延遲
    可擴展性 高(UDF、 UDAF,UDTF)
    數據規模 大(數據大於TB)
    數據檢查 讀時模式 寫時模式
  • UDF,UDAF,UDTF

    1. UDF:直接應用於select語句,一般查詢的時候,須要對字段作一些格式化處理(大小寫轉換),特色:一進一出,1比1

    2. UDAF:多對一場景,group by

    3. UDTF:一對多場景

  • 讀時模式 vs 寫時模式

    1. 讀時模式:只有hive讀的時候纔會檢查、解析字段和schema,優勢:加載數據很迅速,由於在寫的過程當中是不須要解析數據

    2. 寫時模式:缺點:寫的慢,須要創建一些索引、壓縮、數據一致性、字段檢查等,優勢:讀的時候會獲得優化

  • 與傳統關係型數據庫特色比較

    1. hive和關係數據庫存儲文件的系統不一樣,hive使用的是hadoop的HDFS(hadoop的分佈式文件系統),關係數據庫則是服務器本地的文件系統;

    2. hive使用的計算模型是mapreduce,而關係數據庫則是本身設計的計算模型

    3. 關係數據庫都是爲實時查詢的業務進行設計的,而hive則是爲海量數據作數據挖掘設計的,實時性不好

    4. Hive很容易擴展本身的存儲能力和計算能力,這個是繼承hadoop的,而關係數據庫在這個方面要比數據庫差不少。

Hive數據管理

四種數據模型

  • Table(默認表,也稱內部表)
  • External Table(外部表)
  • Partition(分區表)
  • Bucket(分桶表)
    1. Hive會針對某一個列進行桶組織,一般對列值作hash
    2. 優化查詢、方便採樣

Hive內部表和外部表

  • Hive的create建立表的時候,選擇的建立方式:

    1. create table(內部表)
    2. create external table(外部表)
  • 內部表 vs 外部表

    1. 差異:在對內部表操做的時候若是經過Hive對錶進行刪除,那麼表結構和表中的數據也會刪除,反之使用外部表的的話作刪除操做時不會刪除數據,只會刪除表結構,因此儘可能使用外部表

Hive數據類型

  • 原生數據類型

    • TINYINT
    • SMALLINT
    • INT
    • BIGINT
    • BOOLEAN
    • FLOAT
    • DOUBLE
    • STRING
    • BINARY(Hive 0.8.0以上纔可用)
    • TIMESTAMP(Hive 0.8.0以上纔可用)
  • 複合類型

    • Arrays:ARRAY<data_type>
    • Maps:MAP<primitive_type, data_type>
    • Structs:STRUCT<col_name: data_type[COMMENT col_comment],……>
    • Union:UNIONTYPE<data_type, data_type,……>
  • 複合類型的做用

  • Hive Sql -- join in MR

Hive的優化

Map的優化:

  • – 做業會經過input的目錄產生一個或者多個map任務。 set dfs.block.size(=128)

  • – Map越多越好嗎?是否是保證每一個map處理接近文件塊的大小?

  • – 如何合併小文件,減小map數?

set mapred.max.split.size=100000000;
  set mapred.min.split.size.per.node=100000000;
  set mapred.min.split.size.per.rack=100000000;
  set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHive`InputFormat;
  • – 如何適當的增長map數?
set mapred.map.tasks=10;
  • – Map端聚合 hive.map.aggr=true ,Mr中的Combiners

Reduce 的優化

  • hive.exec.reducers.bytes.per.reducer;reduce任務處理的數據量

  • 調整reduce的個數:

    • 設置reduce處理的數據量

    • set mapred.reduce.tasks=10

    select pt,count(1)
    from popt_tbaccountcopy_mes
    where pt = '2012-07-04' group by pt;
    寫成
    select count(1)
    from popt_tbaccountcopy_mes
    where pt = '2012-07-04';

一個Reduce:

  • 沒有group by

  • order by(可使用distribute by和sort by)

  • 笛卡爾積

分區裁剪(partition)

  • – Where中的分區條件,會提早生效,沒必要特地作子查詢,直接Join和GroupBy

笛卡爾積

  • – join的時候不加on條件或者無效的on條件,Hive只能使用1個reducer來完成笛卡爾積

Map join

  • /*+ MAPJOIN(tablelist) */,必須是小表,不要超過1G,或者50萬條

  • 假設有A表、B表,有A.join(B),若是A表示小表的話,可考慮是否將A表放入到內存中(小表儘可能少於1G),

Union all

  • 先作union all再作join或group by等操做能夠有效減小MR過程,儘管是多個Select,最終只有一個mr,數據不去重

  • union操做不會產生重複記錄但效率稍低一些,union all會產生重複數據但效率比union高一些

Multi-insert & multi-group by

  • – 從一份基礎表中按照不一樣的維度,一次組合出不一樣的數據

  • – FROM from_statement

  • – INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1)]select_statement1 group by key1

  • – INSERT OVERWRITE TABLE tablename2 [PARTITION(partcol2=val2 )]select_statement2 group by key2

Automatic merge

  • – 當文件大小比閾值小時,hive會啓動一個mr進行合併

  • – hive.merge.mapfiles = true 是否和並 Map 輸出文件,默認爲 True

  • – hive.merge.mapredfiles = false 是否合併 Reduce 輸出文件,默認爲 False

  • – hive.merge.size.per.task = 25610001000 合併文件的大小

Multi-Count Distinct

  • – 必須設置參數:set hive.groupby.skewindata=true;

  • – select dt, count(distinct uniq_id), count(distinct ip)

  • – from ods_log where dt=20170301 group by dt

Hive優化-- 大小表關聯

  • 緣由

    • Hive在進行join時,按照join的key進行分發,而在join左邊的表的數據會首先讀入內存,若是左邊表的key相對分散,讀入內存的數據會比較小,join任務執行會比較快;而若是左邊的表key比較集中,而這張表的數據量很大,那麼數據傾斜就會比較嚴重,而若是這張表是小表,則仍是應該把這張表放在join左邊。
  • 思路

    • 將key相對分散,而且數據量小的表放在join的左邊,這樣能夠有效減小內存溢出錯誤發生的概率
    • 使用map join讓小的維度表先進內存。
  • 方法

    • Small_table join big_table

Hive優化-- 大大表關聯

  • 緣由

    • 日誌中有一部分的userid是空或者是0的狀況,致使在用user_id進行hash分桶的時候,會將日誌中userid爲0或者空的數據分到一塊兒,致使了過大的斜率。
  • 思路

    • 把空值的key變成一個字符串加上隨機數,把傾斜的數據分到不一樣的reduce上,因爲null值關聯不上,處理後並不影響最終結果。
  • 方法

    • on case when (x.uid = '-' or x.uid = '0‘ or x.uid is null) then concat('dp_hive_search',rand()) else x.uid end = f.user_id;
相關文章
相關標籤/搜索