Hive數(shù)據(jù)倉庫實戰(zhàn)

Hive作為大數(shù)據(jù)平臺Hadoop之上的主流應(yīng)用,公司一般都是用它作為公司的數(shù)據(jù)倉庫,分布式機(jī)器學(xué)習(xí)的訓(xùn)練數(shù)據(jù)和數(shù)據(jù)處理也經(jīng)常用它來處理,下面介紹下它的常用功能。

一、Hive原理和功能介紹

Hive是建立在 Hadoop 上的數(shù)據(jù)倉庫基礎(chǔ)構(gòu)架。它提供了一系列的工具,可以用來進(jìn)行數(shù)據(jù)提取轉(zhuǎn)化加載(ETL),這是一種可以存儲、查詢和分析存儲在 Hadoop 中的大規(guī)模數(shù)據(jù)的機(jī)制。Hive是基于Hadoop的一個數(shù)據(jù)倉庫工具,可以將結(jié)構(gòu)化的數(shù)據(jù)文件映射為一張數(shù)據(jù)庫表,并提供簡單的SQL查詢功能, Hive 定義了簡單的類 SQL 查詢語言,稱為 HQL,它允許熟悉 SQL 的用戶查詢數(shù)據(jù)。

Hive可以將SQL語句轉(zhuǎn)換為MapReduce任務(wù)進(jìn)行運行。 其優(yōu)點是學(xué)習(xí)成本低,可以通過類SQL語句快速實現(xiàn)簡單的MapReduce統(tǒng)計,不必開發(fā)專門的MapReduce應(yīng)用,十分適合數(shù)據(jù)倉庫的統(tǒng)計分析。同時,這個Hive也允許熟悉 MapReduce 開發(fā)者的開發(fā)自定義的 mapper 和 reducer 來處理內(nèi)建的 mapper 和reducer無法完成的復(fù)雜的分析工作。比如UDF函數(shù)。

簡單來講,Hive從表面看來,你可以把他當(dāng)成類似Mysql差不多的東西,就是個數(shù)據(jù)庫而已。按本質(zhì)來講,他也并不是數(shù)據(jù)庫。其實他就是一個客戶端工具而已,真實數(shù)據(jù)是在Hadoop的HDFS分布式文件系統(tǒng)上存著,知識它提供一種方便的方式讓你很輕松把數(shù)據(jù)從HDFS查詢數(shù)據(jù)和更新數(shù)據(jù)。Hive既然是一個客戶端工具,所以并不需要啟動什么服務(wù)。說白了解壓就能用。操作方式通過寫類似Mysql的SQL語句對HDFS操作,提交SQL后,Hive會把SQL解析成MapReduce程序去執(zhí)行,分布式多臺機(jī)器并行的執(zhí)行。當(dāng)數(shù)據(jù)存入到HDFS后,大部分統(tǒng)計工作都可以通過寫Hive SQL的方式來完成,大大提高了工作效率。

二、Hive安裝部署

Hive的安裝部署非常簡單,因為它本身是Hadoop的一個客戶端,不是一個集群服務(wù)。所以把安裝包解壓,改改配置就可以用。在哪臺機(jī)器上登陸Hive客戶端就在哪臺機(jī)器上部署就可以了,不用在每臺服務(wù)器上都部署。安裝過程如下:

#上傳hive.tar.gz到/home/hadoop/software/hadoop2

cd /home/hadoop/software/hadoop2

tar xvzf hive.tar.gz

cd hive/conf

mv hive-env.sh.template hive-env.sh

mv hive-default.xml.template hive-site.xml

vim …/bin/hive-config.sh

#增加:

export JAVA_HOME=/home/hadoop/software/jdk1.8.0_121

export HIVE_HOME=/home/hadoop/software/hadoop2/hive

export HADOOP_HOME=/home/hadoop/software/hadoop2

1.然后修改hive-site.xml文件

修改以下配置字節(jié)點,主要是配置Hive的元數(shù)據(jù)存儲用Mysql,因為默認(rèn)的是Derby文件數(shù)據(jù)庫,實際公司用的時候都是改成用Mysql數(shù)據(jù)庫。

vim hive-site.xml<property><name>javax.jdo.option.ConnectionURL</name><value>jdbc:mysql://192.168.1.166:3306/chongdianleme_hive?createDatabaseIfNotExist=true</value></property><property><name>javax.jdo.option.ConnectionDriverName</name><value>com.mysql.jdbc.Driver</value></property><property><name>javax.jdo.option.ConnectionUserName</name><value>root</value></property><property><name>javax.jdo.option.ConnectionPassword</name><value>123456</value></property><property><name>hive.metastore.schema.verification</name><value>false</value><description></description></property>

因為Hive默認(rèn)沒有把Mysql的驅(qū)動jar包集成進(jìn)去,需要我們手動上傳mysql-connector-java-.-bin.jar到/home/hadoop/software/hadoop2hive/lib目錄下,Hive客戶端啟動的時候會自動加載這個目錄下的所有jar包。

部署就這么簡單,我們在Linux的客戶端輸入Hive回車就進(jìn)去控制臺命令窗口,后面就可以建表、查詢數(shù)據(jù)、更新等操作了。下面我們看下Hive的常用SQL操作。

三、Hive SQL操作

Hive做查詢數(shù)據(jù)、更新數(shù)據(jù)前提需要先建表,有了表之后我們可以往表里寫入數(shù)據(jù),之后才可以查詢和更新等操作。

1.建表操作

#建Hive表腳本

create EXTERNAL table IF NOT EXISTS ods_kc_fact_clicklog_tab(userid string,kcid string,time string)

ROW FORMAT DELIMITED FIELDS

TERMINATED BY ‘\t’

stored as textfile

location ‘/ods/kc/fact/ods_kc_fact_clicklog/’;

#EXTERNAL關(guān)鍵詞意思創(chuàng)建外部表,目的是外部表當(dāng)您drop table 的時候數(shù)據(jù)不會刪除,只會刪掉表結(jié)構(gòu)而已,表結(jié)構(gòu)又叫做元數(shù)據(jù)。想恢復(fù)表結(jié)構(gòu)只需要把這個表再創(chuàng)建一次就行,里面的數(shù)據(jù)還存在。所以為了保險防止誤操作,一般Hive數(shù)據(jù)倉庫都建外部表。

