(第7篇)靈活易用易維護的hadoop數據倉庫工具——Hive

   Hive

hive是基於Hadoop的一個數據倉庫工具,可以將結構化的數據文件映射爲一張數據庫表,並提供完整的sql查詢功能,Hive 定義了簡單的類 SQL 查詢語言,稱爲 HQL,它允許熟悉 SQL 的用戶查詢數據可以將 sql語句轉換爲MapReduce任務進行運行,不必開發專門的MapReduce。畢竟會寫SQL的人比寫JAVA的人多,這樣可以讓一大批運營人員直接獲取海量數據。在數據倉庫建設中,HIVE靈活易用且易於維護,十分適合數據倉庫的統計分析。

本章內容:

1) Hive簡介

2) Hive基礎組成

3) Hive執行流程

4) Hive基礎操作

1. Hive基礎原理

hive是建設在Hadoop之上,Hive包括如下組件:CLI(command line interface)、JDBC/ODBC、Thrift Server、WEB GUI、MetaStoreDriver(Complier、Optimizer和Executor)。

wKioL1jGA1iyo1VhAADCMNOmNK8712.png 

1) Driver組件:包括Complier、Optimizer和Executor,它的作用是將我們寫的HiveQL(類SQL)語句進行解析、編譯優化,生成執行計劃,然後調用底層的MapReduce計算框架。

2) Metastore組件:元數據服務組件存儲hive的元數據,hive的元數據存儲在關係數據庫裏,hive支持的關係數據庫有derby、mysql。Hive還支持把metastore服務安裝到遠程的服務器集羣裏,從而解耦hive服務和metastore服務。

3) Thrift服務:thrift是facebook開發的一個軟件框架,它用來進行可擴展且跨語言的服務的開發,hive集成了該服務,能讓不同的編程語言調用hive的接口。

4) CLI:command line interface,命令行接口。

5) Thrift客戶端: hive架構的許多客戶端接口是建立在thrift客戶端之上,包括JDBC和ODBC接口。

6) WEBGUI:hive客戶端提供了一種通過網頁的方式訪問hive所提供的服務。

用戶接口主要有三個:CLIClient  WUI。其中最常用的是CLI,公司內可通過堡壘機連接ssh [email protected],直接輸入hive,就可連接到HiveServer

Hive的metastore組件是hive元數據集中存放地。Metastore組件包括兩個部分:metastore服務和後臺數據的存儲。後臺數據存儲的介質就是關係數據庫,例如hive默認的嵌入式磁盤數據庫derby,還有mysql數據庫。Metastore服務是建立在後臺數據存儲介質之上,並且可以和hive服務進行交互的服務組件,默認情況下,metastore服務和hive服務是安裝在一起的,運行在同一個進程當中。我也可以把metastore服務從hive服務裏剝離出來,metastore獨立安裝在一個集羣裏,hive遠程調用metastore服務,這樣我們可以把元數據這一層放到防火牆之後,客戶端訪問hive服務,就可以連接到元數據這一層,從而提供了更好的管理性和安全保障。使用遠程的metastore服務,可以讓metastore服務和hive服務運行在不同的進程裏,這樣也保證了hive的穩定性,提升了hive服務的效率。

對於數據存儲,Hive沒有專門的數據存儲格式,可以非常自由的組織Hive中的表,只需要在創建表的時候告訴Hive數據中的列分隔符和行分隔符,Hive就可以解析數據。Hive中所有的數據都存儲在HDFS中,存儲結構主要包括數據庫、文件、表和視圖。Hive中包含以下數據模型:Table內部表,External Table外部表,Partition分區,Bucket桶。Hive默認可以直接加載文本文件,還支持sequence file 、RCFile。

Hive的數據模型介紹如下:

1) Hive數據庫

類似傳統數據庫的DataBase,例如 hive >create database test_database;

2) 內部表

Hive的內部表與數據庫中的表在概念上是類似。每一個Table在Hive中都有一個相應的目錄存儲數據。例如一個表hive_test,它在HDFS中的路徑爲/home/hdp_lbg_ectech/warehouse/hdp_lbg_ectech_bdw.db/hive_test,其中/home/hdp_lbg_ectech/warehouse是在hive-site.xml中由${hive.metastore.warehouse.dir}指定的數據倉庫的目錄,所有的Table數據(不包括外部表)都保存在這個目錄中。刪除表時,元數據與數據都會被刪除。

建表語句示例:

CREATE EXTERNAL TABLE hdp_lbg_ectech_bdw.hive_test

