日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

apache hive 使用概述

發布時間:2025/1/21 编程问答 69 豆豆
生活随笔 收集整理的這篇文章主要介紹了 apache hive 使用概述 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

1???????? 產品概述

1.1? 產品功能

????????Apache Hive數據倉庫軟件提供對存儲在分布式中的大型數據集的查詢和管理,它本身是建立在Apache Hadoop之上,主要提供以下功能:

1. 它提供了一系列的工具,可用來對數據進行提取/轉化/加載(ETL);是一種可以存儲、查詢和分析存儲在HDFS(或者HBase)中的大規模數據的機制;查詢是通過MapReduce來完成的(并不是所有的查詢都需要MapReduce來完成,比如select * from XXX就不需要;在Hive0.11對類似select a,b from XXX的查詢通過配置也可以不通過MapReduce來完成);

2. Hive是一種建立在Hadoop文件系統上的數據倉庫架構,并對存儲在HDFS中的數據進行分析和管理;

3. Hive定義了一種類似SQL的查詢語言,被稱為HQL,對于熟悉SQL的用戶可以直接利用Hive來查詢數據。同時,這個語言也允許熟悉MapReduce開發者們開發自定義的mappersreducers來處理內建的mappersreducers無法完成的復雜的分析工作。Hive可以允許用戶編寫自己定義的函數UDF,在查詢中使用。Hive中有3UDFUser Defined FunctionsUDF)、User Defined Aggregation FunctionsUDAF)、User Defined Table Generating FunctionsUDTF)。

????現在,Hive已經是一個成功的Apache項目,很多組織把它用作一個通用的、可伸縮的數據處理平臺。

????????Hive和傳統的關系型數據庫有很大的區別,Hive將外部的任務解析成一個MapReduce可執行計劃,而啟動MapReduce是一個高延遲的一件事,每次提交任務和執行任務都需要消耗很多時間,這也就決定Hive只能處理一些高延遲的應用(如果想處理低延遲的應用,可以考慮一下Hbase)。同時,由于設計的目標不一樣,Hive目前還不支持事務;不能對表數據進行修改。

1.2? Hive和傳統數據庫進行比較

????????Hive在很多方面和RMDB類似,比如說它支持SQL接口;但是由于其它底層設計的原因,對HDFSMapreduce有很強的依賴,這也就意味這Hive的體系結構和RMDB有很大的區別。這些區別又間接的影響到Hive所支持的一些特性。

????在傳統的RMDB中,表的模式是在數據加載的時候強行確定好的。如果在加載時發現數據不符合模式,則拒絕加載這些數據。而Hive在加載的過程中不對數據進行任何的驗證操作,其只是簡單的將數據復制或者移動到表對應的目錄下面。從這方面來說,傳統數據庫在數據加載的過程中比Hive要慢。但是因為傳統數據庫在數據加載過程中可以進行一些處理,比如對某一列建立索引等,這樣可以提升數據的查詢性能。而在這方面Hive不行。

比較項

SQL

HiveQL

ANSI SQL

支持

不完全支持

更新

UPDATE\INSERT\DELETE

insert OVERWRITE\INTO TABLE

事務

支持

不支持

模式

寫模式

讀模式

數據保存

塊設備、本地文件系統

HDFS

延時

多表插入

不支持

支持

子查詢

完全支持

只能用在From子句中

視圖

Updatable

Read-only

可擴展性

數據規模

……

……

……

????從上表可以看出,Hive和傳統的數據庫還是有很多的區別。

????????HiveSQL方言一般被稱為HiveQL,在下文我們簡稱HQL。在上面我們提到,HQL并不完全支持SQL92標準。這個也是有原因的。遵循SQL92Hive的設計開始就不是它的目標。

1.3?應用場景

????????Hive目前主要應用在海量數據處理、數據挖掘、數據分析等方面,hive是針批量對長時間數據分析設計的,不能做交互式的實時查詢。

2???????? 產品架構

????????Hive產品架構如下所示:

????????Hive架構圖中涉及服務、元數據、HdfsMapreduce等信息,下面分別進行說明:

2.1? 服務

????????hive有三種service,分別是clihiveserverhwi

1. cli是命令行工具,為默認服務,啟動方式$HIVE_HOME/bin/hive $HIVE_HOME/bin/hive --service cli

2. hiverserver通過thrift對外提供服務,默認端口10000,啟動方式為$HIVE_HOME/bin/hive--service hiveserver

3. hwiweb接口,可以通過瀏覽器訪問hive,默認端口9999,啟動方式為$HIVE_HOME/bin/hive--service hwi

????每個服務間互相獨立,有各自的配置文件(配置metasotre/namenode/jobtracker),如果metasotre的配置一樣則物理上對應同一hive庫。

????????Driver用于解釋、編譯、優化、執行HQL,每個serviceDriver相互獨立。

????????CLI為用戶提供命令行接口,每個CLI獨享配置,即在一個CLI里修改配置不影響別的CLI

多個JDBC可同時連到同一HiveServer上,所有會話共享一份配置。(:0.9.0hiveserver配置已經從global降為session,即每個session的配置相互獨立)

?????多個瀏覽器可同時連到同一HWI上,所有會話共享一份配置。

????????Hive可以在運行時用–service選項來明確指定使用的服務類型,可以用下面的--service help來查看幫助,如下:

[wyp@master ~]$ hive --service help

Usage ./hive <parameters> --service serviceName <service parameters>

Service List: beeline cli help hiveserver2 hiveserver hwi jar lineage metastore metatool orcfiledump rcfilecat

Parameters parsed:

? --auxpath : Auxillary jars

? --config : Hive configuration directory

? --service : Starts specific service/component. cli is default

Parameters used:

? HADOOP_HOME or HADOOP_PREFIX : Hadoop install directory

? HIVE_OPT : Hive options

For help on a particular service:

? ./hive --service serviceName --help

Debug help:? ./hive --debug –help

????上面的輸出項Service List,里面顯示出Hive支持的服務列表:beeline cli help hiveserver2 hiveserver hwi jar lineage metastore metatool orcfiledump rcfilecat,下面介紹最常用的一些服務。

1cli:這個就是Command Line Interface的簡寫,是Hive的命令行界面,用的比較多。這是默認的服務,直接可以在命令行里面使用。

2hiveserver:這個可以讓Hive以提供Trift服務的服務器形式來運行,允許許多不同語言編寫的客戶端進行通信。使用時需要啟動HiveServer服務以和客戶端聯系,可以通過設置HIVE_PORT環境變量來設置服務器所監聽的端口號,在默認的情況下,端口為10000。可以通過下面方式來啟動hiveserver

[wyp@master ~]$? bin/hive --service hiveserver -p 10002

Starting Hive Thrift Server

其中-p參數也是用來指定監聽端口的。

3hwi:其實就是hive web interface的縮寫,它是HiveWeb接口,是hive cli的一個web替換方案。

4jar:與Hadoop jar等價的Hive的接口,這是運行類路徑中同時包含HadoopHive類的Java應用程序的簡便方式。

5metastore:在默認情況下,metastoreHive服務運行在同一個進程中。使用這個服務,可以讓metastore作為一個單獨的進程運行,可以通過METASTORE_PORT來指定監聽的端口號,具體如下所示:

