構建資料倉庫Hive
hive是基於Hadoop的一個數據倉庫工具,可以將結構化的資料檔案對映為一張資料庫表,並提供的sql查詢功能,可以將sql語句轉換為MapReduce任務進行執行。 其優點是學習成本低,可以通過類SQL語句快速實現簡單的MapReduce統計,不必開發專門的MapReduce應用,十分適合資料倉庫的統計分析
目錄
架構
1.介面
CLI、Client、WUI。
CLI:最常用,CLI啟動的時候,會同時啟動一個Hive副本
Client:Hive的客戶端,使用者連線至Hive Server。啟動Client模式時,需要指定Hive Server所在的節點,並啟動Hive Server
WUI:通過瀏覽器訪問Hive
2.資料庫
Hive將元資料儲存在資料庫中,如mysql,derby等
Hive中元資料包括表的名字,表的列和分割槽及其屬性,表的資料所在目錄等
3直譯器、編譯器、優化器完成HQL查詢語句從詞法分析、語法分析、編譯、優化以及查詢計劃的生成。生成的查詢計劃儲存在HDFS中,並在隨後有MapReduce呼叫執行
Hive部署
1.安裝Hive
1.安裝Hive
1.將apache-hive-1.2.1-bin.tar.gz壓縮檔案傳到客戶端節點上,並解壓
2.配置環境變數
# 編輯檔案
vim /etc/profile
# 檔案末尾新增
export HIVE_HOME=/data/hive
export PATH=$HIVE_HOME/bin:$HIVE_HOME/conf:$PATH
# 使修改生效
source /etc/profile
2.修改jar包
修改HADOOP_HOME\bin目錄下的jline-*-jar變成HIVE_HOME\lib目錄下的jar包
3.hive三種搭建方式
1. 本地模式(derby):derby與hive工具在同一個節點
缺點:不支援多個使用者同時連線
2. 本地模式(mysql):mysql與hie工具在同一個節點
3. 基於MySQL的遠端模式
2.本地模式(derby)
1.修改hive-site.xml
複製原有的hive-default.xml.template為hive-site.xml
hive-site.xml配置資訊
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:derby:;databaseName=metastore_db;create=true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>org.apache.derby.jdbc.EmbeddedDriver</value>
</property>
<property>
<name>hive.metastore.local</name>
<value>true</value>
</property>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
2.啟動hive
bin/hive
3.本地模式(Mysql)
1.在客戶端節點上安裝一個關係型資料庫(mysql)
yum install mysql-server
2.修改MySQL許可權
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123' WITH GRANT OPTION;
密碼可自定義
3.重新整理MySQL許可權
flush privileges;
4.刪除許可權
刪除多餘會對許可權造成影響的資料,重新整理許可權
#mysql資料庫下的user表
select user,password from user;
刪除多餘會對許可權造成影響的資料,重新整理保留這一個使用者
5.新增使用者
#新增新使用者
CREATE USER 'hive'@'%' IDENTIFIED BY '123';
#給新使用者授權
grant all privileges on hive_meta.* to [email protected]"%" identified by '123';
#重新整理許可權
flush privileges;
密碼可自定義
6.設定開機自啟
chkconfig mysqld on
7.mysql驅動包
將mysql-connector-java-5.1.32-bin.jar放到HIVE_HOME\bin目錄下
8.hvie-site.xml
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive_remote/warehouse</value>
</property>
<property>
<name>hive.metastore.local</name>
<value>true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost/hive_meta?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>hive</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123</value>
</property>
注意許可權:前面給了hive使用者對hive_meta資料庫的操作許可權,如果這個資料庫不存在,hive使用者是沒有許可權建立這個資料庫的,需要提前建立好hive_meta資料庫
注意賬號密碼一致
java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected at jline.TerminalFactory.create(TerminalFactory.java:101)
Hadoop jline版本和hive的jline不一致
4.基於MySQL的遠端模式
1.劃分
服務端 | 客戶端 |
---|---|
client | node01(可多個:node02、node03等) |
2.服務端配置
hive-site.xml:與本地模式(MySQL)一樣
3.客戶端配置
hive-site.xml
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<property>
<name>hive.metastore.local</name>
<value>false</value>
</property>
<property>
<name>hive.metastore.uris</name>
<value>thrift://client:9083</value>
</property>
請注意客戶端地址
4.啟動hive
#1.client端啟動metastore服務,儲存元資料
hive --service metastore
#2.node01端直接使用hive命令
hive
直接使用hive命令,需要配置/etc/profile的環境變數,否則在bin目錄下執行hive命令
可能出現的錯誤:
[ERROR] Terminal initialization failed; falling back to unsupported java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected at jline.TerminalFactory.create(TerminalFactory.java:101)
錯誤的原因: Hadoop jline版本和hive的jline不一致
Hive連線
1.thriftserver(hiveserver2)服務
可以通過修改hive-site.xml檔案自己配置使用者名稱、密碼,需要自己程式設計
1.1.beeline
1.hive-site.xml
<property>
<name>hive.server2.authentication</name>
<value>CUSTOM</value>
</property>
<property>
<name>hive.jdbc_passwd.auth.zhangsan</name>
<value>123456789</value>
</property>
<property>
<name>hive.server2.custom.authentication.class</name>
<value>com.hoe.hive.authoriz.UserPasswdAuth</value>
</property>
賬號密碼可以自己修改,authentication.class是自己程式設計的Java程式碼
2.程式碼
package com.hoe.hive.authoriz;
import javax.security.sasl.AuthenticationException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hive.service.auth.PasswdAuthenticationProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserPasswdAuth implements PasswdAuthenticationProvider {
Logger logger = LoggerFactory.getLogger(UserPasswdAuth.class);
private static final String USER_PASSWD_AUTH_PREFIX = "hive.jdbc_passwd.auth.%s";
private Configuration conf = null;
@Override
public void Authenticate(String userName, String passwd) throws AuthenticationException {
logger.info("user: " + userName + " try login.");
String passwdConf = getConf().get(String.format(USER_PASSWD_AUTH_PREFIX, userName));
if (passwdConf == null) {
String message = "沒有發現密碼 " + userName;
logger.info(message);
throw new AuthenticationException(message);
}
if (!passwd.equals(passwdConf)) {
String message = "使用者名稱密碼不匹配 " + userName;
throw new AuthenticationException(message);
}
}
public Configuration getConf() {
if (conf == null) {
this.conf = new Configuration(new HiveConf());
}
return conf;
}
public void setConf(Configuration conf) {
this.conf = conf;
}
}
3.連線方式
#第一種
./beeline -u jdbc:hive2://node01:10000/test -n zhangsan -p123456789
#第二種
./beeline
!connect jdbc:hive2://node01:10000/test
#輸入賬號
#輸入密碼
1.2.JDBC
編寫java程式碼
package com.hoe.hive.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ConnectHive {
public static String driverName = "org.apache.hive.jdbc.HiveDriver";
public static void main(String[] args) {
try {
Class.forName(driverName);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String url = "jdbc:hive2://node01:10000";
String userName = "zhangsan";
String passwd = "123456789";
Connection conn = null;
try {
conn = DriverManager.getConnection(url, userName, passwd);
Statement statement = conn.createStatement();
String sql = "select * from test.logtbl limit 10";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
System.out.println(resultSet.getString(1) + "-" + resultSet.getString(2));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
注意修改ip、賬號、密碼
2.Web ui
1.原始碼包
apache-hive-1.2.1-src.tar.gz
2.將hwi war包放在HIVE_HOME\bin
將apache-hive-1.2.1-src/hwi/web/*所有檔案達成war包
3.複製jdk/lib/tools.jar到HIVE_HOME/lib下
4.修改hive-site.xml
<property>
<name>hive.hwi.listen.host</name>
<value>0.0.0.0</value>
</property>
<property>
<name>hive.hwi.listen.port</name>
<value>9999</value>
</property>
<property>
<name>hive.hwi.war.file</name>
<value>lib/hive-hwi.war</value>
</property>
5.啟動hwi服務(埠號9999)
hive --service hwi
6.通過瀏覽器來訪問
http://client.9999/hwi/
Hive優化
核心思想:把Hive SQL當成MapReduce程式去優化
select僅查詢本表字段、where僅對本表字段做條件過濾不會被轉為MapReduce來執行
1.模式優化
開啟本地模式
set hive.exec.mode.local.auto=true;
條件:
1.輸入資料大小必須小於引數:hive.exec.mode.local.auto.inputbytes.max(預設128MB)
2.map數必須小於引數:hive.exec.mode.local.auto.tasks.max(預設4)
3.reducce數必須為0或者1
2.平行計算
set hive.exec.parallel=true;
hive.exec.parallel.thread.number是一次SQL計算中允許並行執行的job個數的最大值
3.嚴格模式
#預設是nonstrict,非嚴格模式
set hive.mapred.mode=strict;
查詢限制:
1.對於分割槽表,必須新增where對於分割槽欄位的條件過濾
2.order by語句必須包含limit輸出限制
3.限制執行笛卡爾積的查詢
4.Hive排序
Order By - 對於查詢結果做全排序,只允許有一個reduce處理。當資料量較大時,應慎用。嚴格模式下,必須結合limit來使用
Sort By - 對於單個reduce的資料進行排序
Distribute By - 分割槽,經常和Sort By結合使用達到分割槽排序的效果
Cluster By - 相當於 Sort By + Distribute By。不能通過asc、desc的方式指定排序規則,可通過 distribute by column sort by column asc|desc 的方式
5.Hive Join
Join計算時,將小表(驅動表)放在join的左邊
Map Join:在Map端完成Join
#第一種:SQL方式,在SQL語句中新增MapJoin表級
SELECT /*+ MAPJOIN(smallTable) */ smallTable.key, bigTable.value
FROM smallTable JOIN bigTable ON smallTable.key = bigTable.key;
#第二種,開啟自動的MapJoin
set hive.auto.convert.join = true;
6.Map-Site聚合
#設定Map端的聚合combiner
set hive.map.aggr=true;
7.Hive-JVM重用
適用場景:
1.小檔案個數過多
2.task個數過多
set mapred.job.reuse.jvm.num.tasks=n;
#n為task插槽個數
缺點:設定開啟之後,task插槽會一直佔用資源,不論是否有task執行,直到所有的task即整個job全部執行完成時,才會釋放所有的task插槽資源!