TERMINATED BY ‘\t’ #列之間分隔符

location ‘/ods/kc/fact/ods_kc_fact_clicklog/’;#數(shù)據(jù)存儲路徑

#建表就這么簡單,但建表之前得先建數(shù)據(jù)庫,數(shù)據(jù)庫的創(chuàng)建命令:

create database chongdianleme;

然后選擇這個數(shù)據(jù)庫:use chongdianleme;

#Hive建表的字段類型如下:

#基礎(chǔ)數(shù)據(jù)類型:

Hive類型        說明         java類型      實例

1).tinyint 1byte有符號的整數(shù)    byte 20

2).smalint 2byte有符號的整數(shù)   short 20

3).int 4byte有符號的整數(shù)   int 20

4).bigint 8byte有符號的整數(shù)   long 20

5).boolean     布爾類型true或false boolean true

6).float      單精度         float 3.217

7).double    雙精度         double 3.212

8).string      字符序列,單雙即可   string ‘chongdianleme’;

9).timestamp    時間戳,精確的納秒 timestamp ‘158030219188’

10).binary      字節(jié)數(shù)組        byte[]

#集合數(shù)據(jù)類型:

hive類型      說明           java類型         實例

1).struct 對象類型,可以通過字段名.元素名來訪問object struct(‘name’,‘a(chǎn)ge’)

2).map 一組鍵值對的元組 map map(‘name’,‘zhangsan’,‘a(chǎn)ge’,‘23’)

3).array    數(shù)組  array array(‘name’,‘a(chǎn)ge’)

4).union          組合

#輸入hive回車,執(zhí)行創(chuàng)建表命令

#創(chuàng)建數(shù)據(jù)庫命令

create database chongdianleme;

#使用這個數(shù)據(jù)庫

use chongdianleme;

示例:

#ods層事實表用戶查看點擊課程日志:

create EXTERNAL table IF NOT EXISTS ods_kc_fact_clicklog_tab(userid string,kcid string,time string)

ROW FORMAT DELIMITED FIELDS

TERMINATED BY ‘\t’

stored as textfile

location ‘/ods/kc/fact/ods_kc_fact_clicklog_tab/’;

#ods層維表課程商品表:

create EXTERNAL table IF NOT EXISTS ods_kc_dim_product_tab(kcid string,kcname string,price float ,issale string)

ROW FORMAT DELIMITED FIELDS

TERMINATED BY ‘\t’

stored as textfile

location ‘/ods/kc/dim/ods_kc_dim_product_tab/’;

2.創(chuàng)建表之后我們就可以做一些查詢數(shù)據(jù)表的操作

1)查詢課程日志表前幾條記錄

select * from ods_kc_fact_clicklog_tab limit 6;

2)導(dǎo)入一些數(shù)據(jù)到課程日志表

因為開始表里沒數(shù)據(jù),我們需要先導(dǎo)入數(shù)據(jù)進(jìn)去。有多種方式導(dǎo)入,比如

(1)用Sqoop工具從Mysql導(dǎo)入;

(2)直接把文本文件放到Hive對應(yīng)的HDFS目錄下。

cd /home/hadoop/chongdianleme

#rz上傳

#通過Hadoop命令上傳本地文件到hive表對用的hdfs目錄:

hadoop fs -put kclog.txt /ods/kc/fact/ods_kc_fact_clicklog_tab/

#查看下此目錄,可以看到在這個Hive表目錄下有數(shù)據(jù)了:

$ hadoop fs -ls /ods/kc/fact/ods_kc_fact_clicklog_tab/

Found 1 items

-rw-r–r-- 3 hadoop supergroup 590 2019-05-29 02:16 /ods/kc/fact/ods_kc_fact_clicklog_tab/kclog.txt

#通過Hadoop的tail命令我們可以查看此目錄的文件最后幾條記錄:

$ hadoop fs -tail /ods/kc/fact/ods_kc_fact_clicklog_tab/kclog.txt

u001 kc61800001 2019-06-02 10:01:16

u001 kc61800002 2019-06-02 10:01:17

u001 kc61800003 2019-06-02 10:01:18

u002 kc61800006 2019-06-02 10:01:19

u002 kc61800007 2019-06-02 10:01:20

#然后上傳課程商品表

cd /home/hadoop/chongdianleme

#rz上傳

hadoop fs -put product.txt /ods/kc/dim/ods_kc_dim_product_tab/

#查看記錄

hadoop fs -tail /ods/kc/dim/ods_kc_dim_product_tab/product.txt

3)簡單的查詢課程日志表SQL語句

#查詢前幾條

select * from ods_kc_fact_clicklog_tab limit 6;

#查詢總共有多少條記錄

select count(1) from ods_kc_fact_clicklog_tab;

#查看有多少用戶

select count(distinct userid) from ods_kc_fact_clicklog_tab;

#查看某個用戶的課程日志

select * from ods_kc_fact_clicklog_tab where userid=‘u001’;

#查看大于等于某個時間的日志

select * from ods_kc_fact_clicklog_tab where time>=‘2019-06-02 10:01:19’;

#查看在售,并且價格大于2000的日志

select * from ods_kc_dim_product where issale=‘1’ and price>2000;

#查看在售,或者價格大于2000的日志

select * from ods_kc_dim_product where issale=‘1’ or price>2000;

4)以\001分隔符建表

#以\001分割是Hive建表中常用的規(guī)范,之前用的\t分隔符容易被用戶輸入,數(shù)據(jù)行里如果存在\t分隔符,會和Hive表里的\t分隔符混淆,這樣這一行數(shù)據(jù)會多出幾列,造成列錯亂。

#ods層維表用戶查看點擊課程日志事實表:

create EXTERNAL table IF NOT EXISTS ods_kc_fact_clicklog(userid string,kcid string,time string)

ROW FORMAT DELIMITED FIELDS