2.2??元數據

????????Hive的數據分為表數據和元數據,表數據是Hive中表格(table)具有的數據;而元數據是用來存儲表的名字,表的列和分區及其屬性(是否為外部表等),表的數據所在目錄等。

????元數據位置通過參數javax.jdo.option.ConnectionURL來指定,可在會話中自由修改。相關的參數包括:

javax.jdo.option.ConnectionDriverName??? ?????? #數據庫驅動

javax.jdo.option.ConnectionURL ?????? ?????? ?????? #數據庫ip端口庫名等

javax.jdo.option.ConnectionUserName?????? ?????? #用戶名

javax.jdo.option.ConnectionPassword ?????? ?????? #密碼

通過修改這些參數可以在多個MetaStore間熱切換,可用于HA

2.3??NameNodeJobTracker

????????NameNodefs.default.name指定,JobTrackermapred.job.tracker指定,這兩個參數都可以在會話中自由修改來指向不同的NameNodeJobTracker

????配合MetaStore可以有多種組合出現,例如在同一個MetaStore里讓table1的數據存在HDFS1,用JobTracker1計算,table2的數據存在HDFS2,用JobTracker2計算,或者讓兩個表都在JobTracker3上計算。

????????NameNodeJobTracker最好指向同一個集群,否則計算的時候需要跨集群復制數據。

????在MetaStore存儲的是表數據文件的絕對路徑,當心其與NameNode/ JobTracker不在同一個集群里導致跨集群復制。

????對hiveserverhwi配置的修改會作用到同一service上的所有會話。(:0.9.0hiveserver配置已經從global降為session,即每個session的配置相互獨立)

3 ? ? ? ??安裝部署

????????Hive最新版本是apache-hive-0.13.1-bin.tar.gz,下載地址為http://apache.fayea.com/apache-mirror/hive/hive-0.13.1/

????下載后,選個目錄,解壓,命令如下:

# tar -zxvf hive-0.10.0.tar.gz

????現在需要配置Hive,才能夠運行Hive。進入conf文件夾,將hive-default.xml.template文件的內容復制到hive-site.xml文件中,操作如下:

#cd conf/

#cp hive-default.xml.template hive-site.xml

????在hive-site.xml文件中進行如下配置:

<property>

<name>hive.metastore.warehouse.dir</name>

<value>/home/wyp/cloud/hive/warehouse</value>

<description>location of default database for the warehouse</description>

</property>

<property>

<name>javax.jdo.option.ConnectionURL</name>

<value>jdbc:mysql://localhost:3306/hive_hdp?characterEncoding=UTF-8&amp;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>root</value>

<description>username to use against metastore database</description>

</property>

<property>

<name>javax.jdo.option.ConnectionPassword</name>

<value>123456</value>

<description>password to use against metastore database</description>

</property>

????????Hive將元數據存儲在RDBMS中,比如MySQLDerby中。Hive默認是用Derby數據庫,這里修改為MySQL(所以要確保電腦上已經安裝好了MySQL數據庫)。需要將mysql驅動jarmysql-connector-java-5.1.22-bin.jar拷貝到$HIVE_HOME/lib/目錄下。然后編輯/etc/profile文件,將Hivehome目錄添加進去,操作如下:

#sudo vim /etc/profile

????在其中添加下面語句,修改Hivehome路徑為解壓的目錄:

export HIVE_HOME=/home/...hive-0.10.0

PATH=$PATH:$HIVE_HOME/bin

????最后讓上面的修改生效,請運行下面的命令:

#source /etc/profile

????現在可以試一下,hive是否安裝好(需要啟動Hadoop,否則不能運行成功!):

#hive

hive>

????如果出現了上述情況,說明hive安裝成功。

4? ? ? ? ?數據存儲模式

1. Hive的數據存儲

????????Hive是基于Hadoop分布式文件系統的,它的數據存儲在Hadoop分布式文件系統中。Hive本身是沒有專門的數據存儲格式,也沒有為數據建立索引,只需要在創建表的時候告訴Hive數據中的列分隔符和行分隔符,Hive就可以解析數據。所以往Hive表里面導入數據只是簡單的將數據移動到表所在的目錄中(如果數據是在HDFS上;但如果數據是在本地文件系統中,那么是將數據復制到表所在的目錄中)。

????????Hive中主要包含以下幾種數據模型:Table(表),External Table(外部表),Partition(分區),Bucket(桶)。

a. 表:Hive中的表和關系型數據庫中的表在概念上很類似,每個表在HDFS中都有相應的目錄用來存儲表的數據,這個目錄可以通過${HIVE_HOME}/conf/hive-site.xml配置文件中的hive.metastore.warehouse.dir屬性來配置,這個屬性默認的值是/user/hive/warehouse(這個目錄在HDFS上),我們可以根據實際的情況來修改這個配置。如果我有一個表wyp,那么在HDFS中會創建/user/hive/warehouse/wyp目錄(這里假定hive.metastore.warehouse.dir配置為/user/hive/warehouse);wyp表所有的數據都存放在這個目錄中。這個例外是外部表。

b.外部表:Hive中的外部表和表很類似,但是其數據不是放在自己表所屬的目錄中,而是存放到別處,這樣的好處是如果你要刪除這個外部表,該外部表所指向的數據是不會被刪除的,它只會刪除外部表對應的元數據;而如果你要刪除表,該表對應的所有數據包括元數據都會被刪除。

c.分區:在Hive中,表的每一個分區對應表下的相應目錄,所有分區的數據都是存儲在對應的目錄中。比如wyp表有dtcity兩個分區,則對應dt=20131218,city=BJ對應表的目錄為/user/hive/warehouse/dt=20131218/city=BJ,所有屬于這個分區的數據都存放在這個目錄中。

d.桶:對指定的列計算其hash,根據hash值切分數據,目的是為了并行,每一個桶對應一個文件(注意和分區的區別)。比如將wypid列分散至16個桶中,首先對id列的值計算hash,對應hash值為016的數據存儲的HDFS目錄為:/user/hive/warehouse/wyp/part-00000;而hash值為2的數據存儲的HDFS 目錄為:/user/hive/warehouse/wyp/part-00002

Hive數據抽象結構如下所示:


2.Hive的元數據

????????Hive中的元數據包括表的名字,表的列和分區及其屬性,表的屬性(是否為外部表等),表的數據所在目錄等。由于Hive的元數據需要不斷的更新、修改,而HDFS系統中的文件是多讀少改的,這顯然不能將Hive的元數據存儲在HDFS中。目前Hive將元數據存儲在數據庫中,如MysqlDerby中。我們可以通過以下的配置來修改Hive元數據的存儲方式。

<property>

<name>javax.jdo.option.ConnectionURL</name>

<value>jdbc:mysql://localhost:3306/hive_hdp?characterEncoding=UTF-8

&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>root</value>

<description>username to use against metastore database</description>

</property>

<property>

<name>javax.jdo.option.ConnectionPassword</name>

<value>123456</value>

<description>password to use against metastore database</description>

</property>

