第四章 大数据之hive搭建
這是大數據測試測試第四章,可參考大數據測試系列
說明
- 學習本教程,請先看完第三章 大數據之Hadoop搭建
- 本次教程主要來自基于Hadoop的數據倉庫Hive 學習指南,本次的內容全部經過了自己的實踐,與參考文檔中不一致的地方,也是經過查詢各種資料和實踐通過
hive簡單介紹
使用 hive 的命令行接口,感覺很像操作關系數據庫,但是 hive 和關系數據庫還是有很大的不同,下面我就比較下 hive 與關系數據庫的區別,具體如下:
- Hive 和關系數據庫存儲文件的系統不同,Hive 使用的是 hadoop 的 HDFS(hadoop 的分布式文件系統),關系數據庫則是服務器本地的文件系統;
- hive 使用的計算模型是 mapreduce,而關系數據庫則是自己設計的計算模型;
- 關系數據庫都是為實時查詢的業務進行設計的,而 Hive 則是為海量數據做數據挖掘設計的,實時性很差;實時性的區別導致 Hive 的應用場景和關系數據庫有很大的不同;
安裝hive
- 下載版本選擇為3.1.2
配置環境
[hadoop@VM-24-13-centos local]$ vi ~/.bashrcexport HIVE_HOME=/usr/local/hive export PATH=$PATH:$HIVE_HOME/bin export HADOOP_HOME=/usr/local/hadoop-
生效環境變量
source ~/.bashrc -
修改/usr/local/hive/conf下的hive-site.xml
cd /usr/local/hive/conf mv hive-default.xml.template hive-default.xml[hadoop@VM-24-13-centos conf]$ vi hive-site.xml<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration><property><name>javax.jdo.option.ConnectionURL</name><value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value><description>JDBC connect string for a JDBC metastore</description></property><property><name>javax.jdo.option.ConnectionDriverName</name><value>com.mysql.jdbc.Driver</value><description>Driver class name for a JDBC metastore</description></property><property><name>javax.jdo.option.ConnectionUserName</name><value>hive</value><description>username to use against metastore database</description></property><property><name>javax.jdo.option.ConnectionPassword</name><value>hive1234</value><description>記得在創建用戶時,密碼要和這個對應</description></property> </configuration>
安裝和配置mysql
安裝mysql
- 我之前已經裝好了,省略此步驟
配置mysql
- 新建hive數據庫
- 配置mysql允許hive接入
配置hive
啟動hive
-
啟動hive之前,請先啟動hadoop集群。
start-all.sh #啟動hadoop hive #啟動hive
錯誤處理
hive> show databases;# 輸入后報錯 FAILED: HiveException java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient- Hive現在包含一個用于 Hive Metastore 架構操控的脫機工具,名為 schematool.此工具可用于初始化當前 Hive 版本的 Metastore 架構。此外,其還可處理從較舊版本到新版本的架構升級,用下面的命令:
- 打開mysql下載鏈接
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-bvJeGh4O-1652088056606)(image-20211208112332826.png)]
- 下載安裝mysql驅動
- 再次schematool初始化就可以了
- 進入hive
- 如果要退出Hive交互式執行環境,可以輸入如下命令:
Hive的常用HiveQL操作
Hive基本數據類型
- Hive支持基本數據類型和復雜類型, 基本數據類型主要有數值類型(INT、FLOAT、DOUBLE ) 、布爾型和字符串, 復雜類型有三種:ARRAY、MAP 和 STRUCT。
基本數據類型
- TINYINT: 1個字節
- SMALLINT: 2個字節
- INT: 4個字節
- BIGINT: 8個字節
- BOOLEAN: TRUE/FALSE
- FLOAT: 4個字節,單精度浮點型
- DOUBLE: 8個字節,雙精度浮點型STRING 字符串
復雜數據類型
- ARRAY: 有序字段
- MAP: 無序字段
- STRUCT: 一組命名的字段
用的HiveQL操作命令
-
Hive常用的HiveQL操作命令主要包括:數據定義、數據操作。接下來詳細介紹一下這些命令即用法(想要了解更多請參照《Hive編程指南》一書)
-
數據定義:主要用于創建修改和刪除數據庫、表、視圖、函數和索引。
創建、修改和刪除數據庫
create database if not exists hive; #創建數據庫 show databases; #查看Hive中包含數據庫 show databases like 'h.*'; #查看Hive中以h開頭數據庫 use hive; # 使用數據庫 show tables; # 查看表列表 drop table usr; # 刪除表創建、修改和刪除表
#創建內部表(管理表) create table if not exists hive.usr(name string comment 'username', # name表示字段命,string表示字段類型,comment后面內容表示說明pwd string comment 'password',address struct<street:string,city:string,state:string,zip:int> comment 'home address',identify map<int,tinyint> comment 'number,sex') comment 'description of the table' tblproperties('creator'='me','time'='2016.1.1'); #tblproperties 設置表的屬性 #創建外部表 create external table if not exists usr2(name string,pwd string,address struct<street:string,city:string,state:string,zip:int>,identify map<int,tinyint>) row format delimited fields terminated by ',' # 字段分隔符來進行分割,如:test1,223456,湖南省location '/usr/local/hive/warehouse/hive.db/usr'; # LOCATION一般與外部表(EXTERNAL)一起使用。一般情況下hive元數據默認保存在<hive.metastore.warehouse.dir>中。# 這個字段的適用場景是:數據已經存在HDFS上不能移動位置了,那么就通過這個字段讓表可以直接讀到這份數據。另外,要注意建表的時候,應該讓表變成外部表。#創建分區表 create table if not exists usr3(name string,pwd string,address struct<street:string,city:string,state:string,zip:int>,identify map<int,tinyint>) partitioned by(city string,state string); # 雙分區#復制usr表的表模式 create table if not exists hive.usr1 like hive.usr; show tables in hive; show tables 'u.*'; #查看hive中以u開頭的表 describe hive.usr; #查看usr表相關信息 alter table hive.usr rename to custom; #重命名表 #為表增加一個分區 alter table usr3 add if not exists partition(city="beijing",state="China") location '/usr/local/hive/warehouse/usr3/China/beijing'; #修改分區路徑 alter table usr3 partition(city="beijing",state="China") set location '/usr/local/hive/warehouse/usr3/CH/beijing'; #刪除分區 alter table usr3 drop if exists partition(city="beijing",state="China"); #修改列信息,注意這里,如果使用 after時,交換元素類型不一致,就無法交換成功 alter table custom change column username username string after pwd;alter table custom add columns(hobby string); #增加列 alter table custom replace columns(uname string); #刪除替換列 alter table custom set tblproperties('creator'='liming'); #修改表屬性 alter table usr3 partition(city="beijing",state="China") set fileformat sequencefile; #修改存儲屬性 use hive; #切換到hive數據庫下 drop table if exists usr1; #刪除表 drop database if exists hive cascade; #刪除數據庫和它中的表參考
-
Hive的數據模型及各模塊的應用場景 結合這個Hive之數據模型來看效果比較好
-
Hive在建表時的分隔符的設置
-
hive 中的location
視圖和索引的創建、修改和刪除
- 主要語法如下,用戶可自行實現。
-
因為視圖是只讀的,所以 對于視圖只允許改變元數據中的 tblproperties屬性。
#刪除視圖 drop view if exists view_name; #創建索引 create index index_name on table table_name(partition_name/column_name) as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild....; -
這里’org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler’是一個索引處理器,即一個實現了索引接口的Java類,另外Hive還有其他的索引實現。
- 如果使用 deferred rebuild,那么新索引成空白狀態,任何時候可以進行第一次索引創建或重建。
說明
- 這里沒有實踐,示例可以參考這里hadoop Hive 的建表 和導入導出及索引視圖
用戶自定義函數
-
沒有實踐自定義函數,后續有需求在學
-
在新建用戶自定義函數(UDF)方法前,先了解一下Hive自帶的那些函數。show functions; 命令會顯示Hive中所有的函數名稱:
- 若想要查看具體函數使用方法可使用describe function 函數名:
-
首先編寫自己的UDF前需要繼承UDF類并實現evaluate()函數,或是繼承GenericUDF類實現initialize()函數、evaluate()函數和getDisplayString()函數,還有其他的實現方法,感興趣的用戶可以自行學習。
-
另外,如果用戶想在Hive中使用該UDF需要將我們編寫的Java代碼進行編譯,然后將編譯后的UDF二進制類文件(.class文件)打包成一個JAR文件,然后在Hive會話中將這個JAR文件加入到類路徑下,在通過create function語句定義好使用這個Java類的函數。
數據操作
- 主要實現的是將數據裝載到表中(或是從表中導出),并進行相應查詢操作,對熟悉SQL語言的用戶應該不會陌生。
向表中裝載數據
這里我們以只有兩個屬性的簡單表為例來介紹。首先創建表stu和course,stu有兩個屬性id與name,course有兩個屬性cid與sid。
create table if not exists hive.stu(id int,name string) row format delimited fields terminated by '\t'; create table if not exists hive.course(cid int,sid int) row format delimited fields terminated by '\t';- 向表中裝載數據有兩種方法:從文件中導入和通過查詢語句插入。
從文件中導入
- 假如這個表中的記錄存儲于文件stu.txt中,該文件的存儲路徑為/usr/local/hadoop/examples/stu.txt,內容如下。
-
下面我們把這個文件中的數據裝載到表stu中,操作如下:
hive> use hive; hive> load data local inpath '/usr/local/hadoop/examples/stu.txt' overwrite into table stu; Loading data to table hive.stu OK # 查詢到數據 hive> select * from hive.stu; OK 1 xiapi 2 xiaoxue 3 qingqing Time taken: 1.324 s- 如果stu.txt文件存儲在HDFS 上,則不需要 local 關鍵字。
通過查詢語句插入
使用如下命令,創建stu1表,它和stu表屬性相同,我們要把從stu表中查詢得到的數據插入到stu1中:
hive> create table stu1 as select id,name from stu; ... Moving data to directory hdfs://localhost:9000/user/hive/warehouse/hive.db/.hive-staging_hive_2021-12-10_10-42-32_320_1543053100774530944-1/-ext-10002 Moving data to directory hdfs://localhost:9000/user/hive/warehouse/hive.db/stu1 MapReduce Jobs Launched: Stage-Stage-1: HDFS Read: 31 HDFS Write: 114 SUCCESS Total MapReduce CPU Time Spent: 0 msec OK # 查詢到stu1表結構如下 hive> describe stu1; OK id int name string Time taken: 0.268 seconds, Fetched: 2 row(s)上面是創建表,并直接向新表插入數據;若表已經存在,向表中插入數據需執行以下命令:
# 這里關鍵字overwrite的作用是替換掉表(或分區)中原有數據,換成into關鍵字,直接追加到原有內容后。 hive> insert overwrite table stu1 select id,name from stu where(id='1');# 查詢發現只有id為1的數據,其他數據全部清空 hive> select * from hive.stu1; OK 1 xiapi從表中導出數據
導出到本地文件
hive> insert overwrite local directory '/usr/local/hadoop/examples/export_stu' select * from hive.stu; ... Moving data to local directory /usr/local/hadoop/examples/export_stu MapReduce Jobs Launched: Stage-Stage-1: HDFS Read: 30 HDFS Write: 0 SUCCESS# 查看導出的文件 [hadoop@VM-24-13-centos local]$ cat /usr/local/hadoop/examples/export_stu/000000_0 1xiapi 2xiaoxue 3qingqing導出到hdfs
hive> insert overwrite directory '/usr/local/hadoop/examples/export_hdfs_stu' select * from hive.stu; ...Moving data to directory /usr/local/hadoop/examples/export_hdfs_stu MapReduce Jobs Launched: Stage-Stage-1: HDFS Read: 30 HDFS Write: 30 SUCCESS Total MapReduce CPU Time Spent: 0 msec OK# 查看導出成功的數據 hive> dfs -cat /usr/local/hadoop/examples/export_hdfs_stu/*; 1xiapi 2xiaoxue 3qingqing查詢操作
-
和SQL的查詢完全一樣,這里不再贅述。主要使用select…from…where…等語句,再結合關鍵字group by、having、like、rlike等操作。這里我們簡單介紹一下SQL中沒有的case…when…then…句式、join操作和子查詢操作。
-
case…when…then…句式和if條件語句類似,用于處理單個列的查詢結果,語句如下:
- 連接(join)是將兩個表中在共同數據項上相互匹配的那些行合并起來, HiveQL 的連接分為內連接、左向外連接、右向外連接、全外連接和半連接 5 種。
內連接
- 內連接使用比較運算符根據每個表共有的列的值匹配兩個表中的行。
- 首先,我們先把以下內容插入到course表中
-
下面, 查詢stu和course表中學號相同的所有行,命令如下:
hive> select stu.*, course.* from stu join course on(stu.id=course.sid);OK 1 xiapi 2 1 1 xiapi 3 1 2 xiaoxue 1 2 Time taken: 11.049 seconds, Fetched: 3 row(s)
右連接
右連接是左向外連接的反向連接,將返回右表的所有行。如果右表的某行在左表中沒有匹配行,則將為左表返回空值。命令
hive> select stu.*, course.* from stu right outer join course on(stu.id=course.sid); Total MapReduce CPU Time Spent: 0 msec OK 2 xiaoxue 1 2 1 xiapi 2 1 1 xiapi 3 1 Time taken: 10.887 seconds, Fetched: 3 row(s)全連接
全連接返回左表和右表中的所有行。當某行在另一表中沒有匹配行時,則另一個表的選擇列表包含空值。如果表之間有匹配行,則整個結果集包含基表的數據值。命令如下:
hive> select stu.*, course.* from stu full outer join course on(stu .id=course .sid);OK 1 xiapi 3 1 1 xiapi 2 1 2 xiaoxue 1 2 3 qingqing NULL NULL半連接
半連接是 Hive 所特有的, Hive 不支持 in 操作,但是擁有替代的方案;left semi join,稱為半連接, 需要注意的是連接的表不能在查詢的列中,只能出現在 on 子句中。命令如下:
hive> select stu.* from stu left semi join course on(stu .id=course .sid);Total MapReduce CPU Time Spent: 0 msec OK 1 xiapi 2 xiaoxue Time taken: 9.267 seconds, Fetched: 2 row(s)子查詢
標準 SQL 的子查詢支持嵌套的 select 子句,HiveQL 對子查詢的支持很有限,只能在from 引導的子句中出現子查詢。
Hive簡單編程實踐
-
下面我們以詞頻統計算法為例,來介紹怎么在具體應用中使用Hive。詞頻統計算法又是最能體現MapReduce思想的算法之一,這里我們可以對比它在MapReduce中的實現,來說明使用Hive后的優勢。
-
MapReduce實現詞頻統計的代碼可以通過下載Hadoop源碼后,在 $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.0.3.jar 包中找到(wordcount類),wordcount類由63行Java代碼編寫而成。下面首先簡單介紹一下怎么使用MapReduce中wordcount類來統計單詞出現的次數,具體步驟如下:
- 創建input目錄,output目錄會自動生成。其中input為輸入目錄,output目錄為輸出目錄。命令如下:
- 然后,在input文件夾中創建兩個測試文件file1.txt和file2.txt,命令如下:
- 執行如下hadoop命令:
- 我們可以到output文件夾中查看結果,結果如下:
-
下面我們通過HiveQL實現詞頻統計功能,此時只要編寫下面7行代碼,而且不需要進行編譯生成jar來執行。HiveQL實現命令如下:
[hadoop@VM-24-13-centos hadoop]$ hivehive> create table docs(line string); hive> load data inpath 'input' overwrite into table docs; # create table word_count 表示創建數據庫 # as select word, count(1) as count 表示查詢列表,一個word,一個統計值 # from (select explode(split(line,' '))as word from docs) 這里就是從docs復制數據 hive> create table word_count as select word, count(1) as count from (select explode(split(line,' '))as word from docs) w group by word order by word; -
執行后,用select語句查看,結果如下:
hive> select * from word_count; OK hadoop 1 hello 2 world 1 Time taken: 0.148 seconds, Fetched: 3 row(s)
-
由上可知,采用Hive實現最大的優勢是,對于非程序員,不用學習編寫Java MapReduce代碼了,只需要用戶學習使用HiveQL就可以了,而這對于有SQL基礎的用戶而言是非常容易的。
總結
以上是生活随笔為你收集整理的第四章 大数据之hive搭建的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: netty之wakeup详解
- 下一篇: 数据库-乐观锁和悲观锁