TERMINATED BY ‘\001’

stored as textfile

location ‘/ods/kc/fact/ods_kc_fact_clicklog/’;

#ods層維表用戶查看點擊課程基本信息維度表:

create EXTERNAL table IF NOT EXISTS ods_kc_dim_product(kcid string,kcname string,price float ,issale string)

ROW FORMAT DELIMITED FIELDS

TERMINATED BY ‘\001’

stored as textfile

location ‘/ods/kc/dim/ods_kc_dim_product/’;

5)基于SQL查詢結(jié)果集來更新數(shù)據(jù)表

#把查詢sql語句的結(jié)果集合導(dǎo)出到另外一張表,用insert overwrite table

這是更新數(shù)據(jù)表的常用方式,通過insert overwrite table可以把指定的查詢結(jié)果集合插入到這個表,插入前先把表清空。如果不加overwrite關(guān)鍵詞,就不會清空,而是在原來的數(shù)據(jù)上追加。

#先查詢下ods_kc_fact_clicklog這個表有沒有記錄。

select * from chongdianleme.ods_kc_fact_clicklog limit 6;

#把查詢結(jié)果導(dǎo)入到這個\001分割的表,課程日志表

insert overwrite table chongdianleme.ods_kc_fact_clicklog select userid,kcid,time from chongdianleme.ods_kc_fact_clicklog_tab;

#再查看下導(dǎo)入的結(jié)果

select * from chongdianleme.ods_kc_fact_clicklog limit 6;

#課程商品表

insert overwrite table chongdianleme.ods_kc_dim_product select kcid,kcname,price,issale from chongdianleme.ods_kc_dim_product_tab;

#查看課程商品表

select * from chongdianleme.ods_kc_dim_product limit 36;

select * from ods_kc_dim_product where price>2000;

6)join關(guān)聯(lián)查詢–自然連接

#join關(guān)聯(lián)查詢可以把多個表以某個字段作為關(guān)聯(lián),同時獲得多個表的字段數(shù)據(jù),關(guān)聯(lián)不上的數(shù)據(jù)將會丟棄。

#查詢下在售課程的用戶訪問日志

select a.userid,a.kcid,b.kcname,b.price,a.time from chongdianleme.ods_kc_fact_clicklog a join chongdianleme.ods_kc_dim_product b on a.kcid=b.kcid where b.issale=1;

7)left join關(guān)聯(lián)查詢–左連接

#left join關(guān)聯(lián)查詢和自然連接的區(qū)別,左邊的表的沒有關(guān)聯(lián)上的數(shù)據(jù)記錄不會丟棄,只是對應(yīng)的右表那些記錄是空值而已。

#查詢下在售課程的用戶訪問日志

select a.userid,a.kcid,b.kcname,b.price,a.time,b.kcid from chongdianleme.ods_kc_fact_clicklog a left join chongdianleme.ods_kc_dim_product b on a.kcid=b.kcid where b.kcid is null;

8)full join關(guān)聯(lián)查詢—完全連接

#full join關(guān)聯(lián)查詢不管有沒有關(guān)聯(lián)上,所有的數(shù)據(jù)記錄都會丟棄,關(guān)聯(lián)不上只是顯示為空而已。

#查詢下在售課程的用戶訪問日志

select a.userid,a.kcid,b.kcname,b.price,a.time,b.kcid from chongdianleme.ods_kc_fact_clicklog a full join chongdianleme.ods_kc_dim_product b on a.kcid=b.kcid;

9)導(dǎo)入關(guān)聯(lián)表SQL結(jié)果到新表

#創(chuàng)建要導(dǎo)入的表數(shù)據(jù)

create EXTERNAL table IF NOT EXISTS ods_kc_fact_etlclicklog(userid string,kcid string,time string)

ROW FORMAT DELIMITED FIELDS

TERMINATED BY ‘\001’

stored as textfile

location ‘/ods/kc/fact/ods_kc_fact_etlclicklog/’;

#把查詢集合的結(jié)果更新到剛才創(chuàng)建的表里ods_kc_fact_etlclicklog,先清空,在導(dǎo)入。如果不想清空而是想追加數(shù)據(jù)把overwrite關(guān)鍵詞去掉就可以了。

insert overwrite table chongdianleme.ods_kc_fact_etlclicklog select a.userid,a.kcid,a.time from chongdianleme.ods_kc_fact_clicklog a join chongdianleme.ods_kc_dim_product b on a.kcid=b.kcid where b.issale=1;

上面的SQL語句都是在Hive客戶端操作的,SQL語句根據(jù)數(shù)據(jù)量和復(fù)雜程度不同,快的話如果不觸發(fā)MapReduce計算只需要幾毫秒,如果觸發(fā)了最快也得幾秒左右。一般情況下執(zhí)行幾分鐘或幾個小時很正常。對于執(zhí)行時間長的SQL語句,客戶端的電腦如果斷電或網(wǎng)絡(luò)中斷,SQL語句的執(zhí)行可能也會重點,沒有完全跑完整個SQL。所以這種情況我們可以用一個Shell腳本把需要執(zhí)行的SQL都放在里面,以后就可以用nohup后臺的方式去執(zhí)行這個腳本。

3.通過Shell腳本執(zhí)行Hive的SQL語句來實現(xiàn)ETL

#創(chuàng)建demohive.sql文件

#把insert overwrite table chongdianleme.ods_kc_fact_etlclicklog select a.userid,a.kcid,a.time from chongdianleme.ods_kc_fact_clicklog a join chongdianleme.ods_kc_dim_product b on a.kcid=b.kcid where b.issale=1;

insert overwrite table chongdianleme.ods_kc_dim_product select kcid,kcname,price,issale from chongdianleme.ods_kc_dim_product_tab;

#加進(jìn)去,每個SQL語句后面記得加;分號。

#創(chuàng)建demoshell.sh文件

#加入:echo “通過shell腳本執(zhí)行hive sql語句”

/home/hadoop/software/hadoop2/hive/bin/hive -f /home/hadoop/chongdianleme/demohive.sql;

sh demoshell.sh

#或者

