1. 程式人生 > 其它 >圖解大資料 | 實操案例-Hive搭建與應用案例

圖解大資料 | 實操案例-Hive搭建與應用案例

作者:[韓信子](https://github.com/HanXinzi-AI)@[ShowMeAI](http://www.showmeai.tech/) [教程地址](http://www.showmeai.tech/tutorials/84):http://www.showmeai.tech/tutorials/84 [本文地址](http://www.showmeai.tech/article-detail/171):http://www.showmeai.tech/article-detail/171 宣告:版權所有,轉載請聯絡平臺與作者並註明出處

1.Hive 搭建與配置

大資料生態中最重要的工具平臺之一是Hive,它是離線計算的關鍵元件,常用於數倉建設,在公司內會通過SQL實現大資料的統計與報表。下面來看一下Hive的搭建和配置使用方法。

1)下載Hive

安裝Hive過程可以參考官方文件https://cwiki.apache.org/confluence/display/Hive/GettingStarted

按照檔案建議在 http://www.apache.org/dyn/closer.cgi/hive/ 下載最新的release,這裡以Hive3.1.3為例講解。

把安裝檔案解壓到安裝有hadoop環境的機器上:

root@ubuntu:~/bigdata# ll
total 20
drwxr-xr-x 27 root root 4096 Sep 30 07:24 azkaban/
drwxr-xr-x  2 root root 4096 Oct 13 08:36 demo/
drwxr-xr-x 12 1001 1001 4096 Sep 30 09:43 hadoop-3.3.0/
drwxr-xr-x 11 root root 4096 Oct 13 07:58 hive-3.1.3/
drwxr-xr-x 32 work work 4096 Aug 28 07:28 spark-3.0.1/
root@ubuntu:~/bigdata# pwd
/root/bigdata

接下來把Hive的bin目錄匯出PATH:

root@ubuntu:~/bigdata# cat /etc/profile.d/java.sh 
export PATH=/usr/local/jdk/bin:/root/bigdata/hadoop-3.3.0/bin:/root/bigdata/spark-3.0.1/bin:/root/bigdata/hive-3.1.3/bin:${PATH}

升級guava依賴為hadoop版本:

mv lib/guava-19.0.jar lib/guava-19.0.jar.bk 
ln -s  /root/bigdata/hadoop-3.3.0/share/hadoop/hdfs/lib/guava-27.0-jre.jar  /root/bigdata/hive-3.1.3/lib/guava-27.0-jre.jar

上述第一條命令先備份了Hive自帶的guava依賴包,然後將hadoop自帶的更高版本軟鏈過來,這個版本一致性是Hive正常執行的關鍵之一。

2)安裝MYSQL

hive的元資料服務是獨立部署的,它基於mysql儲存資料。可以使用apt命令在ubuntu環境安裝oracle mysql:

apt-get install mysql-server

如果使用 mysql -h localhost -u root -p 登入時,提示 access denied,那需要找到和刪除 mysql user 表中的一條 localhost 的特殊規則:

delete from user where User=’root’ and Host=’localhost’;
FLUSH PRIVILEGES;

接著建立hive資料庫:

create database hive;

接著通過wget命令下載 JDBC mysql,並把該Jar放到hive的lib目錄下(hive metastore服務將用該JDBC驅動連線mysql讀寫元資料):

wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.21/mysql-connector-java-8.0.21.jar
mv mysql-connector-java-8.0.21.jar lib

3)配置Hive

Hive會自動載入 conf/hive-site.xml 配置檔案,官方在 conf/hive-default.xml.template 提供了一個模板檔案,裡面是 Hive 載入不到 hive-site.xml 時使用的預設值,可以參考 conf/hive-default.xml.template來填寫 hive-site.xml,下面是一個配置好的樣本(只配置了必要項):

