基于Hadoop的大數據的計算/擴展能力
支持SQL like查詢語言
統一的元數據管理
簡單編程
</td>
</tr>
</tbody>
</table>
Hive的安裝
1.1在hadoop生態圈中屬于數據倉庫的角色。他能夠管理hadoop中的數據,同時可以查詢hadoop中的數據。
本質上講,hive是一個SQL解析引擎。Hive可以把SQL查詢轉換為MapReduce中的job來運行。
hive有一套映射工具,可以把SQL轉換為MapReduce中的job,可以把SQL中的表、字段轉換為HDFS中的文件(夾)以及文件中的列。
這套映射工具稱之為metastore,一般存放在derby、mysql中。
1.2 hive在hdfs中的默認位置是/user/hive/warehouse,是由配置文件hive-conf.xml中屬性hive.metastore.warehouse.dir決定的。
2.hive的安裝
(1)解壓縮、重命名、設置環境變量
(2)在目錄$HIVE_HOME/conf/下,執行命令mv hive-default.xml.template hive-site.xml重命名
在目錄$HIVE_HOME/conf/下,執行命令mv hive-env.sh.template hive-env.sh重命名
(3)修改hadoop的配置文件hadoop-env.sh,修改內容如下:
export HADOOP_CLASSPATH=.:$CLASSPATH:$HADOOP_CLASSPATH:$HADOOP_HOME/bin
(4)在目錄$HIVE_HOME/bin下面,修改文件hive-config.sh,增加以下內容:
export JAVA_HOME=/usr/local/jdk
export HIVE_HOME=/usr/local/hive
export HADOOP_HOME=/usr/local/hadoop
3.安裝mysql
(1)刪除linux上已經安裝的mysql相關庫信息。rpm -e xxxxxxx --nodeps
執行命令rpm -qa |grep mysql 檢查是否刪除干凈
(2)執行命令 rpm -i mysql-server-******** 安裝mysql服務端
(3)啟動mysql 服務端,執行命令 mysqld_safe &
(4)執行命令 rpm -i mysql-client-******** 安裝mysql客戶端
(5)執行命令mysql_secure_installation設置root用戶密碼
4. 使用mysql作為hive的metastore
(1)把mysql的jdbc驅動放置到hive的lib目錄下
(2)修改hive-site.xml文件,修改內容如下:
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop0:3306/hive?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>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>admin</value>
</property>

