【Hive】《Hive編程指南》梳理

轉載請註明出處

第1章  基礎知識

Hive不支持事務(標註:低版本不支持,高版本ACID支持)

Hive不支持OLTP(聯機事務處理)所需要的關鍵功能,而更接近成爲一個OLAP(聯機分析技術)工具。

MapReduce是一種計算模型,該模型可將大型數據處理任務分解成很多單個的、可以在服務器集羣中並行執行的任務。

Hive的優點:Hive不僅提供了一個熟悉SQL的用戶所熟悉的編程模型,還消除了大量通用代碼。

HBase是一個分佈式的,可伸縮的數據存儲,其支持行級別的數據更新,快速查詢和行級事務。(不支持多行事務)

 

第2章 基礎操作

1. 命令行界面CLI

2. Thrift服務提供了可遠程訪問其他進程的功能,也提供使用JDBC和ODBC的功能。

3. 所有Hive客戶端都需要一個metasotreservice(元數據服務),Hive使用這個服務來存儲表模式信息和其他元數據信息。

輸出更多信息:

hive>set -v;

Hive中“一次使用”命令

hive -e "select * from mytable limit 3";

增加-S可以開啓靜默模式

hive -S -e "select * from mytable limit 3" > /tmp/myquery

當用戶不能完整記清楚某個屬性名時,可以這樣查找:

hive -S -e "set" | grep warehouse

從文件中執行Hive查詢

hive -f /xxx.hql

查看操作歷史命令:Hive會將最近的100,00行命令記錄到文件$HOME/.hivehistory中

執行shell命令

用戶不需要退出hive CLI就可以執行簡單的bash shell命令,只要在命令前加上!並以;結尾。如:

hive> !/bin/echo “hello”

在Hive內使用Hadoop的dfs命令

hive> dfs -ls / ;

 

第3章 數據類型和文件格式

Hive具有一個特殊的功能,那就是其對於數據在文件中的編碼方式具有非常大的靈活性,大多數的數據庫對數據具有完全的控制,這種控制既包括對數據存儲到磁盤的過程的控制,也包括對數據生命週期的控制。

Hive會隱式地將類型轉換爲兩個整型類型中值較大的那個類型。

顯示轉換: cast(s AS INT)

集合數據類型:

1. STRUCT   struct('hello','world')

2. MAP          map('first','zhang','last','di')

3.ARRAY       Array('Zhang','Di')

create table employees (

name  string,

salary  float.

subordinates ARRAY<string>,      //以json格式輸出

deductions MAP<string,float>,

address  STRUCT<street;string,city:string,state:string.zip:int>

 )

explode(字段) 將字段轉換成表結構

      row format delimited fields terminated by ...

寫時模式(schema on wirte):傳統數據庫是寫時模式,即數據在寫入數據庫時對模式進行檢查。

讀時模式(schema on read):Hive不會在數據加載時進行驗證,而是在查詢時進行也就是讀時模式。

  1. 如果字段少於定義的個數,則返回null
  2. 如果字段非數值(規定數值),則返回null

 

第4章 數據定義

可以用正則表達式匹配篩選數據庫名:

show database like ‘h*’;

用戶可以爲數據庫添加一些和相關的鍵-值對屬性信息:

create database xxx with dbproperties ('creator' = ' zhangdi', 'date' = '2012-01-02');

if exists

 drop database if exists  xxxx;

級聯刪除數據庫中的表

  drop database xxx cascade

修改數據庫

  alter database  xxx  set dbproperties ('edited-by' = 'xxx')

tblproperties  按鍵-值對的格式爲表增加額外的文檔說明

默認情況下,Hive總是將創建的表目錄放置在這個表所屬的數據庫目錄之後

拷貝表:create table if not exists xxx like yyyy;

擴展信息: describe extended xxx;

外部表: create external table xxx;

因爲表是外部的,所以Hive並非認爲其完全擁有這份數據。分區內的數據不會被刪掉。內部表中元數據與數據會被同時刪除。

Hive的strict模式:

如果表中的數據以及分區個數都非常大的話,執行這樣一個包含所有分區的查詢可能會觸發一個巨大的MapReduce任務。

在strict模式下,如果對分區表進行查詢而where子句沒有加分區過濾的話,會禁止提交這個任務。

查看錶中的所有分區:

show partitions xxx

show partitions xxx partition(country='US');