????還需要將連接對應數據庫的依賴包復制到${HIVE_HOME}/lib目錄中,這樣才能將元數據存儲在對應的數據庫中。

5 ? ? ? ?基本操作

5.1? Hive內置數據類型

????????Hive的內置數據類型可以分為兩大類:(1)基礎數據類型;(2)復雜數據類型。其中,基礎數據類型包括:TINYINTSMALLINTINTBIGINTBOOLEANFLOATDOUBLESTRINGBINARYTIMESTAMPDECIMALCHARVARCHARDATE。下面的表格列出這些基礎類型所占的字節以及從什么版本開始支持這些類型。

數據類型

所占字節

開始支持版本

TINYINT

1byte-128 ~ 127


SMALLINT

2byte-32,768 ~ 32,767?


INT

4byte,-2,147,483,648 ~ ? 2,147,483,647


BIGINT

8byte,-9,223,372,036,854,775,808 ? ~ 9,223,372,036,854,775,807


BOOLEAN



FLOAT

4byte雙精度


DOUBLE

8byte雙精度


STRING



BINARY


Hive0.8.0開始支持

TIMESTAMP


Hive0.8.0開始支持

DECIMAL


Hive0.11.0開始支持

CHAR


Hive0.13.0開始支持

VARCHAR


Hive0.12.0開始支持

DATE


Hive0.12.0開始支持

復雜類型包括ARRAY,MAP,STRUCT,UNION,這些復雜類型是由基礎類型組成的。

ARRAYARRAY類型是由一系列相同數據類型的元素組成,這些元素可以通過下標來訪問。比如有一個ARRAY類型的變量fruits,它是由['apple','orange','mango']組成,那么我們可以通過fruits[1]來訪問元素orange,因為ARRAY類型的下標是從0開始的;

MAPMAP包含key->value鍵值對,可以通過key來訪問元素。比如”userlist”是一個map類型,其中usernamekeypasswordvalue;那么我們可以通過userlist['username']來得到這個用戶對應的password

STRUCTSTRUCT可以包含不同數據類型的元素。這些元素可以通過點語法的方式來得到所需要的元素,比如user是一個STRUCT類型,那么可以通過user.address得到這個用戶的地址。

UNION: UNIONTYPE,他是從Hive 0.7.0開始支持的。

創建一個包含復制類型的表格可以如下:

CREATE TABLE employees (

??? name STRING,

??? salary FLOAT,

??? subordinates ARRAY<STRING>,

??? deductions MAP<STRING, FLOAT>,

??? address STRUCT<street:STRING, city:STRING, state:STRING, zip:INT>

) PARTITIONED BY (country STRING, state STRING);

5.2? Hive參數配置方法

????????Hive提供三種可以改變環境變量的方法,分別是:(1)修改${HIVE_HOME}/conf/hive-site.xml配置文件;(2)命令行參數;(3)在已經進入cli時進行參數聲明。下面分別介紹這幾種設定。

方法一:

????在Hive中,所有的默認配置都在${HIVE_HOME}/conf/hive-default.xml文件中,如果需要對默認的配置進行修改,可以創建一個hive-site.xml文件,放在${HIVE_HOME}/conf目錄下。里面可以對一些配置進行個性化設定。在hive-site.xml的格式如下:

<configuration>

??? <property>

??????? <name>hive.metastore.warehouse.dir</name>

??????? <value>/user/hive/warehouse</value>

??????? <description>location of

????????????? default database for the warehouse</description>

??? </property>

</configuration>

????所有的配置都是放在<configuration></configuration>標簽之間,一個configuration標簽里面可以存在多個<property></property>標簽。<name>標簽里面就是要設定屬性的名稱;<value>標簽里面是要設定的值;<description>標簽描述這個屬性的作用。絕大多少配置都是在xml文件里面配置的,因為在這里做的配置都全局用戶都生效,而且是永久的。用戶自定義配置會覆蓋默認配置。另外,Hive也會讀入Hadoop的配置,因為Hive是作為Hadoop的客戶端啟動的,Hive的配置會覆蓋Hadoop的配置。

方法二:

????在啟動Hive cli的時候進行配置,可以在命令行添加-hiveconf param=value來設定參數,例如:

# hive --hiveconf mapreduce.job.queuename=queue1

????這樣在Hive中所有MapReduce作業都提交到隊列queue1中。這一設定對本次啟動的會話有效,下次啟動需要重新配置。

方法三:

????在已經進入cli時進行參數聲明,可以在HQL中使用SET關鍵字設定參數,例如:

hive> set mapreduce.job.queuename=queue1;

????這樣也能達到方法二的效果。這種配置也是對本次啟動的會話有效,下次啟動需要重新配置。在HQL中使用SET關鍵字還可以查看配置的值,如下:

hive> set mapreduce.job.queuename;

mapreduce.job.queuename=queue1

????我們可以得到mapreduce.job.queuename=queue1。如果set后面什么都不添加,這樣可以查到Hive的所有屬性配置,如下:

hive> set;

datanucleus.autoCreateSchema=true

上述三種設定方式的優先級依次遞增。即參數聲明覆蓋命令行參數,命令行參數覆蓋配置文件設定。

5.3? Hive日志調試

????在很多程序中,可以通過輸出日志的形式來得到程序的運行情況,通過這些輸出日志來調試程序。

????在Hive中,使用的是Log4j來輸出日志,默認情況下,CLI是不能將日志信息輸出到控制臺的。在Hive0.13.0之前版本,默認的日志級別是WARN,從Hive0.13.0開始,默認的日志級別是INFO。默認的日志存放在/tmp/<user.name>文件夾的hive.log文件中,即/tmp/<user.name>/hive.log

????在默認的日志級別情況下,不能將DEBUG信息輸出,這樣一來出現的各種詳細的錯誤信息是不能輸出的。但是可以通過以下兩種方式修改log4j輸出的日志級別,從而利用這些調試日志進行錯誤定位,具體做法如下:

# hive --hiveconf hive.root.logger=DEBUG,console

????或者在${HIVE_HOME}/conf/hive-log4j.properties文件中找到hive.root.logger屬性,并將其修改為下面的設置

hive.root.logger=DEBUG,console

????上面兩種方法的設置各有優劣,方法一的設定只是對本次會話有效,下次如果還想修改日志輸出級別需要重新設定,但是不是每時每刻都需要修改日志的輸出級別,所以在有時需要修改輸出的日志級別,有時不需要的時候可以用這種方法;方法二將日志輸出級別設定到文件中去了,這個設定是對所有的用戶都生效,而且每次使用HQL的時候都會輸出一大堆的日志,這種情況適合那些無時無刻都需要HQL的運行日志的用戶。

5.4? hiveQL插入語法

1. Insert基本語法格式為:

INSERT OVERWRITE TABLE tablename [PARTITON(partcol1=val1,partclo2=val2)]select_statement FROM from_statement

示例:insert overwrite table test_insert select * from test_table;

2. 對多個表進行插入操作:

FROM fromstatte

INSERT OVERWRITE TABLE tablename1 [PARTITON(partcol1=val1,partclo2=val2)]select_statement1

INSERT OVERWRITE TABLE tablename2 [PARTITON(partcol1=val1,partclo2=val2)]select_statement2