sudo chmod 755 demoshell.sh

./demoshell.sh

#以nohup后臺進(jìn)程方式執(zhí)行Shell腳本,防止xshell客戶端由于斷網(wǎng)或者下班后關(guān)機(jī)或關(guān)閉客戶端而導(dǎo)致sql執(zhí)行半截退出。

#創(chuàng)建nohupdemoshell.sh文件:

#echo “–nohup后臺方式執(zhí)行腳本,斷網(wǎng)、關(guān)機(jī)、客戶端關(guān)閉無需擔(dān)憂執(zhí)行腳本中斷”;

nohup /home/hadoop/chongdianleme/demoshell.sh >>/home/hadoop/chongdianleme/log.txt 2>&1 &

#然后執(zhí)行可能報錯:

nohup: 無法運行命令’/home/hadoop/chongdianleme/demoshell.sh’: #權(quán)限不夠

#是因為腳本是不可執(zhí)行文件。

sudo chmod 755 demoshell.sh

sudo chmod 755 nohupdemoshell.sh

#然后tail -f log.txt就可以看到實時執(zhí)行日志。

實際上我們用Hive做ETL數(shù)據(jù)處理都可以用這種方式,通過Shell腳本來執(zhí)行Hive SQL,并且是定時觸發(fā),定時觸發(fā)有幾種方式,最簡單的方式用Linux系統(tǒng)自帶的crontab調(diào)度。但crontab調(diào)度不支持復(fù)雜的任務(wù)依賴。這個時候可以用Azkaban、Oozie來調(diào)度?;ヂ?lián)網(wǎng)公司使用最普遍的是Azkaban調(diào)度。

4.crontab調(diào)度定時執(zhí)行腳本

這是Linux自帶的本地系統(tǒng)調(diào)度工具,簡單好用。通過crontab表達(dá)式定時觸發(fā)一個shell腳本。

#Crontab調(diào)度舉例

crontab -e

16 1,2,23 * * * /home/hadoop/chongdianleme/nohupdemoshell.sh

然后保存,重啟cron服務(wù)。

sudo service cron restart

5.Azkaban調(diào)度

Azkaban是一套簡單的任務(wù)調(diào)度服務(wù),整體包括三部分webserver、dbserver、executorserver。Azkaban是linkin的開源項目,開發(fā)語言為Java。Azkaban是由Linkedin開源的一個批量工作流任務(wù)調(diào)度器。用于在一個工作流內(nèi)以一個特定的順序運行一組工作和流程。Azkaban定義了一種KV文件格式來建立任務(wù)之間的依賴關(guān)系,并提供一個易于使用的Web用戶界面維護(hù)和跟蹤你的工作流。

Azkaban實際當(dāng)中經(jīng)常有這些場景:每天有一個大任務(wù),這個大任務(wù)可以分成A,B,C,D四個小任務(wù),A,B任務(wù)之間沒有依賴關(guān)系,C任務(wù)依賴A,B任務(wù)的結(jié)果,D任務(wù)依賴C任務(wù)的結(jié)果。一般的做法是,開兩個終端同時執(zhí)行A,B,兩個都執(zhí)行完了再執(zhí)行C,最后再執(zhí)行D。這樣的話,整個的執(zhí)行過程都需要人工參加,并且得盯著各任務(wù)的進(jìn)度。但是我們的很多任務(wù)都是在深更半夜執(zhí)行的,通過寫腳本設(shè)置crontab執(zhí)行。其實,整個過程類似于一個有向無環(huán)圖(DAG)。每個子任務(wù)相當(dāng)于大任務(wù)中的一個流,任務(wù)的起點可以從沒有度的節(jié)點開始執(zhí)行,任何沒有通路的節(jié)點之間可以同時執(zhí)行,比如上述的A,B。總結(jié)起來的話,我們需要的就是一個工作流的調(diào)度器,而azkaban就是能解決上述問題的一個調(diào)度器。

6.Oozie調(diào)度

Oozie是管理Hadoop作業(yè)的工作流調(diào)度系統(tǒng),Oozie的工作流是一系列的操作圖,Oozie協(xié)調(diào)作業(yè)是通過時間(頻率)以及有效數(shù)據(jù)觸發(fā)當(dāng)前的Oozie工作流程,Oozie是針對Hadoop開發(fā)的開源工作流引擎,專門針對大規(guī)模復(fù)雜工作流程和數(shù)據(jù)管道設(shè)計。Oozie圍繞兩個核心:工作流和協(xié)調(diào)器,前者定義任務(wù)的拓?fù)浜蛨?zhí)行邏輯,后者負(fù)責(zé)工作流的依賴和觸發(fā)。

這節(jié)我們講的Hive常用SQL,Hive SQL能滿足多數(shù)應(yīng)用場景,但有的時候想和自己的業(yè)務(wù)代碼做混合編程,實現(xiàn)復(fù)雜的功能,就需要自定義開發(fā)Java函數(shù),也就是我們下面要講的UDF函數(shù)。

UDF函數(shù)

Hive SQL一般滿足多數(shù)應(yīng)用場景,但是有的時候通過SQL實現(xiàn)比較復(fù)雜,用一個函數(shù)實現(xiàn)會大大簡化SQL的邏輯,在就是通過自定義函數(shù)能夠和業(yè)務(wù)邏輯結(jié)合在一塊,實現(xiàn)更復(fù)雜的功能。

1.Hive類型

Hive中有三種UDF:

1) 用戶定義函數(shù)(user-defined function)UDF

UDF操作作用于單個數(shù)據(jù)行,并且產(chǎn)生一個數(shù)據(jù)行作為輸出。大多數(shù)函數(shù)都屬于這一類,比如數(shù)學(xué)函數(shù)和字符串函數(shù)。簡單來說UDF返回對應(yīng)值,一對一。

2) 用戶定義聚集函數(shù)(user-defined aggregate function,UDAF)

UDAF 接受多個輸入數(shù)據(jù)行,并產(chǎn)生一個輸出數(shù)據(jù)行。像COUNT和MAX這樣的函數(shù)就是聚集函數(shù)。簡單來說UDAF返回聚類值,多對一。