Hive不關心一個分區對應的分區目錄是否存在或者分區目錄下是否有文件

  1. 存儲格式:textfile、sequencefile、rcfile
  2. 序列化 / 反序列化:Avro、orc、regex、thrift、parquet、csv、jsonserde

數據回收站功能:

fs.trash.interval 規定了回收站檢查點時間 (例如:1440,24小時),數據刪除將會被轉移到分佈式文件系統中的用戶根目錄下的.Trash目錄下,即:/user/$USER/.Trash/

用戶可以將誤刪的文件重新移動到正確的文件目錄下來重新存儲數據。

Alter table 僅僅會修改表元數據,表數據本身不會有任何修改

表重命名:alter table xxx rename to xx

增加、修改和刪除表分區:alter table xxx partition(...) location ...

修改列信息:alter table xxx change  column xxxxxx

增加列信息:alter table xxx add columns(user_id string)

刪除或替換列:alter table xxx replace columns...

修改表屬性:alter table xxx set tblproperties(...);

修改存儲屬性 alter table xxx ... set fileformat sequencefile;

"鉤子"回調函數:

alter table log_message TOUCH partition (year=2012, month=1, day=1);

當表中存儲的文件在Hive之外被修改了,就會觸發鉤子的執行。

分區文件打包成HAR文件:

alter table log_message archive partition (year=2012, month=1, day=1);

防止分區被刪除和被查詢:

alter table log_message partition (year=2012, month=1, day=1) ENABLE NO_DROP;

alter table log_message partition (year=2012, month=1, day=1) ENABLE OFFLINE;

 

第5章 數據操作

加載數據:

  1. load
  2. 通過查詢語句

insert overwrite table employee partition (country ='US', state = 'OR')

select * from staged_employees se where se.cnty='US' and se.st='OR';

  1. 動態分區插入

可以基於查詢參數推斷出需要創建的分區名稱

insert overwrite table employees

partition (country, state)

select ......, se.onty, se.st

from staged_employees se;

查詢結果插入到分區中,非靜態

 

第6章 HiveQL 查詢

case when then語句

select name, salary,

CASE

    WHEN  salsary < 5000.0 THEN 'low'

    WHEN  salsary >= 5000.0 THEN 'high'

END AS bracket from employees;

本地模式:

Hive中對某些情況的查詢可以不必使用MapReduce,也就是所謂的本地模式:

1. 對於select * from employees;

Hive可以簡單地讀取employees對應的存儲目錄下的文件,然後輸出到控制檯

2. 對於where語句中過濾條件只是分區字段的情況,也無需MapReduce過程

規避浮點數的問題:

1.如果從textfile中讀取數據,那麼Hive會讀取到字符串“0.2”,然後轉換成真實的數字

2.顯式指出0.2爲float類型

           cast(0.2 AS FLOAT)

Like 和 RLike

Like:相對簡單的匹配

RLike:通過Java的正則表達式來指定匹配條件

與join相關:大多數情況下Hive會對每個join連接對象啓動一個MapReduce任務。

join優化:

用戶需要保證連續查詢中的表的大小從左到右是依次增加的

用戶並非總是將最大的表放置在查詢語句的最後面,用戶可以顯示標記哪張是大表:

select /*STREAMTABLE(s)*/ s.ymd,s.name from stock s join dividends d on s.ymd=d.ymd and s.name = d.name where s.name="apple"

左半開連接:

      LEFT SEMI-JOIN   返回左邊表的記錄

左半開比通常的inner join更高效,對於左表中一條指定的記錄,在右邊表中一旦找到匹配的記錄,Hive就會立即停止掃描,從這點來看,左邊表中選擇的列是可以預測的。

Map-side join

  如果所有表中有一個表是小表,那麼可以在最大的表通過mapper的時候將小表完全放入內存中,Hive可以在map端執行連接的過程,這是因爲Hive可以和內存中的小表進行逐一匹配,從而省略掉常規連接操作需要的reduce過程,而且可以同時減少map過程的執行步驟。

set hive.auto.convert.join=true;

select /*MAPJOIN(s)*/ s.ymd,s.name from stock s join dividends d on s.ymd=d.ymd and s.name = d.name where s.name="apple"

分桶也有這種優化