示例:

from test_table

insert overwrite table test_insert1

select key

insert overwrite table test_insert2

select value;

insert的時候,from子句即可以放在select子句后面,也可以放在 insert子句前面。

hive不支持用insert語句一條一條的進行插入操作,也不支持update操作。數據是以load的方式加載到建立好的表中。數據一旦導入就不可以修改。

3.通過查詢將數據保存到filesystem

INSERT OVERWRITE [LOCAL] DIRECTORY directory SELECT.... FROM .....

導入數據到本地目錄:

insert overwrite local directory '/home/zhangxin/hive' select * from test_insert1;

產生的文件會覆蓋指定目錄中的其他文件,即將目錄中已經存在的文件進行刪除。

導出數據到HDFS中:

insert overwrite directory '/user/zhangxin/export_test' select value from test_table;

同一個查詢結果可以同時插入到多個表或者多個目錄中:

from test_insert1

insert overwrite local directory '/home/zhangxin/hive' select *

insert overwrite directory '/user/zhangxin/export_test' select value;

Hive insert into語句的標準語法如下:

用法一:

INSERT OVERWRITE TABLE tablename1 [PARTITION \

(partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] \

select_statement1 FROM from_statement;

用法二:

INSERT INTO TABLE tablename1 [PARTITION \

(partcol1=val1, partcol2=val2 ...)] \

select_statement1 FROM from_statement;

舉例:

hive> insert into table cite

> select * from tt;

????這樣就會將tt表格里面的數據追加到cite表格里面。并且在cite數據存放目錄生成了一個新的數據文件,這個新文件是經過處理的,列之間的分割是cite表格的列分割符,而不是tt表格列的分隔符。

(1) 如果兩個表格的維度不一樣,將會插入錯誤:

hive> insert into table cite

> select * from cite_standby;

FAILED: SemanticException [Error 10044]: Line 1:18 Cannot insert into

target table because column number/types are different 'cite':

Table insclause-0 has 2 columns, but query has 1 columns.

????從上面錯誤提示看出,查詢的表格cite_standby只有一列,而目標表格(也就是需要插入數據的表格)有2列,由于列的數目不一樣,導致了上面的語句不能成功運行,我們需要保證查詢結果列的數目和需要插入數據表格的列數目一致,這樣才行。

(2) 在用extended關鍵字創建的表格上插入數據將會影響到其它的表格的數據,因為他們共享一份數據文件。

(3) 如果查詢出來的數據類型和插入表格對應的列數據類型不一致,將會進行轉換,但是不能保證轉換一定成功,比如如果查詢出來的數據類型為int,插入表格對應的列類型為string,可以通過轉換將int類型轉換為string類型;但是如果查詢出來的數據類型為string,插入表格對應的列類型為int,轉換過程可能出現錯誤,因為字母就不可以轉換為int,轉換失敗的數據將會為NULL

(4) 可以將一個表查詢出來的數據插入到原表中:

hive> insert into table cite

> select * from cite;

結果就是相當于復制了一份cite表格中的數據。

(5) insert overwrite的區別:

hive> insert overwrite table cite

> select * from tt;

上面的語句將會用tt表格查詢到的數據覆蓋cite表格已經存在的數據。

5.5? hiveQL刪除語法

hiveQL刪除語法如下所示:

hive> TRUNCATE TABLE t;

這樣將會刪掉表格t關聯的所有數據,但會保留表和metadata的完整性。

5.6? hiveQL執行文件

Hive可以運行保存在文件里面的一條或多條的語句,只要用-f參數,一般情況下,保存這些Hive查詢語句的文件通常用.q或者.hql后綴名,但是這不是必須的,你也可以保存你想要的后綴名。假設test文件里面有一下的Hive查詢語句:

select * from p limit 10;

select count(*) from p;

那么我們可以用下面的命令來查詢:

#bin/hive -f test

........這里省略了一些輸出...........

OK

196 242 3?? 881250949?? 20131102??? jx

186 302 3?? 891717742?? 20131102??? jx

22? 377 1?? 878887116?? 20131102??? jx

244 51? 2?? 880606923?? 20131102??? jx

Time taken: 4.386 seconds, Fetched: 4 row(s)

........這里省略了一些輸出...........

OK

4

Time taken: 16.284 seconds, Fetched: 1 row(s)

如果你配置好了Hive shell的路徑,你可以用SOURCE命令來運行那個查詢文件:

[wyp@wyp hive-0.11.0-bin]$ hive

hive> source /home/.../test;

........這里省略了一些輸出...........

........這里省略了一些輸出...........

OK

196 242 3?? 881250949?? 20131102??? jx

186 302 3?? 891717742?? 20131102??? jx

22? 377 1?? 878887116?? 20131102??? jx

244 51? 2?? 880606923?? 20131102??? jx

Time taken: 4.386 seconds, Fetched: 4 row(s)

........這里省略了一些輸出...........

OK

4

Time taken: 16.284 seconds, Fetched: 1 row(s)

6 ? ? ? ??數據導入導出

6.1? Hive數據導入的方式

Hive目前有四種導入數據的方式:

1)從本地文件系統中導入數據到Hive表;

2)從HDFS上導入數據到Hive表;

3)從別的表中查詢出相應的數據并導入到Hive表中;

4)在創建表的時候通過從別的表中查詢出相應的記錄并插入到所創建的表中。

6.1.1??????????? 本地導入

先在Hive中建表,如下:

hive> create table wyp

???? > (id? int , name string,

???? > age? int , tel string)

???? > ROW FORMAT DELIMITED

???? > FIELDS TERMINATED BY '\t'

???? > STORED AS TEXTFILE;

OK

Time taken:? 2.832?? seconds

這個表很簡單,只有四個字段。本地文件系統中有個/home/wyp/wyp.txt文件,內容如下:

[wyp @master?? ~]$ cat wyp.txt

1??? wyp?????? ?????? 25?? 13188888888888

2??? test 30?? 13888888888888

3??? zs??? 34?? 899314121

wyp.txt文件中的數據列之間是使用\t分割的,可以通過下面的語句將這個文件里面的數據導入到wyp表里面,操作如下:

hive> load data local inpath? 'wyp.txt'?? into table wyp;

Copying data from file:/home/wyp/wyp.txt

Copying file: file:/home/wyp/wyp.txt

Loading data to table? default .wyp

Table? default .wyp stats:

[num_partitions:? 0 , num_files:? 1 , num_rows:? 0 , total_size:? 67 ]

OK

Time taken:? 5.967?? seconds

這樣就將wyp.txt里面的內容導入到wyp表里面去了,可以到wyp表的數據目錄下查看,如下命令:

hive> dfs -ls /user/hive/warehouse/wyp ;

Found? 1?? items

-rw-r--r-- 3?? wyp supergroup? 67?? 2014 - 02 - 19?? 18 : 23?? /hive/warehouse/wyp/wyp.txt

數據的確導入到wyp表里面去了。

和關系型數據庫不一樣,Hive現在還不支持在insert語句里面直接給出一組記錄的文字形式,也就是說,Hive并不支持INSERT INTO .... VALUES形式的語句。