3)用戶定義表生成函數(shù)(user-defined table-generating function,UDTF)

UDTF 操作作用于單個數(shù)據(jù)行,并且產(chǎn)生多個數(shù)據(jù)行一個表作為輸出。簡單來說UDTF返回拆分值,一對多。

實際工作中UDF用的最多,下面我們重點講一下第一種UDF函數(shù),也就是用戶定義函數(shù)(user-defined function)UDF,我們統(tǒng)一簡稱為UDF。

2.UDF自定義函數(shù)

Hive的SQL給數(shù)據(jù)挖掘工作者帶來了很多便利,海量數(shù)據(jù)通過簡單的SQL就可以完成分析,有時候Hive提供的函數(shù)功能滿足不了業(yè)務(wù)需要,就需要我們自己來寫UDF函數(shù)來輔助完成。UDF函數(shù)其實就是一個簡單的函數(shù),執(zhí)行過程就是在Hive轉(zhuǎn)換成MapReduce程序后,執(zhí)行Java方法,類似于像MapReduce執(zhí)行過程中加入一個插件,方便擴(kuò)展。 UDF只能實現(xiàn)一進(jìn)一出的操作,如果需要實現(xiàn)多進(jìn)一出,則需要實現(xiàn)UDAF。Hive可以允許用戶編寫自己定義的函數(shù)UDF,來在查詢中使用。我們自定義開發(fā)UDF函數(shù)的時候繼承org.apache.hadoop.hive.ql.exec.UDF類即可,代碼如下所示:

package com.chongdianleme.hiveudf.udf;

import org.apache.hadoop.hive.ql.exec.UDF;

//自定義類繼承UDF

public class HiveUDFTest extends UDF {

//字符串統(tǒng)一轉(zhuǎn)大寫字符串示例

public String evaluate (String str){

if(str==null || str.toString().isEmpty()){

return new String();

}

return new String(str.trim().toUpperCase());

}

}

下面看下怎么部署,部署也分臨時部署和永久生效部署方式,我們分別來看下。

3.臨時部署測試

部署腳本代碼如下所示:

#把程序打包放到目標(biāo)機(jī)器上去;

#進(jìn)入hive客戶端,添加jar包:

hive>add jar /home/hadoop/software/task/HiveUDFTest.jar;

#創(chuàng)建臨時函數(shù):

hive>CREATE TEMPORARY FUNCTION ups AS ‘hive.HiveUDFTest’;

add jar /home/hadoop/software/task/udfTest.jar;

create temporary function row_toUpper as ‘com.chongdianleme.hiveudf.udf.HiveUDFTest’;

4.永久全局方式部署

線上永久配置方式,部署腳本代碼如下所示:

cd /home/hadoop/software/hadoop2/hive

#創(chuàng)建auxlib文件夾

cd auxlib

#在/home/hadoop/software/hadoop2/hive/auxlib上傳udf函數(shù)的jar包。hive sql執(zhí)行時會自動掃描/data/software/hadoop/hive/auxlib下的jar包。

cd /home/hadoop/software/hadoop2/hive/bin

#顯示隱藏文件

ls -a

#編輯vi .hiverc文件加入

create temporary function row_toUpper as ‘com.chongdianleme.hiveudf.udf.HiveUDFTest’;

之后通過輸入hive命令登錄客戶端就可以了,客戶端會自動掃描加載所有的UDF函數(shù)。以上我們講的Hive常用SQL和UDF,以及怎么用Shell腳本觸發(fā)執(zhí)行SQL,怎么去做定時的調(diào)度。實際工作中,并不是盲目隨意的去建表,一般都會制定一個規(guī)范,大家遵守這個規(guī)則去執(zhí)行。這個規(guī)范就是我們下面要講的數(shù)據(jù)倉庫規(guī)范和模型設(shè)計。

Hive 數(shù)據(jù)倉庫模型設(shè)計

數(shù)據(jù)倉庫模型設(shè)計就是要制定一個規(guī)范,這個規(guī)范一般是做數(shù)據(jù)倉庫的分層設(shè)計。我們要搭建數(shù)據(jù)倉庫,把握好數(shù)據(jù)質(zhì)量,對數(shù)據(jù)進(jìn)行清洗、轉(zhuǎn)換。那么更好區(qū)分那個是原始數(shù)據(jù),那個是清洗后的數(shù)據(jù),我們最好做一個數(shù)據(jù)分層,方便我們快速的找到想要的數(shù)據(jù)。另外,有些高頻的數(shù)據(jù)不需要每次都重復(fù)計算,只需要計算一次放在一個中間層里,供其他業(yè)務(wù)模塊復(fù)用,這樣節(jié)省時間,同時也減少的服務(wù)器資源的消耗。數(shù)據(jù)倉庫分層設(shè)計還有其他很多好處,下面舉一個實例看看如何分層。

數(shù)據(jù)倉庫,英文名稱為Data Warehouse,可簡寫為DW或DWH。數(shù)據(jù)倉庫,是為企業(yè)所有級別的決策制定過程,提供所有類型數(shù)據(jù)支持的戰(zhàn)略集合。它是單個數(shù)據(jù)存儲,出于分析性報告和決策支持目的而創(chuàng)建。 為需要業(yè)務(wù)智能的企業(yè),提供指導(dǎo)業(yè)務(wù)流程改進(jìn)、監(jiān)視時間、成本、質(zhì)量以及控制。

我們在看下什么是數(shù)據(jù)集市,數(shù)據(jù)集市(Data Mart) ,也叫數(shù)據(jù)市場,數(shù)據(jù)集市就是滿足特定的部門或者用戶的需求,按照多維的方式進(jìn)行存儲,包括定義維度、需要計算的指標(biāo)、維度的層次等,生成面向決策分析需求的數(shù)據(jù)立方體。從范圍上來說,數(shù)據(jù)是從企業(yè)范圍的數(shù)據(jù)庫、數(shù)據(jù)倉庫,或者是更加專業(yè)的數(shù)據(jù)倉庫中抽取出來的。數(shù)據(jù)中心的重點就在于它迎合了專業(yè)用戶群體的特殊需求,在分析、內(nèi)容、表現(xiàn),以及易用方面。數(shù)據(jù)中心的用戶希望數(shù)據(jù)是由他們熟悉的術(shù)語表現(xiàn)的。