root@ubuntu:~/bigdata/hive-3.1.3# cat conf/hive-site.xml 
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
        <property>
                <name>hive.cli.print.header</name>
                <value>true</value>
                <description>Whether to print the names of the columns in query output.</description>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionURL</name>
                <value>jdbc:mysql://localhost:3306/hive</value>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionDriverName</name>
                <value>com.mysql.cj.jdbc.Driver</value>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionUserName</name>
                <value>root</value>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionPassword</name>
                <value>xxxxx</value>
        </property>
        <property>
                <name>hive.metastore.uris</name>
                <value>thrift://localhost:9083</value>
                <description>Thrift URI for the remote metastore. Used by metastore client to connect to remote metastore.</description>
        </property>
</configuration>

其中核心的專案解釋如下:

  • hive.cli.print.header:Hive命令列工具將列印table的表頭,方便閱讀結果
  • javax.jdo.option.ConnectionURL:資料庫JDBC URL,這裡就是mysql的Hive資料庫
  • javax.jdo.option.ConnectionDriverName:JDBC類名,8.x版本Mysql jar的類名有所變化,需要注意
  • javax.jdo.option.ConnectionUserName:mysql使用者名稱
  • javax.jdo.option.ConnectionPassword:mysql密碼
  • hive.metastore.uris:啟動metastore服務的監聽地址

4)啟動metastore服務

先執行Hive建表命令,完成mysql元資料建表:

bin/schematool -dbType mysql -initSchema

執行命令:

nohup hive –service metastore &

服務將監聽在 localhost:9083 埠,生產環境需要讓host是可以被其他伺服器訪問到的,因為訪問metastore服務的客戶端不一定在本機。

現在命令列使用Hive命令,將會自動根據 hive-site.xml 連線到 metastore 服務,執行Hive命令做一下測試:

root@ubuntu:~/bigdata/hive-3.1.3# hive
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/root/bigdata/hive-3.1.3/lib/log4j-slf4j-impl-2.10.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/root/bigdata/hadoop-3.3.0/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
Hive Session ID = f0d4bf60-d85f-456a-98fb-e904d50f5242

Logging initialized using configuration in jar:file:/root/bigdata/hive-3.1.3/lib/hive-common-3.1.3.jar!/hive-log4j2.properties Async: true
Hive Session ID = 959e0cda-f8eb-4fc1-b798-cb5175e735d2
Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) or using Hive 1.X releases.

hive> show databases;
OK
database_name
default
Time taken: 0.516 seconds, Fetched: 2 row(s)

Hive命令過後進入,可以看到自帶的default資料庫,並且還提示Hive目前使用MR作為計算引擎,實際Hive建議開始使用spark或者tez作為SQL的底層計算引擎,未來最終會徹底取消MR。

目前繼續使用MR作為計算引擎即可,Hive會根據hadoop命令自動找到hadoop和yarn配置檔案,最終SQL是通過MR執行在yarn上完成計算的。

以上就是Hive的完整搭建過程,小夥伴們就可以歡快地開始使用Hive了。

2.Hive應用案例

本案例對視訊網站的資料進行各種指標分析,為管理者提供決策支援。

1)需求描述

統計youtube影音視訊網站的常規指標,各種TopN指標:

  • 統計視訊觀看數Top10
  • 統計視訊類別熱度Top10
  • 統計視訊觀看數Top20所屬類別
  • 統計視訊觀看數Top50所關聯視訊的所屬類別Rank
  • 統計每個類別中的視訊熱度Top10
  • 統計每個類別中視訊流量Top10
  • 統計上傳視訊最多的使用者Top10以及他們上傳的視訊
  • 統計每個類別視訊觀看數Top10

2)專案表欄位

視訊表

欄位 備註 詳細描述
video id 視訊唯一id 11位字串
uploader 視訊上傳者 上傳視訊的使用者名稱String
age 視訊年齡 視訊在平臺上的整數天
category 視訊類別 上傳視訊指定的視訊分類
length 視訊長度 整形數字標識的視訊長度
views 觀看次數 視訊被瀏覽的次數
rate 視訊評分 滿分5分
ratings 流量 視訊的流量,整型數字
conments 評論數 一個視訊的整數評論數
related ids 相關視訊id 相關視訊的id,最多20個

