Hive搭建
Hive下載&上傳&解壓
Hive下載地址: https://mirrors.tuna.tsinghua.edu.cn/apache/hive/, 選擇想用的版本, 這裏筆者使用apache-hive-1.2.1-bin.tar.gz. 注意下載鏈接中只有1.2.2版本, 原因可能是老版本不再發布, 但1.2.1與1.2.2幾乎無差別.
下載完成之後, 通過傳輸工具(Xftp,filezilla等)將Hive安裝包上傳到集羣的node01和client節點上.
解壓Hive安裝包:
tar -zxf apache-hive-1.2.1-bin.tar.gz -C /opt/software/hive
修改hive-site.xml.template文件名稱:
cd /opt/software/hive/apache-hive-1.2.1/conf
cp hive-default.xml.template hive-site.xml
Hive搭建的三種模式
(一)基於Derby的Local模式(不常用)
搭建
在Hive簡介中我們說過, Hive依賴關係型數據庫存儲元數據信息. Derby是Hive默認的元數據庫(Metastore).
這種搭建方式是最簡單的, 只需在改名後的hive-site.xml中稍作修改即可.
打開hive-site文件:
vim /opt/software/hive/apache-hive-1.2.1/conf/hive-site.xml
首先刪除<configuration> </configuration>標籤對中的內容然後加入以下內容
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:derby:;databaseName=metastore_db;create=true</value>
</property>
<!-- 連接本地Derby的Url -->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>org.apache.derby.jdbc.EmbeddedDriver</value>
</property>
<!-- 連接Derby的驅動包 -->
<property>
<name>hive.metastore.local</name>
<value>true</value>
</property>
<!-- 元數據庫是否存放在本地,true代表存放在本地 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<!-- Hive中所有數據存儲在HDFS上的路徑 -->
操作
Hive依賴於HDFS和MapReduce, 因此在啓動Hive之前, 應先啓動HDFS和Yarn(如果沒有使用SQL語句可以不用啓動Yarn).
啓動Hive, 進入Hive Shell (需要先配置環境變量)
hive
此時, 啓動Hive會報java.lang.IncompatibleClassChangeError的錯, 解決方法點此查看
需要注意:
- 使用derby存儲方式時, 運行hive會在當前目錄生成一個derby文件和一個metastore_db目錄.
- Derby模式的最大缺點是不允許多用戶同時操作Hive, 如果一個用戶已經打開Hive Shell, 那麼不允許第二人再連接到Hive上. 這個缺點是由Derby自身缺陷造成的, 而非Hive的問題. 因此這種搭建方式不常用.
(二)基於MySQL的Local模式
上文提到Derby存在缺陷, 爲了彌補這方面的不足, 基本上是使用mysql數據庫來存儲Hive的元數據. 基於MySQL其實就是使用mysql來代替derby.
這種存儲方式需要在本地運行一個mysql服務器, 然後再配置Hive.
在client節點安裝mysql
由於client上有Hadoop的安裝包並配置HADOOP_HOME, 即能找到Hadoop的配置文件, 因此client端搭建Hive可以操作Hadoop集羣.
- 安裝mysql並啓動
yum install mysql-server -y
service mysqld start
查看mysql狀態:
service mysqld status
- 修改權限
先登錄mysql
mysql -uroot -p77123
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '77123' WITH GRANT OPTION;
注意這裏*IDENTIFIED BY ‘77123’*是我本地mysql的root用戶密碼, 修改權限時需要改成對應mysql的密碼.
- 刪除多餘字段
use mysql;
delete from user where host like '%127%';
user 表中多餘的數據字段可能會對權限造成影響. 最終結果如下:
- 創建用戶和數據庫
CREATE USER 'hive'@'%' IDENTIFIED BY '77123';
CREATE DATABASE hive_meta;
- 授權hive用戶
grant all privileges on hive_meta.* to hive@"%" identified by '77123';
雖然hive用戶對hive_meta數據庫有操作權限, 但如果這個數據庫不存在, hive用戶是沒有權限創建這個數據庫的, 所以需提前創建好hive_meta數據庫.
- 刷新權限
flush privileges;
- 設置開機自啓動
chkconfig mysqld on
- 導入mysql驅動包
使用mysql的方式, 需將mysql的驅動jar包放在Hive的lib目錄下, 這裏的驅動包與使用java連接mysql的驅動包一樣.
在client節點上安裝Hive
這種搭建方式是最簡單的, 只需在改名後的hive-site.xml中稍作修改即可.
打開hive-site文件:
vim /opt/software/hive/apache-hive-1.2.1/conf/hive-site.xml
首先刪除<configuration> </configuration>標籤對中的內容然後加入以下內容
<configuration>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive_localmysql/warehouse</value>
</property>
<!-- HDFS存放路徑 -->
<property>
<name>hive.metastore.local</name>
<value>true</value>
</property>
<!-- hive工具和mysql是否在同一個節點 -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost/hive_meta</value>
</property>
<!-- 連接到mysql的數據庫Url地址 -->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<!-- mysql的驅動包 -->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hive</value>
</property>
<!-- 連接Hive的用戶名 -->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>77123</value>
</property>
<!-- 連接Hive的hive用戶的密碼 -->
</configuration>
操作
操作和出現的問題與Derby模式同樣, 此處不再贅述.
當創建一個表之後, 在mysql的hive_meta數據庫中, 有個TBLS表, 通過select * from TBLS
可以看到在Hive中創建的表本身的信息(即元數據).
同時, 基於mysql允許多個用戶同時訪問Hive工具.
(三)基於MySQL的遠程(Remote)模式(常用模式)
原理
在搭建之前, 我們先來了解一下基於MySQL遠程模式的原理.
client節點上的Hive工具提供元數據存儲服務. 啓動該服務後, client節點會啓動一個RunJar進程, 這個進程對外提供元數據服務.
在其他節點(比如node01)上, 解壓一個Hive工具, 通過配置hive-site.xml文件, 使得node01節點的Hive工具能夠連接到client節點提供的元數據服務.
這中模式最大的優點在於 – 解耦. 對應上圖來說, node01節點不需要再安裝mysql數據庫, 而且如果有其它節點(比如node02)需要使用Hive工具, 只要解壓簡單一配置就可以操作同一個庫中的數據(因爲都是使用同一個mysql), 從而避免集羣數據的隔離問題.
在client節點安裝mysql
這種方式首先也是需要在client節點安裝mysql數據庫, 具體流程此處就不再贅述, 跟第二種模式中說明的流程一致.
在client節點配置Hive工具(服務端)
服務端搭建與mysql的本地模式一致.
打開hive-site文件:
vim /opt/software/hive/apache-hive-1.2.1/conf/hive-site.xml
修改配置
<configuration>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive_meta/warehouse</value>
</property>
<property>
<name>hive.metastore.local</name>
<value>true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://192.168.75.137/hive_meta</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hive</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>77123</value>
</property>
</configuration>
在node01節點配置Hive工具(客戶端)
node01節點上也需要解壓一份Hive的安裝包, 此處省略.
打開hive-site文件:
vim /opt/software/hive/apache-hive-1.2.1/conf/hive-site.xml
修改配置, 十分簡單
<configuration>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<!-- HDFS存放路徑 -->
<property>
<name>hive.metastore.local</name>
<value>false</value>
</property>
<!-- 元數據庫非本地 -->
<property>
<name>hive.metastore.uris</name>
<value>thrift://192.168.75.137:9083</value>
</property>
<!-- 提供元數據服務的client節點的url -->
</configuration>
使用Hive工具簡單操作
Hive環境變量配置
vim ~/.bashrc
在文件最後插入:
export HIVE_HOME=/opt/software/hive/apache-hive-1.2.1-bin
export PATH=$PATH:$HIVE_HOME/bin
讓文件生效
source ~/.bashrc
Hive啓動
- 兩種本地模式啓動Hive
hive
- 基於mysql的遠程模式
Hive服務端, 開啓服務
hive --service metastore >>/opt/software/hive/log/meta.log 2>&1 &
Hive客戶端, 連接服務
hive
不論哪種搭建方式, 在啓動Hive之前, 應先啓動HDFS或Yarn.啓動Hive會報java.lang.IncompatibleClassChangeError的錯, 不要忘記解決(如果是版本較新可能不會出現這種問題). 解決方法點此查看
- 簡單操作使用Hive:
創建表:
create table t1(id Int,name String);
插入數據:
insert into t1 values(1,'qb');
解析插入語句後, 會啓動MR任務
查詢表:
select * from t1;
不會啓動MR任務, 直接去HDFS中讀文件
需要注意:
- 簡單的select * 的查詢SQL是不會啓動MR任務的, 只有當SQL語句中帶有where, count, sum等時纔會啓動MR任務;
- insert插入語句會啓動MR任務, 像這種插入少量數據不適合Hive使用, 會非常耗費時間, 通常使用load. insert語句要慎用!