上面我們說的是數(shù)據(jù)倉庫和數(shù)據(jù)集市的概念,簡單來說,在Hadoop平臺上的整個Hive的所有表構(gòu)成了數(shù)據(jù)倉庫,這些表有時分層設(shè)計的,我們可以分為四層,ods層、mid層、tp臨時層、數(shù)據(jù)集市層。其中數(shù)據(jù)集市可以看做數(shù)據(jù)倉庫的一個子集,一個數(shù)據(jù)集市往往是針對一個項目的,比如推薦的叫推薦集市,做用戶畫像的項目叫用戶畫像集市。ods是基礎(chǔ)數(shù)據(jù)層,也是原始數(shù)據(jù)層,是最底層的,數(shù)據(jù)集市是偏最上游的數(shù)據(jù)層。數(shù)據(jù)集市的數(shù)據(jù)可以直接讓項目使用,不用再更多的去加工了。

數(shù)據(jù)倉庫的分層體現(xiàn)在Hive數(shù)據(jù)表名上,Hive存儲對應(yīng)的HDFS目錄最好和表名一致,這樣根據(jù)表名也能快速的找到目錄,當(dāng)然這不是必須的。一般大數(shù)據(jù)平臺都會創(chuàng)建一個數(shù)據(jù)字典平臺,在Web的界面上能夠根據(jù)表名找到對應(yīng)的表解釋,比如表的用途,字段表結(jié)構(gòu),每個字段代表什么意思,存儲目錄等。而且能查詢到表和表之間的血緣關(guān)系。說到血緣關(guān)系在數(shù)據(jù)倉庫里經(jīng)常會提起。我在下面會單獨講一小節(jié)。下面我用實例講下推薦的數(shù)據(jù)倉庫。

首先我們需要和部門所有的人制定一個建表規(guī)范,大家統(tǒng)一遵守這個規(guī)則:

1.建表規(guī)范

以下建表規(guī)范僅供參考,可以根據(jù)每個公司的實際情況來定:

1) 統(tǒng)一創(chuàng)建外部表

外部表的好處是當(dāng)你不小心刪除了這個表,但數(shù)據(jù)還會保留下來,如果是誤刪除,會很快的找回來,只需要把建表語句在創(chuàng)建一遍即可。

2)統(tǒng)一分四級,以下劃線分割

分為幾個級別沒有明確的規(guī)定,一般分為四級的情況比較多。

3)列之間分隔符統(tǒng)一’\001’

用\001分割的目標(biāo)是為了避免因為數(shù)據(jù)也存在同樣的分隔符造成列的錯亂問題。因為\001分割符是用戶無法輸入的,之前用的\t分隔符容易被用戶輸入,數(shù)據(jù)行里如果存在\t分隔符,會和Hive表里的\t分隔符混淆,這樣這一行數(shù)據(jù)會多出幾列,造成列錯亂。

4)location指定目錄統(tǒng)一以/結(jié)尾

指定目錄統(tǒng)一以/結(jié)尾代表最后是一個文件夾,而不是一個文件。一個文件夾下面可以有很多文件,如果數(shù)據(jù)特別大,適合拆分成多個小文件。

5)stored類型統(tǒng)一textfile

每個公司實際情況不太一樣,textfile是文本文件類型,好處是方便查看內(nèi)容,不好的地方是占用空間較多。

6)表名和location指定目錄保持一致

表名和location指定目錄保持一致的主要目的是方便看見表名就馬上知道對應(yīng)的數(shù)據(jù)存儲目錄在哪里,方便檢索和查找。

#下面列舉一個建表的例子給大家做一個演示

create EXTERNAL table IF NOT EXISTS ods_kc_dim_product(kcid string,kcname string,price float ,issale string)

ROW FORMAT DELIMITED FIELDS

TERMINATED BY ‘\001’

stored as textfile

location ‘/ods/kc/dim/ods_kc_dim_product/’;

2.數(shù)據(jù)倉庫分層設(shè)計規(guī)范

上面我們建表的時候已經(jīng)說了分為四級,也就是說我們的數(shù)據(jù)倉庫分為四層,也就是操作數(shù)據(jù)存儲原始數(shù)據(jù)層ODS、middle中間層、tp臨時層、數(shù)據(jù)集市層等,下面我們一一講解。

1)ODS層

說明:操作數(shù)據(jù)存儲ODS(Operational Data Store)用來存放原始基礎(chǔ)數(shù)據(jù),比如維表、事實表。以下劃線分為四級,

(1)原始數(shù)據(jù)層

(2)項目名稱(kc代表視頻課程類項目,Read代表閱讀類文章)

(3)表類型(dim維度表fact事實表)

(4)表名

舉幾個例子:

#原始數(shù)據(jù)_視頻課程_事實表_課程訪問日志表

create EXTERNAL table IF NOT EXISTS ods_kc_fact_clicklog(userid string,kcid string,time string)

ROW FORMAT DELIMITED FIELDS

TERMINATED BY ‘\001’

stored as textfile

location ‘/ods/kc/fact/ods_kc_fact_clicklog/’;

#ods層維表課程基本信息表:

create EXTERNAL table IF NOT EXISTS ods_kc_dim_product(kcid string,kcname string,price float ,issale string)

ROW FORMAT DELIMITED FIELDS

TERMINATED BY ‘\001’

stored as textfile

location ‘/ods/kc/dim/ods_kc_dim_product/’;

這里涉及到一個概念,什么是維表、事實表?

事實表:

