1. 程式人生 > >大資料系列之——hive(七、hive詳解及應用)

大資料系列之——hive(七、hive詳解及應用)

目錄

2.HQL

一、HIVE概述

1.Hadoop分散式計算遇到的問題

MapReduce只能用java開發(也支援其他語言,但是不是主流)需要對Hadoop的底層原理 api比較瞭解才能順暢的開發出分散式的處理程式開發除錯麻煩。

2.HQL

Hive通過類SQL的語法,來進行分散式的計算。HQL用起來和SQL非常的類似,Hive在執行的過程中會將HQL轉換為MapReduce去執行,所以Hive其實是基於Hadoop的一種分散式計算框架,底層仍然是MapReduce,所以它本質上還是一種離線大資料分析工具。

Hive是基於Hadoop的一個數據倉庫工具。可以將結構化的資料檔案對映為一張資料庫表,並提供完整的sql查詢功能,可以將sql語句轉換為MapReduce任務進行執行。其優點是學習成本低,可以通過類SQL語句快速實現簡單的MapReduce統計,不必開發專門的MapReduce應用,十分適合資料倉庫的統計分析。

Hive是建立在 Hadoop 上的資料倉庫基礎構架。它提供了一系列的工具,可以用來進行資料提取轉化載入(ETL),這是一種可以儲存、查詢和分析儲存在 Hadoop 中的大規模資料的機制。Hive 定義了簡單的類 SQL 查詢語言,稱為 HiveQL,它允許熟悉 SQL 的使用者查詢資料。同時,這個語言也允許熟悉 MapReduce 開發者的開發自定義的 mapper 和 reducer 來處理內建的 mapper 和 reducer 無法完成的複雜的分析工作。

Hive不支援線上事務處理,.也不支援行級的插入和更新和刪除。

3.資料倉庫與資料庫的主要區別

(1)資料庫是面向事務的設計,資料倉庫是面向主題設計的。

(2)資料庫一般儲存線上交易資料,資料倉庫儲存的一般是歷史資料。 

(3)資料庫設計是儘量避免冗餘,資料倉庫在設計是有意引入冗餘。

(4)資料庫是為捕獲資料而設計,資料倉庫是為分析資料而設計。

(5)資料庫實現完整的增刪改查,資料倉庫只能一次寫入多次查詢 不支援行級別的增刪改。

(6)資料庫具有完整的事務保證,資料倉庫不強調事務特性。

二、Hive的安裝配置

下載從apache官網下載新版本hive,要注意和hadoop版本的匹配。

 安裝

需要提前安裝好jdk和hadoop,並且配置過JAVA_HOME和HADOOP_HOME,解壓即可安裝,安裝完成後可以進入bin下執行hive指令碼,如果能夠進入hive命令列說明hive安裝成功。

三、Hive原理

結論1:hive中的資料庫對應hdfs中/user/hive/warehouse目錄下以.db結尾的目錄。 結論2:hive中的表對應hdfs/user/hive/warehouse/[db目錄]中的一個目錄 結論3:hive中的資料對應當前hive表對應的hdfs目錄中的檔案。 結論4:hive會將命令轉換為mapreduce執行。 結論5:hive預設的default資料庫直接對應/user/hive/warehouse目錄,在default庫中建立的表直接會在該目錄下建立對應目錄。

四、Hive的元資料庫

Hive預設使用Derby作為元資料庫,但是這種方式只能用於測試不應用於生產環境中,生產環境中應該使用其他資料庫作為元資料儲存的資料庫使用。Hive目前支援Derby和MySql作為元資料庫使用。

1.配置mysql作為hive的元資料庫

mysql在linux中的安裝過程這裡不講述。

步驟:

(1)刪除hdfs中的/user/hive

hadoop fs -rmr /user/hive   

(2)複製hive/conf/hive-default.xml.template為hive-site.xml

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

在<configuration>中進行配置

#配置資料庫連線地址
            <property>
              <name>javax.jdo.option.ConnectionURL</name>
              <value>jdbc:mysql://hadoop01: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>root</value>
              <description>username to use against metastore database</description>
            </property>

#配置資料庫登入密碼
            <property>
              <name>javax.jdo.option.ConnectionPassword</name>
              <value>root</value>
              <description>password to use against metastore database</description>
            </property>

配置過mysql元資料庫後可能遇到的問題:

(1)hive無法啟動,提示缺少驅動包:將mysql的資料庫驅動包拷貝到hive/lib下

(2)hive無法啟動,提示連線被拒絕:在mysql中啟動許可權:

