Hive詳細教程

jopen 10年前發布 | 59K 次閱讀 Hive

為什么選擇Hive?


基于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>


 

   Hive詳細教程

sesese色

?用戶接口,包括 CLI,JDBC/ODBC,WebUI

?元數據存儲,通常是存儲在關系數據庫如 mysql, derby 中

?解釋器、編譯器、優化器、執行器

?Hadoop:用 HDFS 進行存儲,利用 MapReduce 進行計算

</td> </tr> </tbody> </table>

 

 

用戶接口主要有三個:CLIJDBC/ODBCWebUI

.CLI,即Shell命令行

.JDBC/ODBCHive Java,與使用傳統數據庫JDBC的方式類似

.WebGUI是通過瀏覽器訪問 Hive

Hive 將元數據存儲在數據庫中(metastore),目前只支持 mysqlderbyHive 中的元數據包括表的名字,表的列和分區及其屬性,表的屬性(是否為外部表等),表的數據所在目錄等

解釋器、編譯器、優化器完成 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

  • 1hive 命令行模式,直接輸入#/hive/bin/hive的執行程序,或者輸入 #hive --service cli

    2hive web界面的 (端口號9999) 啟動方式

    #hive --service hwi&

    用于通過瀏覽器來訪問hive

    http://hadoop0:9999/hwi/

    3hive 遠程服務 (端口號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的數據類型

    </tr> </tbody> </table>


    Hive的數據存儲

    基本數據類型
    tinyint / smalint / int /bigint
    float / double
    boolean
    string
    復雜數據類型
    Array/Map/Struct
    沒有date /datetime 

  • Hive的數據存儲基于Hadoop HDFS

    Hive沒有專門的數據存儲格式

    存儲結構主要包括:數據庫、文件、表、視圖

    Hive默認可以直接加載文本文件(TextFile),還支持sequence file

    創建表時,指定Hive數據的列分隔符與行分隔符,Hive即可解析數據

    </td> </tr> </tbody> </table>


    Hive的數據模型-內部表


    與數據庫中的 Table 在概念上是類似

    每一個 Table Hive 中都有一個相應的目錄存儲數據。例如,一個表 test,它在 HDFS 中的路徑為:/ warehouse/testwarehouse是在 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; #用哪種方式存儲數據,SEQUENCEFILEhadoop自帶的文件壓縮格式


    一些相關命令

    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客戶端

    </tr> </tbody> </table>



    UDF


    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>





    1、UDF函數可以直接應用于select語句,對查詢結構做格式化處理后,再輸出內容。

    2、編寫UDF函數的時候需要注意一下幾點:

    a)自定義UDF需要繼承org.apache.hadoop.hive.ql.UDF。

    b)需要實現evaluate函數,evaluate函數支持重載。

    4、步驟

    a)把程序打包放到目標機器上去;

    b)進入hive客戶端,添加jar包:hive>add jar /run/jar/udf_test.jar;

    c)創建臨時函數:hive>CREATE TEMPORARY FUNCTION add_example AS 'hive.udf.Add';

    d)查詢HQL語句:

    SELECT add_example(8, 9) FROM scores;

    SELECT add_example(scores.math, scores.art) FROM scores;

    SELECT add_example(6, 7, 8, 6.8) FROM scores;

    e)銷毀臨時函數:hive> DROP TEMPORARY FUNCTION add_example;

    注:UDF只能實現一進一出的操作,如果需要實現多進一出,則需要實現UDAF

    </td> </tr> </tbody> </table> 來自:http://my.oschina.net/yangzhiyuan/blog/228362

     本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!