(`userid` string COMMENT'')

ROW FORMAT DELIMITED FIELDS TERMINATED BY'\001';

load data  inpath ‘/home/hdp_lbg_ectech/resultdata/test.txt’overwrite into table hive_test;

3) 外部表

外部表指向已經在HDFS中存在的數據,可以創建分區。它和內部表在元數據的組織上是相同的,而實際數據的存儲則有較大的差異。內部表在加載數據的過程中,實際數據會被移動到數據倉庫目錄中。刪除表時,表中的數據和元數據將會被同時刪除。而外部表只有一個過程,加載數據和創建表同時完成(CREATE EXTERNAL TABLE ……LOCATION),實際數據是存儲在LOCATION後面指定的 HDFS 路徑中,並不會移動到數據倉庫目錄中。當刪除一個外部表時,僅刪除該表的元數據,而實際外部目錄的數據不會被刪除,推薦使用這種模式。

4) 分區

Partition相當於數據庫中的列的索引,但是Hive組織方式和數據庫中的很不相同。在Hive中,表中的一個分區對應於表下的一個目錄,所有的分區數據都存儲在對應的目錄中。

一般是按時間、地區、類目來分區,便於局部查詢,避免掃描整個數據源。

5) 

Buckets是將表的列通過Hash算法進一步分解成不同的文件存儲。它對指定列計算hash,根據hash值切分數據,目的是爲了並行,每一個Bucket對應一個文件。例如將userid列分散至32個bucket,首先對userid列的值計算hash,對應hash值爲0的HDFS目錄爲/home/hdp_lbg_ectech/resultdata/part-00000;hash值爲20的HDFS目錄爲/home/hdp_lbg_ectech/resultdata/part-00020。

6) Hive的視圖

視圖與傳統數據庫的視圖類似。目前只有邏輯視圖,沒有物化視圖;視圖只能查詢,不能Load/Insert/Update/Delete數據;視圖在創建時候,只是保存了一份元數據,當查詢視圖的時候,纔開始執行視圖對應的那些子查詢;

2. Hive基礎操作

1) DDL操作包括

刪除表

修改表結構

創建/刪除視圖

創建數據庫和顯示命令

增加分區,刪除分區

重命名錶

修改列的名字、類型、位置、註釋

增加/更新列

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name

  [(col_name data_type [COMMENT col_comment], ...)]

  [COMMENT table_comment]

  [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]

  [CLUSTERED BY (col_name, col_name, ...)

  [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]

  [ROW FORMAT row_format]

  [STORED AS file_format]

  [LOCATION hdfs_path]

CREATE TABLE 創建一個指定名字的表。如果相同名字的表已經存在,則拋出異常;用戶可以用 IF NOT EXIST 選項來忽略這個異常

EXTERNAL 關鍵字可以讓用戶創建一個外部表,在建表的同時指定一個指向實際數據的路徑(LOCATION)

LIKE 允許用戶複製現有的表結構,但是不復制數據

COMMENT可以爲表與字段增加描述

ROW FORMAT

DELIMITED [FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char]

[MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]

| SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]

用戶在建表的時候可以自定義 SerDe 或者使用自帶的 SerDe。如果沒有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,將會使用自帶的 SerDe。在建表的時候,用戶還需要爲表指定列,用戶在指定表的列的同時也會指定自定義的 SerDe,Hive 通過 SerDe 確定表的具體的列的數據。

STORED AS

SEQUENCEFILE

| TEXTFILE

| RCFILE

| INPUTFORMAT input_format_classname OUTPUTFORMAT             output_format_classname

如果文件數據是純文本,可以使用 STORED AS TEXTFILE。如果數據需要壓縮,使用 STORED AS SEQUENCE 。

例子1創建簡單表

CREATE TABLE pokes (foo INT, bar STRING);

例子2:創建外部表

CREATE EXTERNAL TABLE page_view(viewTime INT, userid BIGINT,

     page_url STRING, referrer_url STRING,

     ip STRING COMMENT 'IP Address of the User',

     country STRING COMMENT 'country of origination')

COMMENT 'This is the staging page view table'

ROW FORMAT DELIMITED FIELDS TERMINATED BY '\054'

STORED AS TEXTFILE

LOCATION '<hdfs_location>';

例子3:創建分區表

CREATE TABLE par_table(viewTime INT, userid BIGINT,

     page_url STRING, referrer_url STRING,

     ip STRING COMMENT 'IP Address of the User')