使用者表

欄位 備註 欄位型別
uploader 上傳者使用者名稱 string
videos 上傳視訊數 int
friends 朋友數量 int

ETL原始資料

通過觀察原始資料形式,可以發現,視訊可以有多個所屬分類,每個所屬分類用 & 符號分割,且分割的兩邊有空格字元,同時相關視訊也是可以有多個元素,多個相關視訊又用 \t 進行分割。

為了分析資料時方便對存在多個子元素的資料進行操作,首先進行資料重組清洗操作。即:將所有的類別用 & 分割,同時去掉兩邊空格,多個相關視訊 id 也使用 & 進行分割。

核心要做三件事情:

  • 長度不夠9的刪掉
  • 視訊類別刪掉空格
  • 該相關視訊的分割符

3)準備工作

(1)建立 Hive 表

建立表:youtubevideo_oriyoutubevideo_user_ori
建立表:youtubevideo_orcyoutubevideo_user_orc

--建立: youtubevideo_ori表
create table youtubevideo_ori(
    videoId string, 
    uploader string, 
    age int, 
    category array<string>, 
    length int, 
    views int, 
    rate float, 
    ratings int, 
    comments int,
    relatedId array<string>)
row format delimited
fields terminated by "\t"
collection items terminated by "&"
stored as textfile;

--建立 youtubevideo_user_ori表:
create table youtubevideo_user_ori(
    uploader string,
    videos int,
    friends int)
row format delimited
fields terminated by "\t" 
stored as textfile;

--建立 youtubevideo_orc表:
create table youtubevideo_orc(
    videoId string, 
    uploader string, 
    age int, 
    category array<string>, 
    length int, 
    views int, 
    rate float, 
    ratings int, 
    comments int,
    relatedId array<string>)
row format delimited fields terminated by "\t" 
collection items terminated by "&" 
stored as orc;

--建立 youtubevideo_user_orc表:
create table youtubevideo_user_orc(
    uploader string,
    videos int,
    friends int)
row format delimited
fields terminated by "\t" 
stored as orc;

(2)匯入ETL後的資料

youtubevideo_ori

load data inpath "/output/youtube_video" into table youtubevideo_ori;

youtubevideo_user_ori

load data inpath "/youtube_video/user" into table youtubevideo_user_ori;

(3)向ORC表插入資料

youtubevideo_orc

insert overwrite table youtubevideo_orc select * from youtubevideo_ori;

youtubevideo_user_orc

insert into table youtubevideo_user_orc select * from youtubevideo_user_ori;

3.業務分析

1)統計視訊觀看數 top10

思路:使用order by按照views欄位做一個全域性排序即可,同時設定只顯示前10條。

SELECT   videoid,
         uploader,
         age,
         category,
         length,
         views,
         rate,
         ratings,
         comments
FROM     youtubevideo_orc
ORDER BY views DESC limit 10;

-- 方式2SELECT *

FROM  (
                SELECT   videoid ,
                         age,
                         category,
                         length,
                         views,
                         Row_number() OVER( ORDER BY views DESC) AS rn
                FROM     youtubevideo_orc )t
WHERE  t.rn <= 10;

2)統計視訊類別熱度Top10

思路:即統計每個類別有多少個視訊,顯示出包含視訊最多的前10個類別。

  • ① 需要按照類別group by聚合,然後count組內的videoId個數即可。
  • ② 因為當前表結構為:一個視訊對應一個或多個類別。所以如果要group by類別,需要先將類別進行列轉行(展開),然後再進行count即可。
  • ③ 最後按照熱度排序,顯示前10條。
SELECT   category_name     AS category,
         Count(t1.videoid) AS hot