set hive.optimize.bucketmapjoin=true;

  1. order by:對查詢結構結果執行一個全局排序,執行時間可能會過長。
  2. sort by:Hive增加一個可供選擇的方式,只會在每一個reducer中對數據進行排序,也就是執行一個局部排序過程。
  3. distribute by:控制map的輸出在reducer中如何劃分。在map過程中保證具有相同性質的值分發到同一個reducer中。避免了mapreudce過程中,map過程中根據相同的哈希值均勻地分發到多個reducer中去。(Hive要求distribute by 寫在sort by語句之前)
  4. cluster by = sort by + distribute by

select s.ymd, s.symbol from stock s distribute by s.symbol sort by s.symbol asc;

select * from stock s cluster by s.symbol;

數據塊抽樣

Hive提供一種抽樣百分比進行抽樣方式,基於行數。按照輸入路徑下的數據塊百分比進行抽樣:

select * from numbersflat TABLESAMPLE(0.1 PERCENT) s;

抽樣不一定適用所有的文件格式,抽樣的最小單元是一個HDFS數據塊,如果塊128MB

 

第7章 HiveQL視圖

視圖:視圖不能夠作爲insert語句或load命令的目標表

           視圖是隻讀的

 

第8章 HiveQL索引

create index employees_index on table employees (country) as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' 

//BitMap //指定索引處理器

with deferred rebuild       //新索引會呈現空白狀態

idxproperties('creator'='me')

in table employees_index_table

prtition by (country,name)

comment 'comment by victorz'

重建索引

alter index employees_index on table employees partition (country='US') rebuild

顯示索引

show formatted index on employees;

刪除索引

drop index employee_index on table employees;

 

第9章 模式設計

Hive可以從一個數據源產生多個數據聚合,而不續每次聚合都要重新掃描一次

from history

insert overwrite sales select * from where action='purchased'

insert overwrite credits select * from where action='returned';

分桶表數據存儲

並非所有數據集都能修成合理分區,分桶將數據集分解成更容易管理的若干部分的另一種技術。

create table weblog (user_id int) partition by (dt string) clustered by (user_id) into 96 buckets;

分桶的優點:1.桶數量固定,所以沒有數據撥動。2.有利於高效執行map-side JOIN

 

第10章 調優

explain

儘管我們查詢會將其輸出寫入到控制檯,但Hive實際上會先將輸入寫入到一個臨時文件中,越複雜的查詢通常會引入越多的stage,而通常stage越多就需要越多的時間完成任務。

explain extended 產生更多解釋信息

限制調整

hive.limit.optimize.enable

hive.limit.row.max.size

hive.limit.optimize.limit.file

並行執行

某個特定的job可能包含衆多的階段,而這些階段可能並非完全相互依賴的。

<property>

  <name>hive.exec.parallel</name>

  <value>true</value>

</property>

嚴格模式(hive.mapred.mode = strict)

  1. 對於分區表,除非where語句中含有分區字段過濾條件來限制數據範圍,否則不准許執行。用戶不能掃描所有分區。
  2. 對於使用了order by語句的查詢,必須使用limit語句。強制要求用戶添加limit語句可以防止reducer額外執行很長的時間。
  3. 限制笛卡爾乘積查詢。

不可控情況:

select * from table_x join table_y

where table_x.id = table_y.id;

可控情況:

select * from table_x join table_y

on (table_x.id = table_y.id)

調整mapper和reducer個數

Hive是按照輸入的數據量大小來確定reducer個數的(Hive 默認個數是3),可以通過dfs -count 命令來計算輸入量大小

set hive.exec.reducers.bytes.per.reducer = 75000000;

             hive.exec.reducers.max 阻止某個查詢消耗太多的reducer資源

JVM重用

JVM重用可以使得JVM實例在同一個job中重新使用N次

<property>

    <name>mapred.job.reuse.jvm.num.tasks</name>

    <value>10</value>

</property> 

虛擬列

 set hive.exec.rowoffset=true;

1.劃分的輸入文件名   INPUT_FILE_NAME

2.文件中的塊內偏移量  BLOCK_OFFSET_INSIDE_FILE

3.文件的行偏移量  ROW_OFFSET_INSIDE_BLOCK

select INPUT_FILE_NAME, BLOCK_OFFSET_INSIDE_FILE, ROW_OFFSET_INSIDE_BOLCK line from hive_text where line like '%hive%' limit 2;

 

第11章 其他文件格式和壓縮方法

壓縮通常會節約可觀的磁盤空間,壓縮同樣可以增加吞吐量和性能。減少載入內存的數據量而提高I/O吞吐量會更加提高網絡傳輸的性能。