6.1.2??????????? HDFS導入

從本地文件系統中將數據導入到Hive表的過程中,其實是先將數據臨時復制到HDFS的一個目錄下(典型的情況是復制到上傳用戶的HDFS home目錄下,比如/home/wyp/),然后再將數據從那個臨時目錄下移動(注意,這里說的是移動,不是復制!)到對應的Hive表的數據目錄里面。既然如此,那么Hive肯定支持將數據直接從HDFS上的一個目錄移動到相應Hive表的數據目錄下,假設有下面這個文件/home/wyp/add.txt,具體的操作如下:

[wyp@master /home/q/hadoop-2.2.0]$ bin/hadoop fs -cat /home/wyp/add.txt

5?????? wyp1??? 23????? 131212121212

6?????? wyp2??? 24????? 134535353535

7?????? wyp3??? 25????? 132453535353

8?????? wyp4??? 26????? 154243434355

上面是需要插入數據的內容,這個文件是存放在HDFS/home/wyp目錄(和本地導入的不同,本地導入中提到的文件是存放在本地文件系統上)里面,可以通過下面的命令將這個文件里面的內容導入到Hive表中,具體操作如下:

hive> load data inpath '/home/wyp/add.txt' into table wyp;

Loading data to table default.wyp

Table default.wyp stats:

[num_partitions: 0, num_files: 2, num_rows: 0, total_size: 215]

OK

Time taken: 0.47 seconds

?

hive> select * from wyp;

OK

5?????? wyp1??? 23????? 131212121212

6?????? wyp2??? 24????? 134535353535

7?????? wyp3??? 25????? 132453535353

8?????? wyp4??? 26????? 154243434355

1?????? wyp???? 25????? 13188888888888

2?????? test??? 30????? 13888888888888

3??? ???zs????? 34????? 899314121

Time taken: 0.096 seconds, Fetched: 7 row(s)

從上面的執行結果可以看到,數據的確導入到wyp表中了!請注意load data inpath /home/wyp/add.txt into table wyp;里面是沒有local這個單詞的,這個是和本地導入方式的區別。

6.1.3??????????? 別的表查詢導入

假設Hive中有test表,其建表語句如下所示:

hive> create table test(

??? > id int, name string

??? > ,tel string)

??? > partitioned by

??? > (age int)

??? > ROW FORMAT DELIMITED

??? > FIELDS TERMINATED BY '\t'

??? > STORED AS TEXTFILE;

OK

Time taken: 0.261 seconds

大體和wyp表的建表語句類似,只不過test表里面用age作為了分區字段。下面語句將wyp表中的查詢結果插入到test表中:

hive> insert into table test

??? > partition (age='25')

??? > select id, name, tel

??? > from wyp;

#################################################################

?????????? 這里輸出了一堆Mapreduce任務信息,這里省略

#################################################################

Total MapReduce CPU Time Spent: 1 seconds 310 msec

OK

Time taken: 19.125 seconds

hive> select * from test;

OK

5?????? wyp1??? 131212121212??? 25

6?????? wyp2??? 134535353535??? 25

7?????? wyp3??? 132453535353??? 25

8?????? wyp4??? 154243434355??? 25

1 ??????wyp???? 13188888888888? 25

2?????? test??? 13888888888888? 25

3?????? zs????? 899314121?????? 25

Time taken: 0.126 seconds, Fetched: 7 row(s)

通過上面的輸出,我們可以看到從wyp表中查詢出來的東西已經成功插入到test表中去了!如果目標表(test)中不存在分區字段,可以去掉partition (age=25)語句。當然,也可以在select語句里面通過使用分區值來動態指明分區:

hive> set hive.exec.dynamic.partition.mode=nonstrict;

hive> insert into table test

??? > partition (age)

??? > select id, name,

??? > tel, age

??? > from wyp;

#################################################################

?????????? 這里輸出了一堆Mapreduce任務信息,這里省略

#################################################################

Total MapReduce CPU Time Spent: 1 seconds 510 msec

OK

Time taken: 17.712 seconds

hive> select * from test;

OK

5?????? wyp1??? 131212121212??? 23

6?????? wyp2??? 134535353535??? 24

7?????? wyp3??? 132453535353??? 25

1?????? wyp???? 13188888888888? 25

8?????? wyp4??? 154243434355??? 26

2?????? test??? 13888888888888? 30

3?????? zs????? 899314121?????? 34

Time taken: 0.399 seconds, Fetched: 7 row(s)

這種方法叫做動態分區插入,但是Hive中默認是關閉的,所以在使用前需要先把hive.exec.dynamic.partition.mode設置為nonstrict。當然,Hive也支持insert overwrite方式來插入數據,從字面可以看出,overwrite是覆蓋的意思,執行完這條語句的時候,相應數據目錄下的數據將會被覆蓋,而insert into則不會。例子如下:

hive> insert overwrite table test

??? > PARTITION (age)

??? > select id, name, tel, age

??? > from wyp;

Hive還支持多表插入,在Hive中,可以把insert語句倒過來,把from放在最前面,它的執行效果和放在后面是一樣的,如下:

hive> show create table test3;

OK

CREATE? TABLE test3(

? id int,

? name string)

Time taken: 0.277 seconds, Fetched: 18 row(s)

hive> from wyp

??? > insert into table test

??? > partition(age)

??? > select id, name, tel, age

??? > insert into table test3

??? > select id, name

??? > where age>25;

?

hive> select * from test3;

OK

8?????? wyp4

2?????? test

3?????? zs

Time taken: 4.308 seconds, Fetched: 3 row(s)

可以在同一個查詢中使用多個insert子句,這樣只需要掃描一遍源表就可以生成多個不相交的輸出。

6.1.4??????????? 創建表時導入

在實際情況中,表的輸出結果可能太多,不適于顯示在控制臺上,這時候,將Hive的查詢輸出結果直接存在一個新的表中是非常方便的,稱這種情況為CTAScreate table as select)如下:

hive> create table test4

??? > as

??? > select id, name, tel

??? > from wyp;

hive> select * from test4;

OK

5?????? wyp1??? 131212121212

6?????? wyp2??? 134535353535

7?????? wyp3??? 132453535353

8?????? wyp4??? 154243434355

1?????? wyp???? 13188888888888

2?????? test??? 13888888888888

3?????? zs????? 899314121

Time taken: 0.089 seconds, Fetched: 7 row(s)

數據就插入到test4表中去了,CTAS操作是原子的,因此如果select查詢由于某種原因而失敗,新表是不會創建的。

6.2? Hive數據導出的方式

Hive根據導出的地方不同可以將導出方式分為三種:(1)導出到本地文件系統;(2)導出到HDFS中;(3)導出到Hive的另一個表中,下面逐一介紹。

6.2.1??????????? 導出到本地文件系統

hive> insert overwrite local directory '/home/wyp/wyp'

??? > select * from wyp;

這條HQL的執行需要啟用Mapreduce完成,運行完這條語句之后,將會在本地文件系統的/home/wyp/wyp目錄下生成文件,這個文件是Reduce產生的結果(這里生成的文件名是000000_0),我們可以看看這個文件的內容:

[wyp@master ~/wyp]$ vim 000000_0

