Hive是一個基於Hadoop的開源數據倉庫工具,用於存儲和處理海量結構化數據。它是Facebook 2008年8月開源的一個數據倉庫框架,提供了相似於SQL語法的HQL語句做爲數據訪問接口,Hive有以下優缺點:html
l 優勢:java
1.Hive 使用類SQL 查詢語法, 最大限度的實現了和SQL標準的兼容,大大下降了傳統數據分析人員學習的曲線;node
2.使用JDBC 接口/ODBC接口,開發人員更易開發應用;mysql
3.以MR 做爲計算引擎、HDFS 做爲存儲系統,爲超大數據集設計的計算/ 擴展能力;算法
4.統一的元數據管理(Derby、MySql等),並可與Pig 、Presto 等共享;sql
l 缺點:數據庫
1.Hive 的HQL 表達的能力有限,有些複雜運算用HQL 不易表達;apache
2.因爲Hive自動生成MapReduce 做業, HQL 調優困難;編程
3.粒度較粗,可控性差數組
由上圖可知,Hadoop的MapReduce是Hive架構的根基。Hive架構包括以下組件:CLI(Command Line Interface)、JDBC/ODBC、Thrift Server、WEB GUI、Metastore和Driver(Complier、Optimizer和Executor),這些組件分爲兩大類:服務端組件和客戶端組件。
服務端組件:
lDriver組件:該組件包括Complier、Optimizer和Executor,它的做用是將HiveQL(類SQL)語句進行解析、編譯優化,生成執行計劃,而後調用底層的MapReduce計算框架;
lMetastore組件:元數據服務組件,這個組件存儲Hive的元數據,Hive的元數據存儲在關係數據庫裏,Hive支持的關係數據庫有Derby和Mysql。元數據對於Hive十分重要,所以Hive支持把Metastore服務獨立出來,安裝到遠程的服務器集羣裏,從而解耦Hive服務和Metastore服務,保證Hive運行的健壯性;
lThrift服務:Thrift是Facebook開發的一個軟件框架,它用來進行可擴展且跨語言的服務的開發,Hive集成了該服務,能讓不一樣的編程語言調用Hive的接口。
客戶端組件:
lCLI:Command Line Interface,命令行接口。
lThrift客戶端:上面的架構圖裏沒有寫上Thrift客戶端,可是Hive架構的許多客戶端接口是創建在Thrift客戶端之上,包括JDBC和ODBC接口。
lWEBGUI:Hive客戶端提供了一種經過網頁的方式訪問Hive所提供的服務。這個接口對應Hive的HWI組件(Hive Web Interface),使用前要啓動HWI服務。
Hive的執行流程
三種部署模式
1.單用戶模式 此模式鏈接到一個In-Memory 的數據庫Derby,通常用於Unit Test。
2.多用戶模式 經過網絡鏈接到一個數據庫中,是最常用到的模式。
3. 遠程服務器模式 用於非Java客戶端訪問元數據庫,在服務器端啓動MetaStoreServer,客戶端利用Thrift協議經過MetaStoreServer訪問元數據庫。
Hive沒有專門的數據存儲格式,用戶能夠自由的組織Hive中的表,只須要在建立表的時候告訴Hive數據中的列分隔符和行分隔符,Hive就能夠解析數據。Hive中全部的數據都存儲在HDFS中,存儲結構主要包括數據庫、文件、表和視圖。Hive中包含如下數據模型:Table內部表,External Table外部表,Partition分區,Bucket桶。Hive默承認以直接加載文本文件,還支持sequence file 、RCFile。
1.Hive數據庫
相似傳統數據庫的DataBase,在第三方數據庫裏實際是一張表
簡單示例命令行: create database test_database;
2.內部表
Hive的內部表與數據庫中的Table在概念上是相似。每個Table在Hive中都有一個相應的目錄存儲數據。例如一個表tbInner,它在HDFS中的路徑爲/user/hive/warehouse/tbInner,其中/user/hive/warehouse是在hive-site.xml中由${hive.metastore.warehouse.dir} 指定的數據倉庫的目錄,全部的Table數據(不包括External Table)都保存在這個目錄中。內部表刪除時,元數據與數據都會被刪除。
內部表簡單示例:
建立數據文件:test_inner_table.txt
建立表:create table test_inner_table (key string);
加載數據:LOAD DATA LOCAL INPATH 'filepath' INTO TABLE test_inner_table;
查看數據:select * from test_inner_table;
刪除表:drop table test_inner_table;
3. 外部表
外部表指向已經在HDFS中存在的數據,並能夠建立Partition。它和內部表在元數據的組織上是相同的,而實際數據的存儲則有較大的差別。內部表的建立過程和數據加載過程這兩個過程能夠分別獨立完成,也能夠在同一個語句中完成,在加載數據的過程當中,實際數據會被移動到數據倉庫目錄中;以後對數據對訪問將會直接在數據倉庫目錄中完成。刪除表時,表中的數據和元數據將會被同時刪除。而外部表只有一個過程,加載數據和建立表同時完成(CREATE EXTERNAL TABLE ……LOCATION),實際數據是存儲在LOCATION後面指定的 HDFS 路徑中,並不會移動到數據倉庫目錄中。當刪除一個External Table時,僅刪除該連接。
外部表簡單示例:
建立數據文件:test_external_table.txt
建立表:create external table test_external_table (key string);
加載數據:LOAD DATA INPATH ‘filepath’ INTO TABLE test_inner_table;
查看數據:select * from test_external_table;
刪除表:drop table test_external_table;
4.分區
Partition對應於數據庫中的Partition列的密集索引,可是Hive中Partition的組織方式和數據庫中的很不相同。在Hive中,表中的一個Partition對應於表下的一個目錄,全部的Partition的數據都存儲在對應的目錄中。例如pvs表中包含ds和city兩個Partition,則對應於ds = 20090801, ctry = US 的HDFS子目錄爲/user/hive/warehouse/pvs/ds=20090801/ctry=US;對應於 ds = 20090801, ctry = CA 的HDFS子目錄爲/user/hive/warehouse/pvs/ds=20090801/ctry=CA。
分區表簡單示例:
建立數據文件:test_partition_table.txt
建立表:create table test_partition_table (key string) partitioned by (dt string);
加載數據:LOAD DATA INPATH ‘filepath’ INTO TABLE test_partition_table partition (dt=‘2006’);
查看數據:select * from test_partition_table;
刪除表:drop table test_partition_table;
5.桶
Buckets是將表的列經過Hash算法進一步分解成不一樣的文件存儲。它對指定列計算Hash,根據Hash值切分數據,目的是爲了並行,每個Bucket對應一個文件。例如將user列分散至32個bucket,首先對user列的值計算Hash,對應Hash值爲0的HDFS目錄爲/user/hive/warehouse/pvs/ds=20090801/ctry=US/part-00000;Hash值爲20的HDFS目錄爲/user/hive/warehouse/pvs/ds=20090801/ctry=US/part-00020。若是想應用不少的Map任務這樣是不錯的選擇。
桶的簡單示例:
建立數據文件:test_bucket_table.txt
建立表:create table test_bucket_table (key string) clustered by (key) into 20 buckets;
加載數據:LOAD DATA INPATH ‘filepath’ INTO TABLE test_bucket_table;
查看數據:select * from test_bucket_table; set hive.enforce.bucketing = true;
6.Hive的視圖
視圖與傳統數據庫的視圖相似。視圖是隻讀的,它基於的基本表,若是改變,數據增長不會影響視圖的呈現;若是刪除,會出現問題。若是不指定視圖的列,會根據select語句後的生成。
示例:create view test_view as select * from test;
Hive支持兩種數據類型,一類叫原子數據類型,一類叫複雜數據類型。
l 原子數據類型包括數值型、布爾型和字符串類型,具體以下表所示:
基本數據類型 |
||
類型 |
描述 |
示例 |
TINYINT |
1個字節(8位)有符號整數 |
1 |
SMALLINT |
2字節(16位)有符號整數 |
1 |
INT |
4字節(32位)有符號整數 |
1 |
BIGINT |
8字節(64位)有符號整數 |
1 |
FLOAT |
4字節(32位)單精度浮點數 |
1.0 |
DOUBLE |
8字節(64位)雙精度浮點數 |
1.0 |
BOOLEAN |
true/false |
true |
STRING |
字符串 |
‘xia’,」xia」 |
由上表咱們看到Hive不支持日期類型,在Hive裏日期都是用字符串來表示的,而經常使用的日期格式轉化操做則是經過自定義函數進行操做。
Hive是用Java開發的,Hive裏的基本數據類型和java的基本數據類型也是一一對應的,除了String類型。有符號的整數類型:TINYINT、SMALLINT、INT和BIGINT分別等價於Java的Byte、Short、Int和Long原子類型,它們分別爲1字節、2字節、4字節和8字節有符號整數。Hive的浮點數據類型FLOAT和DOUBLE,對應於Java的基本類型Float和Double類型。而Hive的BOOLEAN類型至關於Java的基本數據類型Boolean。對於Hive的String類型至關於數據庫的Varchar類型,該類型是一個可變的字符串,不過它不能聲明其中最多能存儲多少個字符,理論上它能夠存儲2GB的字符數。
l 複雜數據類型包括數組(ARRAY)、映射(MAP)和結構體(STRUCT),具體以下所示:
因爲Hive採用了SQL的查詢語言HQL,所以很容易將Hive理解爲數據庫。其實從結構上來看,Hive和數據庫除了擁有相似的查詢語言,再無相似之處。數據庫能夠用在Online的應用中,可是Hive是爲數據倉庫而設計的,清楚這一點,有助於從應用角度理解Hive的特性。
Hive和數據庫的比較以下表:
Hive |
RDBMS |
|
查詢語言 |
HQL |
SQL |
數據存儲 |
HDFS |
Raw Device or Local FS |
數據格式 |
用戶定義 |
系統決定 |
數據更新 |
不支持 |
支持 |
索引 |
無 |
有 |
執行 |
MapReduce |
Executor |
執行延遲 |
高 |
低 |
處理數據規模 |
大 |
小 |
可擴展性 |
高 |
低 |
下載地址:http://dev.mysql.com/downloads/mysql/#downloads,使用系統爲CentOS選擇 Red Hat Enterprise Linux/Oracle系列:
操做系統爲64位,選擇對應安裝包進行下載:
下載在本地目錄以下圖:
把下載的mysql安裝包,使用SSH Secure File Transfer工具(參見《Spark編譯與部署(上)--基礎環境搭建》1.3.1介紹)上傳到/home/hadoop/upload 目錄下,以下圖所示:
(1)查找之前是否安裝有mysql
使用命令查看是否已經安裝過mysql:
$rpm -qa | grep -i mysql
能夠看到以下圖的所示:
說明以前安裝了:
MySQL-client-5.6.21-1.el6.x86_64
MySQL-server-5.6.21-1.el6.x86_64
MySQL-devel-5.6.21-1.el6.x86_64
若是沒有結果,能夠進行mysql數據庫安裝
(2)中止mysql服務、刪除以前安裝的mysql
中止mysql服務、刪除以前安裝的mysql刪除命令:rpm -e –nodeps 包名
$sudo rpm -ev MySQL-server-5.6.21-1.el6.x86_64
$sudo rpm -ev MySQL-devel-5.6.21-1.el6.x86_64
$sudo rpm -ev MySQL-client-5.6.21-1.el6.x86_64
若是存在CentOS自帶mysql-libs-5.1.71-1.el6.x86_64使用下面的命令卸載便可
$sudo rpm -ev --nodeps mysql-libs-5.1.71-1.el6.x86_64
(3)查找以前老版本mysql的目錄而且刪除老版本mysql的文件和庫
$sudo find / -name mysql
刪除對應的mysql目錄
$sudo rm -rf /usr/lib64/mysql
$sudo rm -rf /var/lib/mysql
(4)再次查找機器是否安裝mysql
$sudo rpm -qa | grep -i mysql
無結果,說明已經卸載完全、接下來直接安裝mysql便可
進入安裝文件的目錄,安裝mysql服務端
$cd /home/hadoop/upload
$sudo rpm -ivh MySQL-server-5.6.21-1.el6.x86_64.rpm
安裝mysql客戶端、mysql-devel
$sudo rpm -ivh MySQL-client-5.6.21-1.el6.x86_64.rpm
$sudo rpm -ivh MySQL-devel-5.6.21-1.el6.x86_64.rpm
在CentOS6.5下安裝mysql設置root密碼時,出現以下錯誤:
/usr/bin/mysqladmin: connect to server at 'localhost' failed
error: 'Access denied for user 'root'@'localhost' (using password: NO)'
能夠進入安全模式進行設置root密碼
(1)中止mysql服務
使用以下命令中止mysql服務:
$sudo service mysql stop
$sudo service mysql status
(2)跳過驗證啓動mysql
使用以下命令驗證啓動mysql,因爲&結尾是後臺運行進程,運行該命令能夠再打開命令窗口或者Ctr+C繼續進行下步操做,因爲mysql啓動時間會長點,須要等待幾分鐘再查看啓動狀態:
$sudo mysqld_safe --skip-grant-tables &
$sudo service mysql status
(3)跳過驗證啓動MySQL
驗證mysql服務已經在後臺運行後,執行以下語句,其中後面三條命令是在mysql語句:
mysql -u root
mysql>use mysql;
mysql>update user set password = password('root') where user = 'root';
mysql>flush privileges;
mysql>quit;
(4)跳過驗證啓動MySQL
重啓mysql服務並查看狀態
$sudo service mysql stop
$sudo service mysql start
$sudo service mysql status
進入mysql命令行,建立Hive用戶並賦予全部權限:
mysql -uroot -proot
mysql>set password=password('root');
mysql>create user 'hive' identified by 'hive';
mysql>grant all on *.* TO 'hive'@'%' with grant option;
mysql>flush privileges;
mysql>quit;
(注意:若是是root第一次登陸數據庫,須要從新設置一下密碼,所報異常信息以下:ERROR 1820 (HY000): You must SET PASSWORD before executing this statement)
使用hive用戶登陸,建立Hive數據庫:
mysql -uhive -phive
mysql>create database hive;
mysql>show databases;
能夠到Apache基金hive官網http://hive.apache.org/downloads.html,選擇鏡像下載地址:http://mirrors.cnnic.cn/apache/hive/下載一個穩定版本,這裏選擇下載apache-hive-0.13.1-bin.tar.gz文件,以下圖所示:
到mysql官網進入下載頁面:http://dev.mysql.com/downloads/connector/j/,默認狀況下是Windows安裝包,這裏須要選擇Platform Independent版本下載zip格式的文件
把下載的hive安裝包和mysql驅動包,使用SSH Secure File Transfer工具(參見《Spark編譯與部署(上)--基礎環境搭建》1.3.1介紹)上傳到/home/hadoop/upload 目錄下,以下圖所示:
到上傳目錄下,用以下命令解壓縮hive安裝文件:
cd /home/hadoop/upload
tar -zxf hive-0.13.1-bin.tar.gz
更名並遷移到/app/hadoop目錄下:
sudo mv apache-hive-0.13.1-bin /app/hadoop/hive-0.13.1
ll /app/hadoop
把下載的hive安裝包和mysql驅動包,使用
cd /home/hadoop/upload
cp mysql-connector-java-5.1.34-bin.jar /app/hadoop/hive-0.13.1/lib
使用以下命令打開/etc/profile文件:
sudo vi /etc/profile
設置以下參數:
export HIVE_HOME=/app/hadoop/hive-0.13.1
export PATH=$PATH:$HIVE_HOME/bin
export CLASSPATH=$CLASSPATH:$HIVE_HOME/bin
使配置文件生效:
source /etc/profile
進入hive-0.13.1/conf目錄,複製hive-env.sh.templaete爲hive-env.sh:
cd /app/hadoop/hive-0.13.1/conf
cp hive-env.sh.template hive-env.sh
ls
使用以下命令邊界配置文件
sudo vi hive-env.sh
分別設置HADOOP_HOME和HIVE_CONF_DIR兩個值:
# Set HADOOP_HOME to point to a specific hadoop install directory
export HADOOP_HOME=/app/hadoop/hadoop-2.2.0
# Hive Configuration Directory can be controlled by:
export HIVE_CONF_DIR=/app/hadoop/hive-0.13.1/conf
複製hive-default.xml.templaete爲hive-site.xml
cp hive-default.xml.template hive-site.xml
sudo vi hive-site.xml
(1)加入配置項
默認metastore在本地,添加配置改成非本地
<property>
<name>hive.metastore.local</name>
<value>false</value>
</property>
(2)修改配置項
hive默認爲derby數據庫,derby數據只運行單個用戶進行鏈接,這裏須要調整爲mysql數據庫
<property>
<name>hive.metastore.uris</name>
<value>thrift://hadoop1:9083</value>
<description>Thrift URI for the remote metastore. ...</description>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop1: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>hive</value>
<description>password to use against metastore database</description>
</property>
把hive.metastore.schema.verification配置項值修改成false
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
<desc....>
</property>
實際使用時,通常經過後臺啓動metastore和hiveserver實現服務,命令以下:
hive --service metastore &
hive --service hiveserver &
啓動用經過jps命令能夠看到兩個進行運行在後臺
登陸hive,在hive建立表並查看該表,命令以下:
hive
hive>create table test(a string, b int);
hive>show tables;
hive>desc test;
登陸mysql,在TBLS表中查看新增test表:
mysql -uhive -phive
mysql>use hive;
mysql>select TBL_ID, CREATE_TIME, DB_ID, OWNER, TBL_NAME,TBL_TYPE from TBLS;
在CentOS6.5下安裝mysql設置root密碼時,出現以下錯誤:
/usr/bin/mysqladmin: connect to server at 'localhost' failed
error: 'Access denied for user 'root'@'localhost' (using password: NO)'
(1)中止mysql服務
使用以下命令中止mysql服務:
sudo service mysql stop
sudo service mysql status
(2)跳過驗證啓動mysql
使用以下命令驗證啓動mysql,因爲&結尾是後臺運行進程,運行該命令能夠再打開命令窗口或者Ctr+C繼續進行下步操做:
mysqld_safe --skip-grant-tables &
sudo service mysql status
(3)跳過驗證啓動MySQL
驗證mysql服務已經在後臺運行後,執行以下語句,其中後面三條命令是在mysql語句:
mysql -u root
mysql>use mysql;
mysql>update user set password = password('root') where user = 'root';
mysql>flush privileges;
(4)跳過驗證啓動MySQL
重啓mysql服務並查看狀態
sudo service mysql stop
sudo service mysql start
sudo service mysql status
啓動Hive時,出現CommandNeedRetryException異常,具體信息以下:
Exception in thread "main" java.lang.NoClassDefFoundError:org/apache/hadoop/hive/ql/CommandNeedRetryException
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at org.apache.hadoop.util.RunJar.main(RunJar.java:149)
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.hive.ql.CommandNeedRetryException
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
因爲之前使用hadoop時,修改hadoop-env.sh的HADOOP_CLASSPATH配置項,由之前的:
export HADOOP_CLASSPATH=/usr/local/hadoop-1.1.2/myclass
修改成:
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/usr/local/hadoop-1.1.2/myclass
啓動Hive後,使用HSQL出現異常,須要啓動metastore和hiveserver
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.metastore.HiveMetaStoreClient
在使用hive以前須要啓動metastore和hiveserver服務,經過以下命令啓用:
hive --service metastore &
hive --service hiveserver &
啓動用經過jps命令能夠看到兩個進行運行在後臺
參考資料:
(1)《Hive體系結構》 http://blog.csdn.net/zhoudaxia/article/details/8855937
(2)《大數據時代的技術hive:hive的數據類型和數據模型》http://www.cnblogs.com/sharpxiajun/archive/2013/06/03/3114560.html