hive -e "set io.compression.codecs"  //查看內置的編碼器

開啓中間壓縮

對中間數據進行壓縮可以減少job中map和reduce task 間的數據傳輸量

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

<value>true</value>

最終結果壓縮

<name>hive.exec.compress.output</name>

<value>false</value>

Sequence file

sequence file 存儲格式可以將一個文件劃分成多個塊,然後採用一種可分割的方式對塊進行壓縮。

Sequence file提供了3種壓縮方式:NONERECORDBOLOCK,默認是RECORD級別。

<name>mapred.output.compression.type</name>

<value>BLOCK</value>

存檔分區

Hadoop中有一種存儲格式爲HAR(Hadoop Archive)

一個HAR文件就像在HDFS文件系統中的一個TAR文件一樣,是一個單獨的文件。其內部可以存放多個文件和文件夾。

alter table hive_test archive partition(folder = 'docs');

alter table hive_test unarchive partition(folder='docs');

 

第12章 開發

 

第13章 函數

函數中的操作:

show functions;

describe function xxx;

describe function extended xxx;//更詳細的文檔

  1. 用戶自定義函數(UDF):數學函數、字符串操作函數
  2. 用戶自定義聚合函數(UDAF):聚合方法通常和group by組合使用
  3. 表生成函數(UDTF):

例如:select array(1,2,3) from table;

explode()函數以array類型數據作爲輸入。

LATERAL VIEW:通過lateral view 可以方便地將explode這個UDTF得到的行轉列的結果集合在一起提供服務。

select name,sub from employees lateral view explode(subordinates) subView AS sub;

用戶自己編輯UDF步驟:

1.編寫java實現:

編寫一個UDF,需要繼承UDF類並實現evaluate()函數,而evaluate()處理後的值會返回給Hive

代碼中的@Description(...)表示Java總註解,註明了關於函數的文檔說明

2.打包jar包,添加jar包,temporary只會在當前會話有效

ADD JAR /full/path/to/zodiac.jar

create temporary function zodiac as 'org.apache.hadoop.hive.contrib.udf.example.UDFZodiacSign';

3.如果永久使用,可以將相關語句增加到$HOME/.hiverc

4.使用完可以刪除此函數

drop temporary function if exists zodiac;

------------------------------------------------------------------------------------------------------------------

1.GenericUDF具有更復雜的抽象概念,其支持更好的null值處理同時可以處理一些標準的UDF無法支持的編程操作。initialize()

2.evaluate

3.getDisplayString() 其用於Hadoop task內部。在使用到這個函數來展示調試信息

4.ADD JAR  /path/to/jar.jar;

5.create temporary function nv1 as 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFNv1';

6.select nvl(1,2) as col1, nvl(null,5) as col2, nvl(null,"stuff") as col3 from src limit 1;

nvl() 要求兩個參數,如果第一個是非null值,那就返回這個值,如果第一個參數是null,則返回第二個值。

------------------------------------------------------------------------------------------------------------------

Group_concat:

select name, GROUP_CONCAT(firendname SEPARATOR ',')

from people

group by name;

宏命令:

宏比UDF更省事

     //名稱

create temporary MACRO SIGMOID  (x double) 1.0 / (1.0 + EXP(-x))

select SIGMOID(2) from src limit 1;

 

第14章 Streaming

Streaming提供了另一種處理數據方式。在streaming job中,Hadoop Streaming API會爲外部進程開啓I/O管道。然後數據會被傳給這個進程,其會從標準輸入中讀取數據,然後通過標準輸出來寫結果數據。

MAP() ,  REDUCE() , TRANSFORM()

1.恆等變換

/bin/cat 將傳遞給它的數據直接輸出

select TRANSFORM(a,b) USING '/bin/cat' as newA, newB from default.a;

2.改變類型,轉換其他數據類型

select TRANSFORM(col1,col2) USING '/bin/cat' as (newA INT, newB DOUBLE) from a;

3.投影變換

使用cut命令提取或者映射出特定的字段

select TRANSFORM(a,b) USING '/bin/cut -f1' as newA, newB from a;

4.操作轉換

select TRANSFORM(a,b) USING '/bin/sed s/4/10/' as newA, newB from a;

第15章 自定義Hive文件和記錄格式

闡述create table句式

  1. stored  as  sequencefile
  2. row format delimited
  3. serde
  4. inputformat
  5. outputformat