在多維數(shù)據(jù)倉庫中,保存度量值的詳細(xì)值或事實的表稱為“事實表”。事實數(shù)據(jù)表通常包含大量的行。事實數(shù)據(jù)表的主要特點是包含數(shù)字?jǐn)?shù)據(jù)(事實),并且這些數(shù)字信息可以匯總,以提供有關(guān)單位作為歷史的數(shù)據(jù),每個事實數(shù)據(jù)表包含一個由多個部分組成的索引,該索引包含作為外鍵的相關(guān)性緯度表的主鍵,而維度表包含事實記錄的特性。事實數(shù)據(jù)表不應(yīng)該包含描述性的信息,也不應(yīng)該包含除數(shù)字度量字段及使事實與緯度表中對應(yīng)項的相關(guān)索引字段之外的任何數(shù)據(jù)。

維度表:

維度表可以看作是用戶來分析數(shù)據(jù)的窗口,緯度表中包含事實數(shù)據(jù)表中事實記錄的特性,有些特性提供描述性信息,有些特性指定如何匯總事實數(shù)據(jù)表數(shù)據(jù),以便為分析者提供有用的信息,維度表包含幫助匯總數(shù)據(jù)的特性的層次結(jié)構(gòu)。例如,包含產(chǎn)品信息的維度表通常包含將產(chǎn)品分為食品、飲料、非消費品等若干類的層次結(jié)構(gòu),這些產(chǎn)品中的每一類進(jìn)一步多次細(xì)分,直到各產(chǎn)品達(dá)到最低級別。在維度表中,每個表都包含獨立于其他維度表的事實特性,例如,客戶維度表包含有關(guān)客戶的數(shù)據(jù)。維度表中的列字段可以將信息分為不同層次的結(jié)構(gòu)級。維度表包含了維度的每個成員的特定名稱。維度成員的名稱稱為“屬性”(Attribute)。

在我們的推薦場景,比如這個課程訪問日志表ods_kc_fact_clicklog,都是用戶訪問課程的大量日志,針對每條記錄也沒有一個實際意義的主鍵,同一個用戶有多條課程訪問記錄,同一個課程也會別多個用戶訪問,這個表就是事實表。課程基本信息表ods_kc_dim_product,每個課程都有一個唯一的課程主鍵,課程具有唯一性。每個課程都有基本屬性。這個表就是維表。

2)mid層

說明:middle中間層,從ods層中join多表或某一段時間內(nèi)的小表計算生成的中間表,再后續(xù)的集市層中頻繁使用。用來一次生成多次使用,避免每次關(guān)聯(lián)多個表重復(fù)計算。

從ODS層提取數(shù)據(jù)到集市層常用SQL方式:

#把某個select的查詢結(jié)果集覆蓋到某個表,相當(dāng)于truncate和insert的操作。

insert overwrite table chongdianleme.ods_kc_fact_etlclicklog select a.userid,a.kcid,a.time from chongdianleme.ods_kc_fact_clicklog a join chongdianleme.ods_kc_dim_product b on a.kcid=b.kcid where b.issale=1;

3)tp臨時層

說明:temp臨時層簡稱tp,臨時生成的數(shù)據(jù)統(tǒng)一放在這層。系統(tǒng)默認(rèn)有一個/tmp目錄,不要放在這里目錄,這個目錄很多是Hive本身自己存放在的臨時層,我們不要跟它混在一起

#建表舉例:

create EXTERNAL table IF NOT EXISTS tp_kc_fact_clicklogtotemp(userid string,kcid string,time string)

ROW FORMAT DELIMITED FIELDS

TERMINATED BY ‘\001’

stored as textfile

location ‘/tp/kc/fact/tp_kc_fact_clicklogtotemp/’;

4)數(shù)據(jù)集市層

比如,用戶畫像集市,推薦集市,搜索集市等。說明:存放搜索項目數(shù)據(jù),集市數(shù)據(jù)一般是中間層和ods層關(guān)聯(lián)表計算,或使用Spark程序處理開發(fā)算出來的數(shù)據(jù)。

#用戶畫像集市建表舉例:

create EXTERNAL table IF NOT EXISTS personas_kc_fact_userlog(userid string,kcid string,name string,age string,sex string)

ROW FORMAT DELIMITED FIELDS

TERMINATED BY ‘\001’

stored as textfile

location ‘/personas/kc/fact/personas_kc_fact_userlog/’;

從開發(fā)人員的角色,是有專門的數(shù)據(jù)倉庫工程師來負(fù)責(zé),當(dāng)然如果預(yù)算有限,也可以有大數(shù)據(jù)ETL工程師來負(fù)責(zé)。

Hive非常適合離線的數(shù)據(jù)處理分析,但有些場景需要對數(shù)據(jù)做實時處理,而Hbase數(shù)據(jù)庫特別適合處理實時數(shù)據(jù)。

總結(jié)

此文章有對應(yīng)的配套視頻,除了Hive數(shù)據(jù)倉庫實戰(zhàn),其它更多精彩文章請大家下載充電了么app,可獲取千萬免費好課和文章,配套新書教材請看陳敬雷新書:《分布式機(jī)器學(xué)習(xí)實戰(zhàn)》(人工智能科學(xué)與技術(shù)叢書)

其它深度學(xué)習(xí)框架也有不錯的開源實現(xiàn),比如MXNet,后面請大家關(guān)注充電了么app,課程,微信群,更多內(nèi)容請看新書《分布式機(jī)器學(xué)習(xí)實戰(zhàn)(人工智能科學(xué)與技術(shù)叢書)》

【新書介紹】

《分布式機(jī)器學(xué)習(xí)實戰(zhàn)》(人工智能科學(xué)與技術(shù)叢書)【陳敬雷編著】【清華大學(xué)出版社】https://item.jd.com/12743009.html

新書特色:深入淺出,逐步講解分布式機(jī)器學(xué)習(xí)的框架及應(yīng)用配套個性化推薦算法系統(tǒng)、人臉識別、對話機(jī)器人等實戰(zhàn)項目

【新書介紹視頻】

分布式機(jī)器學(xué)習(xí)實戰(zhàn)(人工智能科學(xué)與技術(shù)叢書)新書【陳敬雷】https://ke.qq.com/course/3067704?flowToken=1029963