COMMENT 'This is the page view table'

PARTITIONED BY(date STRING, pos STRING)

ROW FORMAT DELIMITED ‘\t’

FIELDS TERMINATED BY '\n'

STORED AS SEQUENCEFILE;

例子4:創建Bucket表

CREATE TABLE par_table(viewTime INT, userid BIGINT,

     page_url STRING, referrer_url STRING,

     ip STRING COMMENT 'IP Address of the User')

COMMENT 'This is the page view table'

PARTITIONED BY(date STRING, pos STRING)

CLUSTERED BY(userid) SORTED BY(viewTime) INTO 32 BUCKETS

ROW FORMAT DELIMITED ‘\t’

FIELDS TERMINATED BY '\n'

STORED AS SEQUENCEFILE;

例子5:創建表並創建索引字段ds

CREATE TABLE invites (foo INT, bar STRING) PARTITIONED BY (ds STRING);

例子6:複製一個空表

CREATE TABLE empty_key_value_store

  LIKE key_value_store;

例子7:顯示所有表

SHOW TABLES;

例子8:按正則條件(正則表達式)顯示錶

SHOW TABLES '.*s';

例子9:添加一列

ALTER TABLE pokes ADD COLUMNS (new_col INT);

例子10:添加一列並增加列字段註釋

ALTER TABLE invites ADD COLUMNS (new_col2 INT COMMENT 'a comment');

例子11:更改表名

ALTER TABLE events RENAME TO 3koobecaf;

例子12:刪除列

DROP TABLE pokes;

例子13:增加、刪除分區

增加:

ALTER TABLE table_name ADD [IF NOT EXISTS] partition_spec [ LOCATION 'location1' ] partition_spec [ LOCATION 'location2' ] ...

      partition_spec:

  : PARTITION (partition_col = partition_col_value, partition_col = partiton_col_value, ...)

刪除:

  ALTER TABLE table_name DROP partition_spec, partition_spec,...

例子14:重命名錶

ALTER TABLE table_name RENAME TO new_table_name

例子15:修改列的名字、類型、位置、註釋

ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]

這個命令可以允許改變列名、數據類型、註釋、列位置或者它們的任意組合

例子16:創建/刪除視圖

CREATE VIEW [IF NOT EXISTS] view_name [ (column_name [COMMENT column_comment], ...) ][COMMENT view_comment][TBLPROPERTIES (property_name = property_value, ...)] AS SELECT

增加視圖

如果沒有提供表名,視圖列的名字將由定義的SELECT表達式自動生成

如果修改基本表的屬性,視圖中不會體現,無效查詢將會失敗

視圖是隻讀的,不能用LOAD/INSERT/ALTER

 

DROP VIEW view_name

刪除視圖

例子17:創建數據庫

CREATE DATABASE name

例子18:顯示命令

show tables;

show databases;

show partitions ;

show functions

describe extended table_name dot col_name

2) DML操作元數據存儲

hive不支持用insert語句一條一條的進行插入操作,也不支持update操作。數據是以load的方式加載到建立好的表中。數據一旦導入就不可以修改。

DML包括:

INSERT插入

UPDATE更新

DELETE刪除

向數據表內加載文件

將查詢結果插入到Hive表中

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]

 

Load 操作只是單純的複製/移動操作,將數據文件移動到 Hive 表對應的位置。

filepath

相對路徑,例如:project/data1

絕對路徑,例如: /user/hive/project/data1

包含模式的完整 URI,例如:hdfs://namenode:9000/user/hive/project/data1

例子1:向數據表內加載文件

LOAD DATA LOCAL INPATH './examples/files/kv1.txt' OVERWRITE INTO TABLE pokes;

例子2:加載本地數據,同時給定分區信息

LOAD DATA LOCAL INPATH './examples/files/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');

例子3:加載本地數據,同時給定分區信息

LOAD DATA INPATH '/user/myname/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');

例子4:將查詢結果插入Hive表

基本模式:

INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement

 

多插入模式:

FROM from_statement

INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1

[INSERT OVERWRITE TABLE tablename2 [PARTITION ...] select_statement2] ...

 

自動分區模式:

INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement

例子3:將查詢結果寫入HDFS文件系統

INSERT OVERWRITE [LOCAL] DIRECTORY directory1 SELECT ... FROM ...

 

FROM from_statement

INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1

[INSERT OVERWRITE [LOCAL] DIRECTORY directory2 select_statement2]

 