stored as sequencefile = inputformat 'org.apache.hadoop.mapred.SequenceFileInputFormat'

                         = outputformat 'org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat'

文件格式:

1.SequenceFile

包含鍵-值對的二進制文件。hadoop相關的工具共享,在Hadoop生態系圈中適用

2.RCfile

列式存儲,壓縮,一些列式存儲並不需要物理存儲null值的列

不可以打開SequenceFile的工具打開RCFile,可以使用rcfilecat查看RCFile文件內容

bin/hive --service rcfilecat /user/hive/warehouse/....

3.SerDe 序列化、反序列化

4.CSV 和 TSV SerDe

  1. CSV 逗號分隔符
  2. TSV 回車分隔符

5.XML UDF  p213

6.JSON SerDe

create external table messages(

mag_id BIGINT.

tstamp  STRING

)

ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.JsonSerde'

with serdeproperties(  //准許用戶定義一些可以傳遞給SerDe的屬性信息

 "msg_id"="$.id"

 "tstamp"="$.created_at"

)

location '/data/messages';

7.Avro Hive SerDe

Avro 是一個序列化系統,其主要特定是它是一個進化的模式驅動的二進制數據存儲模式。

Serde ‘org.apache.hadoop.hive.serde2.avro.AvroSerDe’

 

第16章 Hive的Thrift服務

Hive具有一個可選的組件叫做HiveServer或者HiveThrift,其准許通過指定端口訪問Hive

HiveServer使用Thrift提供服務。Thrift提供一個接口語言,通過這些接口,Thrift編譯器可以產生網絡RPC的多種程序語言的客戶端的代碼。

Hive會話會直接連接到一個JDBC數據庫,這個數據庫用作元數據存儲數據庫。Hive提供一個可選的組件名爲ThriftMetaStore

 

第17章 NoSQL

HiveStorageHandler是Hive用於連接如NOSQL存儲的主要接口。

Hbase,通過過濾下推裁剪返回給Hive行數據

create table xx(key int,name string)

stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

with serdeproperties ("hbase.columns.mapping"=":key,stock:val") //列映射

tblproperties("hbase.table.name"="stock");//表明映射

 

第18章 安全

Hadoop的安全引入了多個變化,主要針對Kerberos安全認證的支持

Kerberos准許客戶端和服務端相互認證,客戶端的每次請求都帶有憑證ticket信息

在TaskTracker上執行的任務(task)都是由執行任務(job)的用戶來執行的,所有Hadoop組件從頭到尾要使用Kerberos安全認證。

 umask 創建文件使用

<name>hive.metastore.authorization.storage.checks</name>

<value>true</value>

爲true時,如果用戶沒有權限刪除表底層文件,Hive會阻止用戶來刪除這個表

開啓授權功能

set hive.security.authorization.enabled=true;

<name>hive.security.authorization.enabled</name>

<value>true</value>

組是由系統外部進行控制的,而角色是由Hive內部進行控制的

自動授權

<name>hive.security.authorization.createtable.owner.grants</name>

<value>select,drop</value>

 

第19章 鎖

在Hadoop中通常是一次寫入的,細粒度鎖是不需要的。

Hadoop和Hive是多租戶系統,鎖協調是必要的。且需要由單獨的系統zookeeper進行協調。

show locks

顯式上鎖:

LOCK TABLE xxx EXCLUSIVE

顯式解鎖

UNLOCK TABLE xxx

 

第22章 HCatalog

作用:1.使Hive元數據爲基於Hadoop的其他工具所公用,爲MapRduce 和 Pig提供連接器

    2.提供命令行工具

    3.提供消息通知服務(給Oozie等)

1.讀數據

HCatlog 提供一個 HCatInputFormat 供 Mapreduce用戶讀取數據

2.HCatRecord

HCatlog用於交互的類

3.寫數據

HCatOutputFormat

命令行 (hcat 命令)

非Hive訪問Hive元數據

/usr/bin/hcat -e "create table xx (user string, url string);"

p270  Hive的HCatalog架構

一些其他概念:

  1. JSON:Javascript Object Natation
  2. Map:輸入的鍵-值對集合會轉換成新的鍵-值對集合
  3. JobTracker:使用Hadoop的MapReduce的所有任務的頂層控制器
  4. Task:task實在單個集羣上的工作最小單元,每個task都會啓動一個JVM進程,每個map和reduce調用都有自身的task。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章