大資料系列之——hive(七、hive詳解及應用)
目錄
一、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的全部內容,如有疑問和建議歡迎留言。