數據寫入文件系統時進行文本序列化,且每列用^A 來區分,\n換行

例子3:INSERT INTO

INSERT INTO  TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement

3) DQL操作數據查詢SQL

DQL包括:

基本的Select 操作

基於Partition的查詢

Join

基本Select操作:

SELECT [ALL | DISTINCT] select_expr, select_expr, ...

FROM table_reference

[WHERE where_condition]

[GROUP BY col_list [HAVING condition]]

[   CLUSTER BY col_list

| [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list]

]

[LIMIT number]

 

使用ALL和DISTINCT選項區分對重複記錄的處理。默認是ALL,表示查詢所有記錄。DISTINCT表示去掉重複的記錄

Where 條件

類似我們傳統SQL的where 條件

目前支持 AND,OR ,0.9版本支持between

IN, NOT IN

不支持EXIST ,NOT EXIST

 

ORDER BY與SORT BY的不同

ORDER BY 全局排序,只有一個Reduce任務

SORT BY 只在本機做排序

 

Limit

Limit 可以限制查詢的記錄數

例子1:按先件查詢

SELECT a.foo FROM invites a WHERE a.ds='<DATE>';

例子2:將查詢數據輸出至目錄

INSERT OVERWRITE DIRECTORY '/tmp/hdfs_out' SELECT a.* FROM invites a WHERE a.ds='<DATE>';

例子3:將查詢結果輸出至本地目錄

INSERT OVERWRITE LOCAL DIRECTORY '/tmp/local_out' SELECT a.* FROM pokes a;

例子4:選擇所有列到本地目錄

hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a;

INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a WHERE a.key < 100;

INSERT OVERWRITE LOCAL DIRECTORY '/tmp/reg_3' SELECT a.* FROM events a;

INSERT OVERWRITE DIRECTORY '/tmp/reg_4' select a.invites, a.pokes FROM profiles a;

INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT COUNT(1) FROM invites a WHERE a.ds='<DATE>';

INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT a.foo, a.bar FROM invites a;

INSERT OVERWRITE LOCAL DIRECTORY '/tmp/sum' SELECT SUM(a.pc) FROM pc1 a;

例子5:將一個表的統計結果插入另一個表中

INSERT OVERWRITE TABLE events SELECT a.bar, count(1) FROM invites a WHERE a.foo > 0 GROUP BY a.bar;

FROM pokes t1 JOIN invites t2 ON (t1.bar = t2.bar) INSERT OVERWRITE TABLE events SELECT t1.bar, t1.foo, t2.foo;

例子6:將多表數據插入到同一表中

FROM src

INSERT OVERWRITE TABLE dest1 SELECT src.* WHERE src.key < 100

INSERT OVERWRITE TABLE dest2 SELECT src.key, src.value WHERE src.key >= 100 and src.key < 200

INSERT OVERWRITE TABLE dest3 PARTITION(ds='2008-04-08', hr='12') SELECT src.key WHERE src.key >= 200 and src.key < 300

INSERT OVERWRITE LOCAL DIRECTORY '/tmp/dest4.out' SELECT src.value WHERE src.key >= 300;

例子7:將文件流直接插入文件

FROM invites a INSERT OVERWRITE TABLE events SELECT TRANSFORM(a.foo, a.bar) AS (oof, rab) USING '/bin/cat' WHERE a.ds > '2008-08-09';


Hadoop生態圈中,針對大數據進行批量計算時,通常需要一個或者多個MapReduce作業來完成,這種批量計算方式滿足不了對實時性要求高的場景。

此時就到了Storm上場的時候,那Storm又是如何高效完成實時計算的呢?下一篇我會介紹開源分佈式實時計算系統——Storm。


wKioL1jI24bRW-bkAABC3HPbV6s285.jpg


如何用4個月學會Hadoop開發並找到年薪25萬工作?

 

免費分享一套17年最新Hadoop大數據教程100Hadoop大數據必會面試題

因爲鏈接經常被和諧,需要的朋友請加微信 ganshiyun666 來獲取最新下載鏈接,註明“51CTO”

 

教程已幫助300+人成功轉型Hadoop開發,90%起薪超過20K,工資比之前翻了一倍。

百度Hadoop核心架構師親自錄製

內容包括0基礎入門、Hadoop生態系統、真實商業項目實戰3大部分。其中商業案例可以讓你接觸真實的生產環境,訓練自己的開發能力。

wKioL1mdQGiDPhHeAAAuZtp-5xs706.png

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