1. 程式人生 > >構建資料倉庫Hive

構建資料倉庫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插槽資源!