視頻特色:重點對新書進(jìn)行介紹,最新前沿技術(shù)熱點剖析,技術(shù)職業(yè)規(guī)劃建議!聽完此課你對人工智能領(lǐng)域?qū)⒂幸粋€嶄新的技術(shù)視野!職業(yè)發(fā)展也將有更加清晰的認(rèn)識!

【精品課程】

《分布式機(jī)器學(xué)習(xí)實戰(zhàn)》大數(shù)據(jù)人工智能AI專家級精品課程https://ke.qq.com/course/393750?flowToken=1028919

【免費體驗視頻】

人工智能百萬年薪成長路線/從Python到最新熱點技術(shù)https://ke.qq.com/course/package/31251?flowToken=1029962

從Python編程零基礎(chǔ)小白入門到人工智能高級實戰(zhàn)系列課

https://ke.qq.com/course/package/29782?flowToken=1028733

視頻特色:本系列專家級精品課有對應(yīng)的配套書籍《分布式機(jī)器學(xué)習(xí)實戰(zhàn)》,精品課和書籍可以互補(bǔ)式學(xué)習(xí),彼此相互補(bǔ)充,大大提高了學(xué)習(xí)效率。本系列課和書籍是以分布式機(jī)器學(xué)習(xí)為主線,并對其依賴的大數(shù)據(jù)技術(shù)做了詳細(xì)介紹,之后對目前主流的分布式機(jī)器學(xué)習(xí)框架和算法進(jìn)行重點講解,本系列課和書籍側(cè)重實戰(zhàn),最后講幾個工業(yè)級的系統(tǒng)實戰(zhàn)項目給大家。課程核心內(nèi)容有互聯(lián)網(wǎng)公司大數(shù)據(jù)和人工智能那些事、大數(shù)據(jù)算法系統(tǒng)架構(gòu)、大數(shù)據(jù)基礎(chǔ)、Python編程、Java編程、Scala編程、Docker容器、Mahout分布式機(jī)器學(xué)習(xí)平臺、Spark分布式機(jī)器學(xué)習(xí)平臺、分布式深度學(xué)習(xí)框架和神經(jīng)網(wǎng)絡(luò)算法、自然語言處理算法、工業(yè)級完整系統(tǒng)實戰(zhàn)(推薦算法系統(tǒng)實戰(zhàn)、人臉識別實戰(zhàn)、對話機(jī)器人實戰(zhàn))、就業(yè)/面試技巧/職業(yè)生涯規(guī)劃/職業(yè)晉升指導(dǎo)等內(nèi)容。

【充電了么App】

本書在充電了么App里有對應(yīng)的視頻課程,更多學(xué)習(xí)資源也可以通過下載充電了么App客戶端,也可以從各大應(yīng)用商店里搜索“充電了么”自行下載。充電了么是專注上班族職業(yè)技能提升的在線教育平臺。這里有海量免費課程,在這里你可以學(xué)習(xí)牛人的實際工作經(jīng)驗,也能夠大幅提升職業(yè)技能,提高工作效率,帶來經(jīng)濟(jì)效益!除了陳敬雷老師的課以外,還有上千萬好課免費分享。全都在充電了么App上。充電了么APP是專注上班族職業(yè)培訓(xùn)充電學(xué)習(xí)的在線教育平臺。各大安卓商店和蘋果App Store搜索“充電了么”即可下載。按照下圖輸入網(wǎng)址也可以下載哦~

充電了么官網(wǎng):http://www.chongdianleme.com/

充電了么App官網(wǎng)下載地址:https://a.app.qq.com/o/simple.jsp?pkgname=com.charged.app

功能特色如下:

【全行業(yè)職位】 - 專注職場上班族職業(yè)技能提升

覆蓋所有行業(yè)和職位,不管你是上班族,高管,還是創(chuàng)業(yè)都有你要學(xué)習(xí)的視頻和文章。其中大數(shù)據(jù)智能AI、區(qū)塊鏈、深度學(xué)習(xí)是互聯(lián)網(wǎng)一線工業(yè)級的實戰(zhàn)經(jīng)驗。

除了專業(yè)技能學(xué)習(xí),還有通用職場技能,比如企業(yè)管理、股權(quán)激勵和設(shè)計、職業(yè)生涯規(guī)劃、社交禮儀、溝通技巧、演講技巧、開會技巧、發(fā)郵件技巧、工作壓力如何放松、人脈關(guān)系等等,全方位提高你的專業(yè)水平和整體素質(zhì)。

【牛人課堂】 - 學(xué)習(xí)牛人的工作經(jīng)驗

1.智能個性化引擎:

海量視頻課程,覆蓋所有行業(yè)、所有職位,通過不同行業(yè)職位的技能詞偏好挖掘分析,智能匹配你目前職位最感興趣的技能學(xué)習(xí)課程。

2.聽課全網(wǎng)搜索

輸入關(guān)鍵詞搜索海量視頻課程,應(yīng)有盡有,總有適合你的課程。

3.聽課播放詳情

視頻播放詳情,除了播放當(dāng)前視頻,更有相關(guān)視頻課程和文章閱讀,對某個技能知識點強(qiáng)化,讓你輕松成為某個領(lǐng)域的資深專家。

【精品閱讀】 - 技能文章興趣閱讀

1.個性化閱讀引擎:

千萬級文章閱讀,覆蓋所有行業(yè)、所有職位,通過不同行業(yè)職位的技能詞偏好挖掘分析,智能匹配你目前職位最感興趣的技能學(xué)習(xí)文章。

2.閱讀全網(wǎng)搜索

輸入關(guān)鍵詞搜索海量文章閱讀,應(yīng)有盡有,總有你感興趣的技能學(xué)習(xí)文章。

【機(jī)器人老師】 - 個人提升趣味學(xué)習(xí)

基于搜索引擎和智能深度學(xué)習(xí)訓(xùn)練,為您打造更懂你的機(jī)器人老師,用自然語言和機(jī)器人老師聊天學(xué)習(xí),寓教于樂,高效學(xué)習(xí),快樂人生。

【精短課程】 - 高效學(xué)習(xí)知識

海量精短牛人課程,滿足你的時間碎片化學(xué)習(xí),快速提高某個技能知識點。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容