5^Awyp1^A23^A131212121212

6^Awyp2^A24^A134535353535

7^Awyp3^A25^A132453535353

8^Awyp4^A26^A154243434355

1^Awyp^A25^A13188888888888

2^Atest^A30^A13888888888888

3^Azs^A34^A899314121

可以看出,這是wyp表中的所有數據。數據中的列與列之間的分隔符是^A(ascii碼是\00001)

Hive 0.11.0版本之前,數據的導出是不能指定列之間的分隔符的,只能用默認的列分隔符,也就是上面的^A來分割,這樣導出來的數據很不直觀,看起來很不方便。

如果用的Hive版本是0.11.0和之后版本,可以在導出數據的時候來指定列之間的分隔符,操作如下:

hive> insert overwrite local directory '/home/yangping.wu/local'

??? > row format delimited

??? > fields terminated by '\t'

??? > select * from wyp;

?

?[wyp@master ~/local]$ vim 000000_0

5?????? wyp1??? 23????? 131212121212

6?????? wyp2??? 24????? 134535353535

7?????? wyp3??? 25????? 132453535353

8?????? wyp4??? 26????? 154243434355

1?????? wyp???? 25????? 13188888888888

2?????? test??? 30????? 13888888888888

3?????? zs????? 34????? 899314121

其實,還可以用hive-e-f參數來導出數據。其中-e表示后面直接接帶雙引號的sql語句;而-f是接一個文件,文件的內容為一個sql語句,如下:

[wyp@master ~/local]$? hive -e "select * from wyp" >> local/wyp.txt

[wyp@master ~/local]$cat wyp.txt

5?????? wyp1??? 23????? 131212121212

6?????? wyp2??? 24????? 134535353535

7?????? wyp3??? 25????? 132453535353

8?????? wyp4??? 26????? 154243434355

1?????? wyp???? 25????? 13188888888888

2?????? test??? 30????? 13888888888888

3?????? zs????? 34????? 899314121

得到的結果也是用\t分割的。也可以用-f參數實現:

[wyp@master ~/local]$ cat wyp.sql

select * from wyp

[wyp@master ~/local]$ hive -f wyp.sql >> local/wyp2.txt

上述語句得到的結果也是\t分割的。

6.2.2??????????? 導出到HDFS

和導入數據到本地文件系統一樣的簡單,可以用下面的語句實現:

hive> insert overwrite directory '/home/wyp/hdfs'

??? > select * from wyp;

將會在HDFS/home/wyp/hdfs目錄下保存導出來的數據。注意,和導出文件到本地文件系統的HQL少一個local,數據的存放路徑就不一樣了。

6.2.3??????????? 導出到Hive的另一個表中

hive> insert into table test

??? > partition (age='25')

??? > select id, name, tel

??? > from wyp;

#################################################################

?????????? 這里輸出了一堆Mapreduce任務信息,這里省略

#################################################################

Total MapReduce CPU Time Spent: 1 seconds 310 msec

OK

Time taken: 19.125 seconds

hive> select * from test;

OK

5?????? wyp1??? 131212121212??? 25

6?????? wyp2??? 134535353535??? 25

7?????? wyp3??? 132453535353??? 25

8?????? wyp4??? 154243434355??? 25

1?????? wyp???? 13188888888888? 25

2?????? test??? 13888888888888? 25

3?????? zs???? ?899314121?????? 25

Time taken: 0.126 seconds, Fetched: 7 row(s)

其實就是講hive中一個表的內容導入到另一個表中。

7 ? ? ? ??Hive索引

索引是標準的數據庫技術,hive 0.7版本之后支持索引。Hive提供有限的索引功能,這不像傳統的關系型數據庫那樣有(key)”的概念,用戶可以在某些列上創建索引來加速某些操作,給一個表創建的索引數據被保存在另外的表中。 Hive的索引功能現在還相對較晚,提供的選項還較少。但是,索引被設計為可使用內置的可插拔的java代碼來定制,用戶可以擴展這個功能來滿足自己的需求。用戶可以使用EXPLAIN語法來分析HiveQL語句是否可以使用索引來提升用戶查詢的性能。像RDBMS中的索引一樣,需要評估索引創建的是否合理,畢竟,索引需要更多的磁盤空間,并且創建維護索引也會有一定的代價。 用戶必須要權衡從索引得到的好處和代價。

下面介紹創建索引的方法:

1. 先創建表:

hive> create table a3( id int, name string)

> ROW FORMAT DELIMITED

> FIELDS TERMINATED BY '\t'

> STORED AS TEXTFILE;

2. 導入數據:

hive> load data local inpath 'apache-hive-0.13.1-bin/a21.txt'

??? > overwrite into table a3;??????????????????????????????

Copying data from file:/usr/local/apache-hive-0.13.1-bin/a21.txt

Copying file: file:/usr/local/apache-hive-0.13.1-bin/a21.txt

Loading data to table default.a3

rmr: DEPRECATED: Please use 'rm -r' instead.

Deleted hdfs://localhost:9000/user/hive/warehouse/a3

Table default.a3 stats: [numFiles=1, numRows=0, totalSize=169, rawDataSize=0]

OK

Time taken: 0.468 seconds

3. 創建索引之前測試

hive> select * from a3 where id=28;

Total jobs = 1

Launching Job 1 out of 1

Number of reduce tasks is set to 0 since there's no reduce operator

Starting Job = job_1414112118511_0001, Tracking URL = http://h77.hadoop.org:8088/proxy/application_1414112118511_0001/

Kill Command = /usr/local/hadoop-2.4.1/bin/hadoop job? -kill job_1414112118511_0001

Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 0

2014-10-24 09:12:11,220 Stage-1 map = 0%,? reduce = 0%

2014-10-24 09:12:16,404 Stage-1 map = 100%,? reduce = 0%, Cumulative CPU 1.13 sec

MapReduce Total cumulative CPU time: 1 seconds 130 msec

Ended Job = job_1414112118511_0001

MapReduce Jobs Launched:

Job 0: Map: 1?? Cumulative CPU: 1.13 sec?? HDFS Read: 375 HDFS Write: 8 SUCCESS

Total MapReduce CPU Time Spent: 1 seconds 130 msec

OK

28????? fdah

Time taken: 14.007 seconds, Fetched: 1 row(s)

一共用了14.007s

4. user創建索引

hive> create index a3_index on table a3(id)

??? > as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'

??? > with deferred rebuild

??? > in table a3_index_table;

OK

Time taken: 0.292 seconds

hive> alter index a3_index on a3 rebuild

??? > ;

Total jobs = 1

Launching Job 1 out of 1

Number of reduce tasks not specified. Estimated from input data size: 1

In order to change the average load for a reducer (in bytes):

? set hive.exec.reducers.bytes.per.reducer=<number>

In order to limit the maximum number of reducers:

? set hive.exec.reducers.max=<number>

In order to set a constant number of reducers:

? set mapreduce.job.reduces=<number>

Starting Job = job_1414112118511_0002, Tracking URL = http://h77.hadoop.org:8088/proxy/application_1414112118511_0002/

Kill Command = /usr/local/hadoop-2.4.1/bin/hadoop job? -kill job_1414112118511_0002

Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 1

