Hive官方文檔
Hive官方文檔
內容列表 Cloudera制作的Hive介紹視頻 安裝與配置 系統需求 安裝Hive發行版 從Hive源碼編譯 運行Hive 配置管理概覽 運行時配置 Hive, Map-Reduce 與本地模式 錯誤日誌 DDL 操作 元數據存儲 DML 操作 SQL 操作 查詢示例 SELECTS 和 FILTERS GROUP BY JOIN MULTITABLE INSERT STREAMING Simple Example Use Cases MovieLens User Ratings Apache Weblog Data 免責聲明: Hive目前僅在Unix(linux)和Mac系統下使用Java 1.6測試運行,可以在這些或類似的平臺上正常運行。並不支持在Cygwin上工作(註:windows還是別想了)。 絕大部分的測試工作是基於Hadoop 0.20完成的 - 所以,我們建議不要使用其他版本,以避免編譯或運行的異常。 Cloudera制作的Hive介紹視頻 Hive 介紹視頻 Hive 演示視頻 安裝與配置 系統需求 Java 1.6 Hadoop 0.20.x.(註:目前0.9.0支持hadoop 1.0.x) 用發行版安裝Hive 使用下載工具從Apache下載鏡像下載最近的Hive發行包(查看 Hive發行包) 下一步你需要解壓縮Tar包,這將會創建一個名為hive-x.y.z的子目錄: $ tar -xzvf hive-x.y.z.tar.gz 設置HIVE_HOME環境變量指向到Hive的安裝目錄: $ cd hive-x.y.z$ export HIVE_HOME={{pwd}} 最後, 將$HIVE_HOME/bin添加到你的PATH環境變量中: $ export PATH=$HIVE_HOME/bin:$PATH 使用源碼創建Hive Hive SVN 源: http://svn.apache.org/repos/asf/hive/trunk $ svn co http://svn.apache.org/repos/asf/hive/trunk hive
$ cd hive
$ ant clean package
$ cd build/dist
$ ls
README.txt
bin/ (所有shell腳本)
lib/ (所需的jar文件)
conf/ (配置文件)
examples/ (示例輸入與查詢文件) 在接下來, 我們會交替的使用build/dist和<install-dir>. 運行Hive Hive 使用Hadoop,這意味著: 你必須在PATH裏面設置了hadoop路徑 (註:原文是 you must have hadoop in your path,我認為這個path應該是大寫的) 或者 export HADOOP_HOME=<hadoop-install-dir> 作為附加的, 你必須在創建Hive庫表前,在HDFS上創建/tmp和/user/hive/warehouse,並且將它們的權限設置為chmod g+w. 完成這個操作的命令如下: $ $HADOOP_HOME/bin/hadoop fs -mkdir /tmp
$ $HADOOP_HOME/bin/hadoop fs -mkdir /user/hive/warehouse
$ $HADOOP_HOME/bin/hadoop fs -chmod g+w /tmp
$ $HADOOP_HOME/bin/hadoop fs -chmod g+w /user/hive/warehouse 我同樣發現設置 HIVE_HOME 是很重要的,但並非必須 $ export HIVE_HOME=<hive-install-dir> 在Shell中使用Hive命令行(cli)模式: $ $HIVE_HOME/bin/hive 配置文件管理概述 Hive 默認的配置文件保存在 <install-dir>/conf/hive-default.xml 你可以修改其中的配置,並重命名這個文件為 <install-dir>/conf/hive-site.xml(註:我建議你還是保留原始配置文件) Hive配置文件的位置可以通過設置HIVE_CONF_DIR環境變量來改變. Log4j的配置保存在 <install-dir>/conf/hive-log4j.properties Hive的配置存在於Hadoop之上,這意味著Hadoop的配置默認會被繼承到Hive中. Hive 配置可以被如下方式控制: 編輯 hive-site.xml 並定義任何需要的變量 (包括hadoop的變量) 從 cli 模式使用使用set命令 (看下面) 使用如下方式: $ bin/hive -hiveconf x1=y1 -hiveconf x2=y2 這個例子分別設置了變量x1為y1,x2為y2 設置使用 HIVE_OPTS 環境變量 "-hiveconf x1=y1 -hiveconf x2=y2" 與上面的功能相同 運行時配置 Hive 查詢是執行map-reduce查詢,並且,這些查詢是可以被hadoop的配置所控制的. 命令行命令 ‘SET‘ 可以被用來設置任何hadoop(或者hive)的配置變量,例如: hive> SET mapred.job.tracker=myhost.mycompany.com:50030;
hive> SET -v; 後者(註 SET -v)用來查看當前全部的設置. 而不使用 -v 選項,則是用來查看當前與Hadoop不同的配置. Hive, Map-Reduce 與本地模式 Hive編譯器會為絕大多數查詢生成map-reduce的jobs。這些Jobs使用下面這個變量來表明被提交到Map-Reduce集群中: mapred.job.tracker 由於這通常是在一個多節點的map-reduce集群中被指出,Hadoop同樣有個就近的方式來在用戶的工作機上運行map-reduce jobs。這就在小數據集的查詢上顯得非常有用 - 在這種情況下,本地模式運行通常會比將任務提交到整個大集群中查詢更快。數據從HDFS上獲取是透明的。同樣的,由於本地模式僅運行一個reducer,這樣,在大數據查詢上是非常慢的。 從 0.7 版本開始, Hive全面支持本地運行模式,要使用這個模式,請按照下列進行設置: hive> SET mapred.job.tracker=local; 作為附加的,mapred.local.dir應該指定一個合法的本機路徑(註:安裝hive的那臺服務器) (例如: /tmp/<username>/mapred/local). (否則,用戶將獲取一個定位本地空間的異常拋出). 從0.7版本開始, Hive同樣支持自動/非自動地使用本地模式來完成map-reduce jobs,相關的選項是: hive> SET hive.exec.mode.local.auto=false; 請註意這個功能默認是關閉的,如果打開 - Hive將分析每一個查詢的map-reduce job ,並且如果以下閥值被確認為OK,就嘗試運行在本地: 全部job的輸入大小低於: hive.exec.mode.local.auto.inputbytes.max (128MB 默認) 全部的map任務數低於: hive.exec.mode.local.auto.tasks.max (4 個默認) 全部reduce任務數等於 1 或者 0. 對於查詢大於小數據集,或者需要查詢在多個map-reduce jobs中完成,但是子查詢很小的(註:小於上述條件),jobs仍可能使用本地模式來運行。 註意,可能不同的hadoop服務器節點和hive客戶端的運行時環境(由於不同的jvm版本或者不同的軟件庫)。運行本地模式可能會導致一個不可被捕獲的錯誤。同樣需要註意的是,本地運行模式是在一個獨立的子jvm(hive 客戶端的子進程)中完成的。 如果用戶希望,子jvm所能使用的最大內存數,可以通過訪問hive.mapred.local.mem來進行控制。默認設置是0,所以Hive允許Hadoop來決定子jvm的默認內存限制 錯誤日誌 Hive 使用 log4j 來記錄日誌. 默認來說,日誌不會被返回到CLI模式的控制臺上(註:也就是CRT中)。默認的日誌記錄等級是WARN,並被保存到以下文件夾中: /tmp/<user.name>/hive.log 如果用戶願意 - 日誌可以通過修改下面的參數來返回到控制臺上: bin/hive -hiveconf hive.root.logger=INFO,console 另外,用戶可以改變記錄等級: bin/hive -hiveconf hive.root.logger=INFO,DRFA 註意,配置項 hive.root.logger 在hive初始化以後,即不能通過使用‘set‘命令來改變了 Hive同樣會為每個hive會話保存查詢日誌,在/tmp/<user.name>/ (註:本機路徑下),但是可以通過修改 hive-site.xml 中的 hive.querylog.location屬性來變更。 Hive在一個hadoop集群上運行過程中的日誌是由Hadoop的配置所決定的。通常Hadoop會為每個map和reduce任務創建日誌文件,並保存在運行任務的集群服務器上。日誌文件可以通過Hadoop Jobtracker提供的Web UI上的Task Detail頁面來跟蹤觀察。 運行本地模式時(mapred.job.tracker=local),Hadoop/Hive 將會將執行日誌放在本機上,從0.6版本開始 - Hive使用hive-exec-log4j.properties (如果不存在,則是使用hive-log4j.properties文件)來決定默認的日誌的保存方式。默認的配置文件將為每個查詢執行在本地模式下的日誌放到/tmp/<user.name>。這樣做的目的是為了將配置單獨管理,並可以將日誌集中存放到一個用戶需要的位置(例如一個NFS文件服務器)上。執行日誌對於運行時錯誤的debug並無幫助。 錯誤日誌對於定位問題非常有用,[email protected]
hive> ALTER TABLE invites ADD COLUMNS (new_col2 INT COMMENT ‘a comment‘);
hive> ALTER TABLE events RENAME TO 3koobecaf; 刪除表: hive> DROP TABLE pokes; 元數據存儲 元數據默認使用Derby數據庫保存在本地文件系統中,並保存在./metastore_db下。通過修改conf/hive-default.xml中的javax.jdo.option.ConnectionURL變量修改。 當前,在默認配置下,元數據每次只能同時被一個用戶所使用。 元數據可以存儲在任何一個使用JPOX支持的數據庫中,這些關系型數據庫的連接和類型可以通過兩個變量進行控制。javax.jdo.option.ConnectionURL 和 javax.jdo.option.ConnectionDriverName。 你需要查看數據庫的JDO(或JPOX)手冊來獲取更多信息。 數據庫的Schema定義在JDO元數據註釋文件package.jdo中,位置在src/contrib/hive/metastore/src/model。 計劃在未來,元數據存儲引擎可以成為一個獨立的服務。 如果你想將元數據作為一個網絡的服務來在多個節點中訪問,請嘗試HiveDerbyServerMode. DML 操作 將文件中的數據加載到Hive中: hive> LOAD DATA LOCAL INPATH ‘./examples/files/kv1.txt‘ OVERWRITE INTO TABLE pokes; 加載到pokes表的文件包含兩個用ctrl-a符號分割的數據列,‘LOCAL‘ 意味著文件是從本地文件系統加載,如果沒有 ‘LOCAL‘ 則意味著從HDFS中加載。 關鍵詞 ‘OVERWRITE‘ 意味著當前表中已經存在的數據將會被刪除掉。 如果沒有給出 ‘OVERWRITE‘,則意味著數據文件將追加到當前的數據集中。 註意: 通過load命令加載的數據不會被校驗正確性。 如果文件在HDFS上,他將會被移動到hive所管理的文件系統的命名空間中 Hive目錄的根路徑是在hive-default.xml文件中的變量 hive.metastore.warehouse.dir 決定的。 我們建議用戶在使用Hive建表之前就創建好這個變量指定的目錄。 hive> LOAD DATA LOCAL INPATH ‘./examples/files/kv2.txt‘ OVERWRITE INTO TABLE invites PARTITION (ds=‘2008-08-15‘);
hive> LOAD DATA LOCAL INPATH ‘./examples/files/kv3.txt‘ OVERWRITE INTO TABLE invites PARTITION (ds=‘2008-08-08‘); 上面這兩個 LOAD 語句,將加載不同的數據到invites表的分區(partition)中。invites表必須事先使用 ds 創建好partition。 hive> LOAD DATA INPATH ‘/user/myname/kv2.txt‘ OVERWRITE INTO TABLE invites PARTITION (ds=‘2008-08-15‘); 上述命令是將HDFS上的文件加載到表中。 註意從HDFS中加載數據,將會把數據移動到目錄下。這幾乎是瞬間完成的。(註:因為只是在HDFS元數據中修改了文件路徑的指向。) SQL 查詢 查詢示例 下面會演示一些查詢範例,在build/dist/examples/queries中可以找到。 更多的,可以在hive源碼中的 ql/src/test/queries/positive中可以找到。 SELECTS 和 FILTERS hive> SELECT a.foo FROM invites a WHERE a.ds=‘2008-08-15‘; 從invite表的字段 ‘foo‘ 中選擇所有分區ds=2008-08-15的結果。這些結果並不存儲在任何地方,只在控制臺中顯示。 註意:下面的示例中,INSERT (到hive表,本地目錄或者HDFS目錄) 是可選命令。 hive> INSERT OVERWRITE DIRECTORY ‘/tmp/hdfs_out‘ SELECT a.* FROM invites a WHERE a.ds=‘2008-08-15‘; 從invites表中選擇分區 ds=2008-08-15 的所有行,並放入HDFS目錄中。結果數據在在/tmp/hdfs_out目錄中的文件(多個文件,文件數量取決於mapper的數量)。 存在分區的表在使用 WHERE 條件過濾的時候必須至少指定一個分區來查詢。 hive> INSERT OVERWRITE LOCAL DIRECTORY ‘/tmp/local_out‘ SELECT a.* FROM pokes a; 選擇pokes表中所有的數據並放到一個本地(註:當前服務器)的文件路徑中。 hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a;
hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a WHERE a.key < 100;
hive> INSERT OVERWRITE LOCAL DIRECTORY ‘/tmp/reg_3‘ SELECT a.* FROM events a;
hive> INSERT OVERWRITE DIRECTORY ‘/tmp/reg_4‘ select a.invites, a.pokes FROM profiles a;
hive> INSERT OVERWRITE DIRECTORY ‘/tmp/reg_5‘ SELECT COUNT(*) FROM invites a WHERE a.ds=‘2008-08-15‘;
hive> INSERT OVERWRITE DIRECTORY ‘/tmp/reg_5‘ SELECT a.foo, a.bar FROM invites a;
hive> INSERT OVERWRITE LOCAL DIRECTORY ‘/tmp/sum‘ SELECT SUM(a.pc) FROM pc1 a; 字段計算和,最大值,最小值同樣可以使用,註意不包含在 HIVE-287 中的Hive版本,你需要使用COUNT(1) 來代替 COUNT(*) GROUP BY hive> FROM invites a INSERT OVERWRITE TABLE events SELECT a.bar, count(*) WHERE a.foo > 0 GROUP BY a.bar;
hive> INSERT OVERWRITE TABLE events SELECT a.bar, count(*) FROM invites a WHERE a.foo > 0 GROUP BY a.bar; 註意不包含在 HIVE-287 中的Hive版本,你需要使用COUNT(1) 來代替 COUNT(*) JOIN hive> FROM pokes t1 JOIN invites t2 ON (t1.bar = t2.bar) INSERT OVERWRITE TABLE events SELECT t1.bar, t1.foo, t2.foo; MULTITABLE INSERT(多重插入) FROM src
INSERT OVERWRITE TABLE dest1 SELECT src.* WHERE src.key < 100
INSERT OVERWRITE TABLE dest2 SELECT src.key, src.value WHERE src.key >= 100 and src.key < 200
INSERT OVERWRITE TABLE dest3 PARTITION(ds=‘2008-04-08‘, hr=‘12‘) SELECT src.key WHERE src.key >= 200 and src.key < 300
INSERT OVERWRITE LOCAL DIRECTORY ‘/tmp/dest4.out‘ SELECT src.value WHERE src.key >= 300;
STREAMING
hive> FROM invites a INSERT OVERWRITE TABLE events SELECT TRANSFORM(a.foo, a.bar) AS (oof, rab) USING ‘/bin/cat‘ WHERE a.ds > ‘2008-08-09‘; 在map中使用腳本/bin/cat對數據的流式訪問(就像使用hadoop的streaming) 同樣的 - 流式訪問也可以使用在reduce階段。(請查看 Hive Tutorial 範例) 簡單的使用範例 用戶對電影的投票統計 首先,創建一個使用tab分割的文本文件的表 CREATE TABLE u_data (
userid INT,
movieid INT,
rating INT,
unixtime STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ‘\t‘
STORED AS TEXTFILE; 然後,下載這個數據文件 wget http://www.grouplens.org/system/files/ml-data.tar+0.gz tar xvzf ml-data.tar+0.gz 將這個文件加載到剛剛創建的表中: LOAD DATA LOCAL INPATH ‘ml-data/u.data‘ OVERWRITE INTO TABLE u_data; 計算表 u_data 中的總行數: SELECT COUNT(*) FROM u_data; 註意不包含在 HIVE-287 中的Hive版本,你需要使用COUNT(1) 來代替 COUNT(*) 現在,我們可以在表 u_data 中做一些復雜的數據分析 創建 weekday_mapper.py: import sys
import datetime
for line in sys.stdin:
line = line.strip()
userid, movieid, rating, unixtime = line.split(‘\t‘)
weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()
print ‘\t‘.join([userid, movieid, rating, str(weekday)]) 使用mapper腳本: CREATE TABLE u_data_new (
userid INT,
movieid INT,
rating INT,
weekday INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ‘\t‘;
add FILE weekday_mapper.py;
INSERT OVERWRITE TABLE u_data_new
SELECT
TRANSFORM (userid, movieid, rating, unixtime)
USING ‘python weekday_mapper.py‘
AS (userid, movieid, rating, weekday)
FROM u_data;
SELECT weekday, COUNT(*)
FROM u_data_new
GROUP BY weekday; 註意 0.5.0 及更早的的Hive版本,你需要使用COUNT(1) 來代替 COUNT(*) Apache Web日誌數據 Apache日誌格式是可以自定義的,作為大多數網管來說都是使用默認設置。 我們可以給默認的Apache日誌創建一個如下的表 更多的關於正則序列化/反序列化(註: 原文!RegexSerDe) 可以在這裏看到。 http://issues.apache.org/jira/browse/HIVE-662 add jar ../build/contrib/hive_contrib.jar;
CREATE TABLE apachelog (
host STRING,
identity STRING,
user STRING,
time STRING,
request STRING,
status STRING,
size STRING,
referer STRING,
agent STRING)
ROW FORMAT SERDE ‘org.apache.hadoop.hive.contrib.serde2.RegexSerDe‘
WITH SERDEPROPERTIES (
"input.regex" = "([^]*) ([^]*) ([^]*) (-|\\[^\\]*\\]) ([^ \"]*|\"[^\"]*\") (-|[0-9]*) (-|[0-9]*)(?: ([^ \"]*|\".*\") ([^ \"]*|\".*\"))?",
"output.format.string" = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s"
)
STORED AS TEXTFILE;
Hive官方文檔