#(執行下面的語句  *.*:所有庫下的所有表   %:任何IP地址或主機都可以連線)             GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;             FLUSH PRIVILEGES;

(3)hive能夠啟動,但是在執行一些操作時報奇怪的錯誤:原因很可能是mysql中hive庫不是latin編碼,刪除元資料庫手動建立hive庫,指定編碼集為latin1。

連線mysql,發現多了一個hive庫。其中儲存有hive的元資料。

2.元資料庫介紹

    DBS:資料庫的元資料資訊         DB_ID 資料庫編號         DB_LOCATION_URI 資料庫在hdfs中的位置     TBLS:表資訊。         TBL_ID 表的編號         DB_ID 屬於哪個資料庫         TBL_NAME 表的名稱         TBL_TYPE 表的型別 內部表MANAGED_TABLE/外部表         COLUMNS_V2 表中欄位資訊         CD_ID 所屬表的編號         COLUMN_NAME 列明         TYPE_NAME 列的型別名     SDS:表對應hdfs目錄         CD_ID 表的編號         LOCATION 表對應到hdfs中的位置

五、內部表、外部表(重要)

內部表:         如果表是通過hive來建立,其中的資料也是通過hive來匯入,則先有表後有表中的資料,則稱這種表為內部表。外部表:         如果是先有的資料檔案,再建立hive表來管理,則這樣的表稱為外部表。         建立語法:create external table ext_student(id int ,name string) row format delimited fields terminated by '\t' location '/datax';

注意:

內部表被Drop的時候,表關聯的hdfs中的資料夾和其中的檔案都會被刪除。

外部表被Drop的時候,表關聯的hdfs中的資料夾和其中的檔案都不會被刪除。

內部表/外部表可以在表文件夾下直接上傳符合格式的檔案,從而增加表中的記錄。

六、分割槽表(重要)

hive也支援分割槽表     對資料進行分割槽可以提高查詢時的效率 。     普通表和分割槽表區別:有大量資料增加的需要建分割槽表     create table book (id bigint, name string) partitioned by (category string) row format delimited fields terminated by '\t';      create table book (id bigint, name string) partitioned by (category string,gender string) row format delimited fields terminated by '\t'; 

所謂的分割槽表是又在表文件夾下建立了子資料夾([分割槽的名]=分割槽名字的值 )分別存放同一張表中不同分割槽的資料,從而將資料分割槽存放,提高按照分割槽查詢資料時的效率。所以當資料量比較大,而且資料經常要按照某個欄位作為條件進行查詢時,最好按照該條件進行分割槽存放。通過觀察元資料庫發現,分割槽表也會當作元資料存放在SDS表中。

注意:如果手動的建立分割槽目錄,是無法被表識別到的,因為在元資料庫中並沒有該分割槽的資訊,如果想讓手動建立的分割槽能夠被表識別需要在元資料庫SDS表中增加分割槽的元資料資訊。

ALTER TABLE book add  PARTITION (category = 'jp',gender='male') location '/user/hive/warehouse/testx.db/book/category=jp/gender=male';

七、分桶表(重要)

hive也支援分桶表。分桶操作是更細粒度的分配方式。一張表可以同時分割槽和分桶。分桶的原理是根據指定的列的計算hash值模餘分桶數量後將資料分開存放。分桶的主要作用是:對於一個龐大的資料集我們經常需要拿出來一小部分作為樣例,然後在樣例上驗證我們的查詢,優化我們的程式。

建立帶桶的 table :         create table teacher(id int,name string) clustered by (id) into 4 buckets row format delimited fields terminated by '\t'; 強制多個 reduce 進行輸出:         set hive.enforce.bucketing=true;  往表中插入資料:         insert overwrite table teacher select * from temp;//需要提前準備好temp,從temp查詢資料寫入到teacher 查看錶的結構,會發現當前表下有四個檔案:         dfs -ls /user/hive/warehouse/teacher; 讀取資料,看一個檔案的資料:         dfs -cat /user/hive/warehouse/teacher/000000_0;         //桶使用 hash 來實現,所以每個檔案擁有的資料的個數都有可能不相等。 對桶中的資料進行取樣:         select * from teacher tablesample(bucket 1 out of 4 on id);         //桶的個數從1開始計數,前面的查詢從4個桶中的第一個桶獲取資料。其實就是四分之一。 查詢一半返回的桶數:         select * from bucketed_user tablesample(bucket 1 out of 2 on id);         //桶的個數從1開始計數,前2個桶中的第一個桶獲取資料。其實就是二分之一。