?用戶接口,包括 CLI,JDBC/ODBC,WebUI
?元數據存儲,通常是存儲在關系數據庫如 mysql, derby 中
?解釋器、編譯器、優化器、執行器
?Hadoop:用 HDFS 進行存儲,利用 MapReduce 進行計算
</td>
</tr>
</tbody>
</table>
用戶接口主要有三個:CLI,JDBC/ODBC和 WebUI
.CLI,即Shell命令行
.JDBC/ODBC是 Hive 的Java,與使用傳統數據庫JDBC的方式類似
.WebGUI是通過瀏覽器訪問 Hive
Hive 將元數據存儲在數據庫中(metastore),目前只支持 mysql、derby。Hive 中的元數據包括表的名字,表的列和分區及其屬性,表的屬性(是否為外部表等),表的數據所在目錄等
解釋器、編譯器、優化器完成 HQL 查詢語句從詞法分析、語法分析、編譯、優化以及查詢計劃(plan)的生成。生成的查詢計劃存儲在 HDFS 中,并在隨后有 MapReduce 調用執行
Hive 的數據存儲在 HDFS 中,大部分的查詢由 MapReduce 完成(包含 * 的查詢,比如 select * from table 不會生成 MapRedcue 任務)
</td>
</tr>
</tbody>
</table>
Hive的metastore
metastore是hive元數據的集中存放地。metastore默認使用內嵌的derby數據庫作為存儲引擎
Derby引擎的缺點:一次只能打開一個會話
使用Mysql作為外置存儲引擎,多用戶同時訪問
</td>
</tr>
</tbody>
</table>
Hive的shell
1、hive 命令行模式,直接輸入#/hive/bin/hive的執行程序,或者輸入 #hive --service cli
2、 hive web界面的 (端口號9999) 啟動方式
#hive --service hwi&
用于通過瀏覽器來訪問hive
http://hadoop0:9999/hwi/
3、 hive 遠程服務 (端口號10000) 啟動方式
#hive --service hiveserver&
</td>
</tr>
</tbody>
</table>
Hive與傳統數據庫
查詢語言
</td>
|
HiveQL
</td>
|
SQL
</td>
</tr>
|
數據存儲位置
</td>
|
HDFS
</td>
|
Raw Device or 本地FS
</td>
</tr>
|
數據格式
</td>
|
用戶定義
</td>
|
系統決定
</td>
</tr>
|
數據更新
</td>
|
不支持
</td>
|
支持
</td>
</tr>
|
索引
</td>
|
新版本有,但弱
</td>
|
有
</td>
</tr>
|
執行
</td>
|
MapReduce
</td>
|
Executor
</td>
</tr>
|
執行延遲
</td>
|
高
</td>
|
低
</td>
</tr>
|
可擴展性
</td>
|
高
</td>
|
低
</td>
</tr>
|
數據規模
</td>
|
大
</td>
|
小
</td>
</tr>
</tbody>
</table>
Hive的數據類型
基本數據類型
tinyint / smalint / int /bigint
float / double
boolean
string
復雜數據類型
Array/Map/Struct
沒有date /datetime |
</tr>
</tbody>
</table>
Hive的數據存儲
Hive的數據存儲基于Hadoop HDFS
Hive沒有專門的數據存儲格式
存儲結構主要包括:數據庫、文件、表、視圖
Hive默認可以直接加載文本文件(TextFile),還支持sequence file
創建表時,指定Hive數據的列分隔符與行分隔符,Hive即可解析數據
</td>
</tr>
</tbody>
</table>
Hive的數據模型-內部表
與數據庫中的 Table 在概念上是類似
每一個 Table 在 Hive 中都有一個相應的目錄存儲數據。例如,一個表 test,它在 HDFS 中的路徑為:/ warehouse/test。 warehouse是在 hive-site.xml 中由 ${hive.metastore.warehouse.dir}
指定的數據倉庫的目錄
所有的 Table 數據(不包括 External Table)都保存在這個目錄中。
刪除表時,元數據與數據都會被刪除
</td>
</tr>
</tbody>
</table>
Hive的數據模型-分區表
Partition 對應于數據庫的 Partition 列的密集索引
在 Hive 中,表中的一個 Partition 對應于表下的一個目錄,所有的 Partition 的數據都存儲在對應的目錄中
例如:test表中包含 date 和 city 兩個 Partition,
?則對應于date=20130201, city = bj 的HDFS 子目錄?:
/warehouse/test/date=20130201/city=bj
?對應于date=20130202, city=sh 的HDFS 子目錄為;?
/warehouse/test/date=20130202/city=sh
CREATE TABLE tmp_table #表名
(
title string, #字段名稱 字段類型
minimum_bid double,
quantity bigint,
have_invoice bigint
)COMMENT'注釋:XXX' #表注釋
PARTITIONED BY(ptSTRING) #分區表字段(如果你文件非常之大的話,采用分區表可以快過濾出按分區字段劃分的數據)
ROW FORMAT DELIMITED
FIELDSTERMINATED BY '\001' # 字段是用什么分割開的
STOREDAS SEQUENCEFILE; #用哪種方式存儲數據,SEQUENCEFILE是hadoop自帶的文件壓縮格式
一些相關命令
SHOW TABLES; #查看所有的表
SHOW TABLES '*TMP*'; #支持模糊查詢
SHOWPARTITIONS TMP_TABLE; #查看表有哪些分區
DESCRIBE TMP_TABLE; #查看表結構
</td>
</tr>
</tbody>
</table>
分區表的shell
創建數據文件partition_table.dat
創建表
create table partition_table(rectime
string,msisdnstring) partitioned by(daytime strin
g,citystring) row format delimited fields
terminated by '\t' stored as TEXTFILE;
加載數據到分區
load data local inpath'/home/partition_table.dat' i
nto table partition_tablepartition (daytime='20
13-02-01',city='bj');
查看數據
select * from partition_table
select count(*) from partition_table
刪除表 drop table partition_table
</td>
</tr>
</tbody>
</table>
Hive的數據模型—桶表
桶表是對數據進行哈希取值,然后放到不同文件中存儲。
創建表
create table bucket_table(id string) clustered by(id) into 4 buckets;
加載數據
set hive.enforce.bucketing = true;
insert into table bucket_table select name from stu;
insert overwrite table bucket_table select name from stu;
數據加載到桶表時,會對字段取hash值,然后與桶的數量取模。把數據放到對應的文件中。
抽樣查詢
select * from bucket_table tablesample(bucket 1 out of 4 on id);
</td>
</tr>
</tbody>
</table>
Hive的數據模型-外部表
指向已經在 HDFS 中存在的數據,可以創建 Partition
它和 內部表 在元數據的組織上是相同的,而實際數據的存儲則有較大的差異
內部表 的創建過程和數據加載過程(這兩個過程可以在同一個語句中完成),在加載數據的過程中,實際數據會被移動到數據
倉庫目錄中;之后對數據對訪問將會直接在數據倉庫目錄中完成。刪除表時,表中的數據和元數據將會被同時刪除
外部表只有一個過程,加載數據和創建表同時完成,并不會移動到數據倉庫目錄中,只是與外部數據建立一個鏈接。當刪除一個外部表時,僅刪除鏈接
CREATEEXTERNAL TABLE page_view
( viewTimeINT,
useridBIGINT,
page_urlSTRING,
referrer_urlSTRING,
ipSTRING COMMENT 'IP Address of the User',
country STRING COMMENT 'country of origination‘
)
COMMENT 'This is the staging page view table'
ROW FORMAT DELIMITED FIELDSTERMINATED BY '44' LINES TERMINATED BY '12'
STORED ASTEXTFILE
LOCATION 'hdfs://centos:9000/user/data/staging/page_view';</pre>
</td>
</tr>
</tbody>
</table>
外部表的shell
創建數據文件external_table.dat
創建表
hive>create external table external_table1 (key string) ROW FORM AT DELIMITED FIELDS
TERMINATED BY '\t' location '/home/external';
在HDFS創建目錄/home/external
#hadoop fs -put /home/external_table.dat /home/
external
加載數據
LOAD DATA INPATH '/home/external_table1.dat'
IN
TO TABLE external_table1;
查看數據
select * from external_table
select count(*) from external_table
刪除表
drop table external_table
</td>
</tr>
</tbody>
</table>
導入數據
?當數據被加載至表中時,不會對數據進行任何轉換。Load 操作只是將數據復制/移動至 Hive 表對應的位置。
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE]
INTO TABLE tablename
[PARTITION (partcol1=val1, partcol2=val2 ...)]
?把一個Hive表導入到另一個已建Hive表
INSERT OVERWRITE TABLE tablename[PARTITION (partcol1=val1, partcol2=val2 ...)] select_statementFROM from_statement
?CTAS
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
(col_namedata_type, ...) …
AS SELECT …
例:create table new_external_testas select * from external_table1
</span></td>
</tr>
</tbody>
</table>
查詢
?基于Partition的查詢
一般 SELECT查詢是全表掃描。但如果是分區表,查詢就可以利用分區剪枝(input pruning)的特性,類似“分區索引“”,只掃描一個表中它關心的那一部分。Hive當前的實現是,只有分區斷言(Partitioned by)出現在離FROM子句最近的那個WHERE子句中,才會啟用分區剪枝。例如,如果page_views表(按天分區)使用date列分區,以下語句只會讀取分區為‘2008-03-01’的數據。
SELECT page_views.* FROM page_views WHERE page_views.date>= '2013-03-01' AND page_views.date<= '2013-03-01'
?LIMIT Clause
Limit可以限制查詢的記錄數。查詢的結果是隨機選擇的。下面的查詢語句從t1表中隨機查詢5條記錄:
SELECT * FROM t1 LIMIT 5
?Top N查詢
下面的查詢語句查詢銷售記錄最大的5個銷售代表。
SETmapred.reduce.tasks= 1
SELECT * FROM sales SORT BY amount DESC LIMIT 5
</td>
</tr>
</tbody>
</table>
表連接
導入ac信息表
hive> create table acinfo(name string,acipstring) row format delimited fields terminated by '\t' stored as TEXTFILE;
hive> load data local inpath'/home/acinfo/ac.dat' into table acinfo;
內連接
select b.name,a.* from dim_aca join acinfo b on (a.ac=b.acip) limit 10;
左外連接
select b.name,a.* from dim_ac a left outer join acinfo b on a.ac=b.acip limit 10;
</td>
</tr>
</tbody>
</table>
Java客戶端
Hive遠程服務啟動#hive --service hiveserver>/dev/null 2>/dev/null &
JAVA客戶端相關代碼
Class.forName("org.apache.hadoop.hive.jdbc.HiveDriver");
Connection con = DriverManager.getConnection("jdbc:hive://192.168.1.102:10000/wlan_dw", "", "");
Statement stmt = con.createStatement();
String querySQL="SELECT * FROM wlan_dw.dim_m order by flux desc limit 10";
ResultSet res = stmt.executeQuery(querySQL);
while (res.next()) {
System.out.println(res.getString(1) +"\t" +res.getLong(2)+"\t" +res.getLong(3)+"\t" +res.getLong(4)+"\t" +res.getLong(5));
}
</td>
</tr>
|
|
</tr>
</tbody>
</table>
UDF
| | | | | | | | | | | | | | | |