FROM     (
                SELECT videoid,
                       category_name
                FROM   youtubevideo_orc lateral view explode(category) t_catetory as category_name) t1
GROUP BY t1.category_name
ORDER BY hot DESC limit 10;

3)統計出視訊觀看數最高的20個視訊的所屬類別以及類別包含Top20視訊的個數

思路:

  • ① 先找到觀看數最高的20個視訊所屬條目的所有資訊,降序排列
  • ② 把這20條資訊中的category分裂出來(列轉行)
  • ③ 最後查詢視訊分類名稱和該分類下有多少個Top20的視訊
SELECT   category_name     AS category,
         Count(t2.videoid) AS hot_with_views
FROM     (
                SELECT videoid,
                       category_name
                FROM   (
                                SELECT   *
                                FROM     youtubevideo_orc
                                ORDER BY views DESC limit 20) t1 lateral VIEW explode(category) t_catetory as category_name) t2
GROUP BY category_name
ORDER BY hot_with_views DESC;

4)統計每個類別中的視訊熱度Top10,以Music為例

思路:

  • ① 要想統計Music類別中的視訊熱度Top10,需要先找到Music類別,那麼就需要將category展開,所以可以建立一張表用於存放categoryId展開的資料。
  • ② 向category展開的表中插入資料。
  • ③ 統計對應類別(Music)中的視訊熱度。
--建立表類別表:
CREATE TABLE youtubevideo_category
             (
                          videoid STRING,
                          uploader STRING,
                          age INT,
                          categoryid STRING,
                          length INT,
                          views  INT,
                          rate FLOAT,
                          ratings  INT,
                          comments INT,
                          relatedid ARRAY<string>
             )
             row format delimited fields terminated BY "\t" collection items terminated BY "&" stored AS orc;

--向類別表中插入資料:
INSERT INTO table youtubevideo_category
SELECT videoid,
       uploader,
       age,
       categoryid,
       length,
       views,
       rate,
       ratings,
       comments,
       relatedid
FROM   youtubevideo_orc lateral view explode(category) catetory AS categoryid;

--統計Music類別的Top10(也可以統計其他)
SELECT   videoid,
         views
FROM     youtubevideo_category
WHERE    categoryid = "Music"
ORDER BY views DESC limit 10;

-- 方式2SELECT *
FROM  (
                SELECT   videoid ,
                         age,
                         categoryid,
                         length,
                         views,
                         Row_number() OVER( ORDER BY views DESC) AS rn
                FROM     youtubevideo_category
                WHERE    categoryid = "music" )t
WHERE  t.rn <= 10;

5)統計每個類別中視訊流量Top10

思路:

  • ① 建立視訊類別展開表(categoryId列轉行後的表)
  • ② 按照ratings排序即可
SELECT *
FROM  (SELECT videoid,
              age,
              categoryid,
              length,
              ratings,
              Row_number()
                OVER(
                  partition BY categoryid
                  ORDER BY ratings DESC) AS rn
       FROM   youtubevideo_category)t
WHERE  t.rn <= 10; 

6)統計上傳視訊最多的使用者Top10以及他們上傳的觀看次數在前10的視訊

思路:

  • ① 先找到上傳視訊最多的10個使用者的使用者資訊
  • ② 通過uploader欄位與youtubevideo_orc表進行join,得到的資訊按照views觀看次數進行排序即可。
--第一步:
SELECT *
FROM   youtubevideo_user_orc
ORDER  BY videos DESC
LIMIT  10;

--第二步:
SELECT t2.videoid,
       t2.uploader,
       t2.views,
       t2.ratings,
       t1.videos,
       t1.friends
FROM   (SELECT *
        FROM   youtubevideo_user_orc
        ORDER  BY videos DESC
        LIMIT  10) t1
       JOIN youtubevideo_orc t2
         ON t1.uploader = t2.uploader
ORDER  BY views DESC
LIMIT  20;

ShowMeAI相關文章推薦

ShowMeAI系列教程推薦