八、Hive的語法

1.資料型別         TINYINT - byte         SMALLINT - short         INT    - int         BIGINT - long         BOOLEAN - boolean         FLOAT - float         DOUBLE - double         STRING - String         TIMESTAMP - TimeStamp         BINARY - byte[]

2.create table         create table book (id bigint, name string)  row format delimited fields terminated by '\t';          create external table book (id bigint, name string)  row format delimited fields terminated by '\t' location 'xxxxx';          create table book (id bigint, name string) partitioned by (category string) row format delimited fields terminated by '\t';          3.修改表         增加分割槽:ALTER TABLE book add  PARTITION (category = 'zazhi') location '/user/hive/warehouse/datax.db/book/category=zazhi';         刪除分割槽:ALTER TABLE table_name DROP partition_spec, partition_spec,...         重命名錶:ALTER TABLE table_name RENAME TO new_table_name      修改列:ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]        增加/替換列:ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)

4.Show         檢視資料庫         SHOW DATABASES;         查看錶名         SHOW TABLES;

        查看錶名,部分匹配         SHOW TABLES 'page.*';         SHOW TABLES '.*view';

        檢視某表的所有Partition,如果沒有就報錯:         SHOW PARTITIONS page_view;

        檢視某表結構:         DESCRIBE invites;

        檢視分割槽內容         SELECT a.foo FROM invites a WHERE a.ds='2008-08-15';

        檢視有限行內容,同Greenplum,用limit關鍵詞         SELECT a.foo FROM invites a limit 3;

        查看錶分割槽定義         DESCRIBE EXTENDED page_view PARTITION (ds='2008-08-08');

5.Load         LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]         Load 操作只是單純的複製/移動操作,將資料檔案移動到 Hive 表對應的位置。

6.Insert         (1)將查詢的結果插入指定表中         INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement         (2)將查詢結果寫入檔案系統中          INSERT OVERWRITE [LOCAL] DIRECTORY directory1 SELECT ... FROM ...

7.Drop         刪除一個內部表的同時會同時刪除表的元資料和資料。刪除一個外部表,只刪除元資料而保留資料。

8.Limit          Limit 可以限制查詢的記錄數。查詢的結果是隨機選擇的

9.Select         SELECT [ALL | DISTINCT] select_expr, select_expr, ...         FROM table_reference         [WHERE where_condition]          [GROUP BY col_list]         [   CLUSTER BY col_list           | [DISTRIBUTE BY col_list] [SORT BY col_list]         ]         [LIMIT number]

10.JOIN         join_table:             table_reference JOIN table_factor [join_condition]           | table_reference {LEFT|RIGHT|FULL} [OUTER] JOIN table_reference join_condition           | table_reference LEFT SEMI JOIN table_reference join_condition

        table_reference:             table_factor           | join_table

        table_factor:             tbl_name [alias]           | table_subquery alias           | ( table_references )

        join_condition:             ON equality_expression ( AND equality_expression )*

        equality_expression:             expression = expression

九、HIVE的UDF

如果hive的內建函式不夠用,我們也可以自己定義函式來使用,這樣的函式稱為hive的使用者自定義函式,簡稱UDF。

    新建java工程,匯入hive相關包,匯入hive相關的lib。     建立類繼承UDF     自己編寫一個evaluate方法,返回值和引數任意。     為了能讓mapreduce處理,String要用Text處理。     將寫好的類打成jar包,上傳到linux中     在hive命令列下,向hive註冊UDF:add jar /xxxx/xxxx.jar     為當前udf起一個名字:create temporary function fname as '類的全路徑名';     之後就可以在hql中使用該自定義函數了。

十、HIVE的java api操作

hive實現了jdbc介面,所以可以非常方便用jdbc技術通過java程式碼操作。

1.在伺服器端開啟HiveServer服務         ./hive --service hiveserver2

2.建立本地工程,匯入jar包         匯入hive\lib目錄下的hive-jdbc-1.2.0-standalone.jar         匯入hadoop-2.7.1\share\hadoop\common下的hadoop-common-2.7.1.jar

3.編寫jdbc程式碼執行         Class.forName("org.apache.hive.jdbc.HiveDriver");         Connection conn = DriverManager.getConnection("jdbc:hive2://192.168.242.101:10000/park","root","root");         Statement statement = conn.createStatement();         //statement.executeUpdate("create table x2xx (id int,name string)");         //其他sql語句...         statement.close();         conn.close();

以上就是hive的全部內容,如有疑問和建議歡迎留言。