2014-10-24 09:13:52,094 Stage-1 map = 0%,? reduce = 0%

2014-10-24 09:13:57,265 Stage-1 map = 100%,? reduce = 0%, Cumulative CPU 0.75 sec

2014-10-24 09:14:03,479 Stage-1 map = 100%,? reduce = 100%, Cumulative CPU 1.81 sec

MapReduce Total cumulative CPU time: 1 seconds 810 msec

Ended Job = job_1414112118511_0002

Loading data to table default.a3_index_table

rmr: DEPRECATED: Please use 'rm -r' instead.

Deleted hdfs://localhost:9000/user/hive/warehouse/a3_index_table

Table default.a3_index_table stats: [numFiles=1, numRows=20, totalSize=1197, rawDataSize=1177]

MapReduce Jobs Launched:

Job 0: Map: 1? Reduce: 1?? Cumulative CPU: 1.81 sec?? HDFS Read: 375 HDFS Write: 1277 SUCCESS

Total MapReduce CPU Time Spent: 1 seconds 810 msec

OK

Time taken: 17.976 seconds

hive> select * from a3_index_table;

OK

1?????? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [0]

2?????? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [6]

3?????? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [12]

6?????? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [40]

8?????? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [18]

12????? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [46]

18????? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [54]

21????? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [22]

28????? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [128]

78????? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [119]

83????? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [136]

98????? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [153]

123???? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [27]

129???? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [161]

234???? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [80,109]

812???? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [144]

891???? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [34]

1231??? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [70,88]

2134??? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [61]

7897??? hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt??? [98]

Time taken: 0.041 seconds, Fetched: 20 row(s)

這樣對user表創建了一個索引。

5、對創建索引后的user再進行測試

hive> select * from a3 where id=28;??????????????????????????????????

Total jobs = 1

Launching Job 1 out of 1

Number of reduce tasks is set to 0 since there's no reduce operator

Starting Job = job_1414112118511_0003, Tracking URL = http://h77.hadoop.org:8088/proxy/application_1414112118511_0003/

Kill Command = /usr/local/hadoop-2.4.1/bin/hadoop job? -kill job_1414112118511_0003

Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 0

2014-10-24 09:15:40,439 Stage-1 map = 0%,? reduce = 0%

2014-10-24 09:15:46,617 Stage-1 map = 100%,? reduce = 0%, Cumulative CPU 1.21 sec

MapReduce Total cumulative CPU time: 1 seconds 210 msec

Ended Job = job_1414112118511_0003

MapReduce Jobs Launched:

Job 0: Map: 1?? Cumulative CPU: 1.21 sec?? HDFS Read: 375 HDFS Write: 8 SUCCESS

Total MapReduce CPU Time Spent: 1 seconds 210 msec

OK

28????? fdah

Time taken: 11.924 seconds, Fetched: 1 row(s)

時間用了11.924s比沒有創建索引的效果好些,數據量大的時候效果會更明顯。

8 ? ? ? ??JDBC連接Hive Server

可以通過CLIClientWeb UIHive提供的用戶接口來和Hive通信,但這三種方式最常用的是CLIClientHive的客戶端,用來連接至Hive Server。在啟動Client模式的時候,需要指出Hive Server所在節點,并且在該節點啟動Hive ServerWUI是通過瀏覽器訪問 Hive。下面介紹通過HiveServer來操作Hive

Hive提供了JDBC驅動,使得我們可以用Java代碼來連接Hive并進行一些類關系型數據庫的SQL語句查詢等操作。同關系型數據庫一樣,也需要將Hive的服務打開;在Hive 0.11.0版本之前,只有HiveServer服務可用,得在程序操作Hive之前,在安裝Hive的服務器上打開HiveServer服務,如下所示:

#bin/hive --service hiveserver -p 10002

Starting Hive Thrift Server

上面代表你已經成功的在端口為10002(默認的端口是10000)啟動了hiveserver服務。這時候,你就可以通過Java代碼來連接hiveserver,代碼如下:

import java.sql.SQLException;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.Statement;

import java.sql.DriverManager;

?

public class Testmzl {

?

?????? private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";

?

?????? public static void main(String[] args) throws SQLException {

?????? ?????? try {

?????? ?????? ?????? Class.forName(driverName);

?????? ?????? } catch (ClassNotFoundException e) {

?????? ?????? ?????? e.printStackTrace();

?????? ?????? ?????? System.exit(1);

?????? ?????? }

?

?????? ?????? Connection con = DriverManager.getConnection(

?????? ?????? ?????? ?????? "jdbc:hive://192.168.1.77:10002/default", "", "");

?????? ?????? Statement stmt = con.createStatement();

?????? ?????? String tableName = "wyp";

?????? ?????? stmt.execute("drop table if exists " + tableName);

?????? ?????? stmt.execute("create table " + tableName + " (key int, value string)");

?????? ?????? System.out.println("Create table success!");

?????? ?????? // show tables

?????? ?????? String sql = "show tables";

?????? ?????? System.out.println("Running: " + sql);

?????? ?????? ResultSet res = stmt.executeQuery(sql);

?????? ?????? while (res.next()) {

?????? ?????? ?????? System.out.println(res.getString(1));

?????? ?????? }

?

?????? ?????? // describe table

?????? ?????? sql = "describe " + tableName;

?????? ?????? System.out.println("Running: " + sql);

?????? ?????? res = stmt.executeQuery(sql);

?????? ?????? while (res.next()) {

?????? ?????? ?????? System.out.println(res.getString(1) + "\t" + res.getString(2));

?????? ?????? }

?

?????? ?????? sql = "select * from " + tableName;

?????? ?????? res = stmt.executeQuery(sql);

?????? ?????? while (res.next()) {

?????? ?????? ?????? System.out.println(String.valueOf(res.getInt(1)) + "\t"

?????? ?????? ?????? ?????? ?????? + res.getString(2));

?????? ?????? }

?

?????? ?????? sql = "select count(1) from " + tableName;

?????? ?????? System.out.println("Running: " + sql);

?????? ?????? res = stmt.executeQuery(sql);

?????? ?????? while (res.next()) {

?????? ?????? ?????? System.out.println(res.getString(1));

?????? ?????? }

?????? }

}

編譯上面的代碼,之后就可以運行,結果如下:

Create table success!

Running: show tables 'wyphao'

wyphao

Running: describe wyphao

key???????????????????? int???????????????

value?????????????????? string????????????

Running: select count(1) from wyphao

0

上面用Java連接HiveServer,而HiveServer本身存在很多問題(比如:安全性、并發性等);針對這些問題,Hive0.11.0版本提供了一個全新的服務:HiveServer2,這個很好的解決HiveServer存在的安全性、并發性等問題。這個服務啟動程序在${HIVE_HOME}/bin/hiveserver2里面,可以通過下面的方式來啟動HiveServer2服務:

$HIVE_HOME/bin/hiveserver2

也可以通過下面的方式啟動HiveServer2

$HIVE_HOME/bin/hive --service hiveserver2

兩種方式效果一樣。但是之前的java程序需要修改兩個地方,如下所示:

private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";

改為

private static String driverName = "org.apache.hive.jdbc.HiveDriver";

?

Connection con = DriverManager.getConnection("jdbc:hive://localhost:10002/default", "", "");

改為

Connection con = DriverManager.getConnection("jdbc:hive2://localhost:10000/default", "", "");

其他的不變就可以了。

?

9 ? ? ? ??常見問題

9.1? disabled stack guard

在安裝運行hadoop時會出現下面的錯誤:

Hadoop 2.2.0 - warning: You have loaded library /home/hadoop/2.2.0/lib/native/libhadoop.so.1.0.0 which might have disabled stack guard.

具體出錯內容如下:

Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

Starting namenodes on [Java HotSpot(TM) 64-Bit Server VM warning: You have loaded library /home/hadoop/2.2.0/lib/native/libhadoop.so.1.0.0 which might have disabled stack guard. The VM will try to fix the stack guard now.

It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'.

localhost]

sed: -e expression #1, char 6: unknown option to `s'

HotSpot(TM): ssh: Could not resolve hostname HotSpot(TM): Name or service not known

64-Bit: ssh: Could not resolve hostname 64-Bit: Name or service not known

Java: ssh: Could not resolve hostname Java: Name or service not known

Server: ssh: Could not resolve hostname Server: Name or service not known

VM: ssh: Could not resolve hostname VM: Name or service not known

解決方法:

[root@h77 hadoop-2.4.1]#vim etc/hadoop/hadoop-env.sh

HADOOP_PREFIX變量的定義后面,HADOOP_OPTS變量的定義前面添加下列變量:

export HADOOP_COMMON_LIB_NATIVE_DIR=${HADOOP_PREFIX}/lib/native

export HADOOP_OPTS="-Djava.library.path=$HADOOP_PREFIX/lib"

9.2? javax.jdo.option.ConnectionURL配置的問題

Hive安裝過程中出現 The reference to entity "createDatabaseIfNotExist" must end with the ';' delimiter.問題,具體如下所示:

[Fatal Error] hive-site.xml:132:95: The reference to entity "createDatabaseIfNotExist" must end with the ';' delimiter.

14/10/23 11:15:04 FATAL conf.Configuration: error parsing conf file:/usr/local/apache-hive-0.13.1-bin/conf/hive-site.xml

org.xml.sax.SAXParseException; systemId: file:/usr/local/apache-hive-0.13.1-bin/conf/hive-site.xml; lineNumber: 132; columnNumber: 95; The reference to entity "createDatabaseIfNotExist" must end with the ';' delimiter.

顯示如下所示:

因為hive-site.xml中的javax.jdo.option.ConnectionURL配置項引起的,如下所示:

<property>

<name>javax.jdo.option.ConnectionURL</name>

<value>jdbc:mysql://localhost:3306/hive_hdp?characterEncoding=UTF-8&createDatabaseIfNotExist=true</value>

<description>JDBC connect string for a JDBC metastore</description>

</property>

正確配置如下:

<property>

<name>javax.jdo.option.ConnectionURL</name>

<value>jdbc:mysql://localhost:3306/hive_hdp?characterEncoding=UTF-8&amp;createDatabaseIfNotExist=true</value>

<description>JDBC connect string for a JDBC metastore</description>

</property>

這是因為xml文件中的編碼規則引起的。

xml文件中有以下幾類字符要進行轉義替換如下表所示:

符號

Xml表示

含義

&lt;

<?

小于號

&gt;

>?

大于號

&amp;

&

&apos;

'

單引號

&quot;

"

雙引號

所以javax.jdo.option.ConnectionURL項中的&符號需要用&amp;表示。

10???????? Hive優化

10.1? 簡單查詢不啟用Mapreduce job

如果你想查詢某個表的某一列,Hive默認是會啟用MapReduce Job來完成這個任務:

hive> SELECT id, money FROM m limit 10;

Total MapReduce jobs = 1

Launching Job 1 out of 1

Number of reduce tasks is set to 0 since there's no reduce operator

Cannot run job locally: Input Size (= 235105473) is larger than

hive.exec.mode.local.auto.inputbytes.max (= 134217728)

Starting Job = job_1384246387966_0229, Tracking URL =

?

http://l-datalogm1.data.cn1:9981/proxy/application_1384246387966_0229/

?

Kill Command = /home/q/hadoop-2.2.0/bin/hadoop job

-kill job_1384246387966_0229

hadoop job information for Stage-1: number of mappers: 1;

number of reducers: 0

2013-11-13 11:35:16,167 Stage-1 map = 0%,? reduce = 0%

2013-11-13 11:35:21,327 Stage-1 map = 100%,? reduce = 0%,

Cumulative CPU 1.26 sec

2013-11-13 11:35:22,377 Stage-1 map = 100%,? reduce = 0%,

Cumulative CPU 1.26 sec

MapReduce Total cumulative CPU time: 1 seconds 260 msec

Ended Job = job_1384246387966_0229

MapReduce Jobs Launched:

Job 0: Map: 1?? Cumulative CPU: 1.26 sec?

HDFS Read: 8388865 HDFS Write: 60 SUCCESS

Total MapReduce CPU Time Spent: 1 seconds 260 msec

OK

1?????? 122

1?????? 185

1?????? 231

1?????? 292

1?????? 316

1 ??????329

1?????? 355

1?????? 356

1?????? 362

1?????? 364

Time taken: 16.802 seconds, Fetched: 10 row(s)

啟用MapReduce Job會消耗系統開銷,對于這個問題,從Hive0.10.0版本開始,對于簡單的不需要聚合的類似SELECT <col> from <table> LIMIT n語句,不需要起MapReduce job,直接通過Fetch task獲取數據,可以通過下面幾種方法實現:

方法一:

hive> set hive.fetch.task.conversion=more;

hive> SELECT id, money FROM m limit 10;

OK

1?????? 122

1?????? 185

1?????? 231

1?????? 292

1?????? 316

1?????? 329

1?????? 355

1?????? 356

1?????? 362

1?????? 364

Time taken: 0.138 seconds, Fetched: 10 row(s)

上面set hive.fetch.task.conversion=more;開啟了Fetch任務,所以對于上述簡單的列查詢不再啟用MapReduce job

方法二:

bin/hive --hiveconf hive.fetch.task.conversion=more

方法三:

上面的兩種方法都可以開啟了Fetch任務,但是都是臨時起作用的;如果你想一直啟用這個功能,可以在${HIVE_HOME}/conf/hive-site.xml里面加入以下配置:

<property>

<name>hive.fetch.task.conversion</name>

<value>more</value>

<description>Some select queries can be converted to single FETCH task

minimizing latency.Currently the query should be single

sourced not having any subquery and should not have

any aggregations or distincts (which incurrs RS),

lateral views and joins.

1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only

2. more??? : SELECT, FILTER, LIMIT only (+TABLESAMPLE, virtual columns)

</description>

</property>

這樣就可以長期啟用Fetch任務了。

11???????? 參考博文

本文主要參考下面的博文:

http://www.iteblog.com/archives/category/hive







轉載于:https://my.oschina.net/u/1169607/blog/342316

總結

以上是生活随笔為你收集整理的apache hive 使用概述的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。