Hive工具介紹(三)

Hive表的相關操作
Hive是一個數據倉庫,它可以把結構化的數據文件映射爲一張數據庫表,並且有SQL語言的查詢功能。
注意:一般來說數據倉庫存放的是一些歷史數據,它的作用是用來做查詢分析,往往不會用來做單條記錄的增加、刪除、修改
Hive表的創建語法與傳統的關係型數據庫類似,它是它的類型會更加複雜一些,如:它的類型可以是數組、Map……
一、創建Hive表
如下我們創建一張Hive表。
表名:person
字段包含:id,name,age,fav,addr
數據類型分別爲:int,String,int,String數組,Map<String,String>
 
建表語句:
CREATE TABLE person(
id INT,
name STRING,
age  INT,
fav  ARRAY<STRING>,
addr MAP<STRING,STRING>
)
COMMENT 'This is the person table'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
STORED AS TEXTFILE;
 
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'  這個用來設定每一個字段的分隔符,這裏的'\t'表示使用Tab鍵來進行分隔每行字段
COLLECTION ITEMS TERMINATED BY '-'  這個用來表示集合類型中每個對象的分隔符
fav ARRAY<STRING>  這個表示fav爲字符串的數組類型
MAP KEYS TERMINATED BY ':'  這個用來定義MAP類型的鍵值對的分隔符
STORED AS TEXTFILE  這個表示使用數據文件格式,這裏指的是txt類型
 
二、數據導入
在Hive中會把結構化的數據映射爲一張表,上述建立的有是一個txt格式的文件,注意這個txt文件中的內容必須要按照表定義的分隔符進行分隔。
導入文件數據:
新建一個txt文件 data.txt
1    rod    18    study-game-driver    std_addr:beijing-work_addr:shanghai
2    tom    21    study-game-driver    std_addr:beijing-work_addr:beijing
3    jerry    33    study-game-driver    std_addr:beijing-work_addr:shenzhen
導入文件命令如下:
load data local inpath '/root/data.txt' overwrite into table person;
導入成功後,查詢表數據:
select * from person;
 
三、表的分區與分桶
表進行分區 與分桶的目的是防止對錶中數據的全量掃描,從而提升查詢的性能。
刪除表操作:drop table person;
  1. 表的分區(在建立表時指定分區)
CREATE TABLE person(
id INT,
name STRING,
age  INT,
fav  ARRAY<STRING>,
addr MAP<STRING,STRING>
)
COMMENT 'This is the person table'
PARTITIONED BY(dt STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
STORED AS TEXTFILE;
 
在上面的建表語句中,指定了以String類型的字段dt爲依據進行分區,對於導入數據也存在一定的區別,在導入數據時也要指定導入哪一個分區中
load data local inpath '/root/data.txt' overwrite into table person partition(dt='20200512');
查詢數據
select * from person where dt='20200512';
select addr['work_addr'] from person where dt=20200512;
 
四、表的分桶
分桶是相對於分區進行更加細粒度的劃分,一旦當分區數量過於龐大時,我們就需要採用分桶來解決了。
分桶是把整個數據內容按某列屬性值的Hash值進行區分
分桶應該在建立表時進行建立
CREATE TABLE person(
id INT,
name STRING,
age  INT,
fav  ARRAY<STRING>,
addr MAP<STRING,STRING>
)
COMMENT 'This is the person table'
PARTITIONED BY(dt STRING)
clustered by (id) into 3 buckets
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY '-'
MAP KEYS TERMINATED BY ':'
STORED AS TEXTFILE;
上面的建表語句是分爲三個桶,那如果要查找第一個桶中的所有數據查詢語句如下:
select * from person tablesample(bucket 1 out of 3 on id);
 
如果運行過程中報錯:is running 460233216B beyond the 'VIRTUAL' memory limit.
一般是虛擬內存設置的不對的原因
解決方案:
在hadoop的配置文件目錄中,對mapred-site.xml中添加如下配置
<property>
 
    <name>mapreduce.map.memory.mb</name>
 
    <value>2048</value>
 
 </property>
 
 
  <property>
 
    <name>mapreduce.reduce.memory.mb</name>
 
    <value>2048</value>
 
 </property>
 
 
HA集羣發現其中一個備NN無法啓動
解決方案:
將能夠啓動的namenode節點的tmp/dfs/name目錄下面的文件拷貝到不能啓動的namenode節點上
然後重啓hdfs
 
五、內部表與外部表
Hive創建的表分爲內部表和外部表,對於內部表來說,在創建的時候會把數據移動到數據倉庫指向的位置,如果是外部表,則僅僅記錄數據所在的位置。
對於內部表,在刪除的時候會把元數據和數據一起刪除,外部表則僅僅只刪除元數據,真正的數據不會刪除。因而在共享源數據的情況下,可以選擇使用外部表。
  1. 內部表
        數據文件的全部操作都是由Hive來完成的,除此外不會有其它的應用使用這個數據文件
  1. 外部表
        在實際的應用中數據文件可能不僅僅是由Hive來操作,這時一般是不可以改變數據文件的格式及位置的,這時一般是用外部表來實現Hive操作
外部表的創建方式
  1. 創建一張空表,然後導入數據
     create external table person(
     id int,
    name string,
    age int,
    fav array<string>,
    addr map<string,string>
    )
    comment 'this is a person table'
    row format delimited fields terminated by '\t'
    collection items terminated by '-'
    map keys terminated by ':'
    stored as textfile;
注意:上面的建表語句使用了external關鍵字
  1. 導入數據:load data local inpath '/root/data.txt' overwrite into table person;
  2. 查看數據:dfs -ls /usr/hive/warehouse/person;
            查看數據是可以看到:/usr/hive/warehouse/person/data.txt
 
六、內置函數與自定義函數
Hive中包含了一些自定義的函數,如果內置函數不滿足需求,我們也可以編寫自定義函數(UDF:User Defined Function)
UDF函數有如下三種類型:
  1. UDF:用於單條數據,並且輸出一個數據行,大多數函數屬於這一類
  2. UDAF:可以接受多個輸入,同時輸出一個數據行
  3. UDTF:用於單個數據行同時產生多個輸出數據行
創建一個虛擬txt文件
echo 'X' > dual.txt
創建一個虛擬表dual
create table dual (dummy string);
導入數據
load data local inpath '/root/dual.txt' overwrite into table dual;
 
拼接函數concat
select concat('a','b','c','d') from dual;
輸出結果:abcd
統計記錄行count
select count(1) from dual;
輸出結果:1
拆分字符串並逐行輸出explode、split
select explode(split('a,b,c,d,e',',')) from dual;
輸出結果:
a
b
c
d
e
 
自定義函數
java代碼:
import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
import org.apache.hadoop.io.IntWritable;


public class Maximum extends UDAF {
    public static class MaximumIntUDAFEvaluator implements UDAFEvaluator{


        private IntWritable result;
        @Override
        public void init() {
            result = null;
        }


        public boolean iterate(IntWritable value){
            if(value == null){
                return true;
            }
            if(result == null){
                result = new IntWritable(value.get());
            } else {
                result.set(Math.max(result.get(),value.get()));
            }
            return true;
        }


        public IntWritable terminatePartial(){
            return result;
        }


        public boolean merge(IntWritable other){
            return iterate(other);
        }


        public IntWritable terminate(){
            return result;
        }
    }
}

 

將代碼打包爲jar包
1.file-->Project Structure-->Artifacts
2.輸入jar包的名稱,Output directory的路徑
3.添加好對應的包路徑
4.添加對應的class文件
5.打包爲jar包
上傳jar包到服務器
向Hive中添加jar包
add jar /root/Maximum.jar;
使用jar包來生成一個自定義函數
create function maximumtext as 'com.xiaoxie.hive.Maximum';
測試自定義函數
select maximumtest(id) from person;
返回結果:3
 
七、通過JAVA訪問Hive
 
JAVA代碼與訪問JDBC操作一致
import java.sql.*;


public class HiveTest {
    private static final String DRIVER = "org.apache.hive.jdbc.HiveDriver";
    private static final String DATABASE_PATH="jdbc:hive2://192.168.2.2:10000/default";
    private static final String USER_NAME="root";
    private static final String PASSWORD="123456";


    public static void main(String[] args) throws SQLException {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;


        String hql = "select count(1) from person";
        int count = 0;
        try {
            //註冊驅動
            Class.forName(DRIVER);
            //創建連接
            conn = DriverManager.getConnection(DATABASE_PATH,USER_NAME,PASSWORD);
            //創建statement
            stmt = conn.createStatement();
            //執行hql語句
            rs = stmt.executeQuery(hql);
            //處理結果集
            if(rs.next()){
                count = rs.getInt(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //關閉連接
            if(rs != null)
                rs.close();
            if(stmt != null)
                stmt.close();
            if(conn != null)
                conn.close();
        }
        System.out.println(count);
    }
}

 

注意:這裏需要導的包是:hive-jdbc-3.1.2.jar
 
執行時報錯:Error: Could not open connection to jdbc:hive2://192.168.2.2:10000/default: java.net.ConnectException: Connection refused (Connection refused) (state=08S01,code=0)
解決方案:
1.進入到hive的配置目錄conf,修改配置文件hive-site.xml
添加如下如下配置
<!--hive server2的超時時間,默認是5000-->
<property>
  <name>hive.server2.long.polling.timeout</name>
  <value>5000</value>
  <!--尤其注意時間是5000,原配置文件中會多個L,需要去掉-->
</property>
<!-- hive server2的使用端口,默認就是10000-->
<property>
  <name>hive.server2.thrift.port</name>
  <value>10000</value>
</property>
 
<!-- hive server2綁定的主機名-->
<property>
  <name>hive.server2.thrift.bind.host</name>
  <value>hadoop21</value>
</property>
2.啓動hive的後臺服務
hive --service hiveserver2 &
beeline
!connect jdbc:hive2://192.168.2.2:10000 root
輸入上面命令後輸入對應的密碼
 
如果報錯如下: root is not allowed to impersonate root
解決方案:
1.在hadoop的配置文件core-site.xml中添加如下屬性:
<property>
        <name>hadoop.proxyuser.root.hosts</name>
        <value>*</value>
</property>
<property>
        <name>hadoop.proxyuser.root.groups</name>
        <value>*</value>
</property>
2.重啓hdfs
3.如果還報錯,則表示hive所在的節點並不是active的節點(可以訪問 http://192.168.2.2:9870/dfshealth.html),可以看到當前節點如果是 standy。需要把它所在的節點切換爲active
運行java程序在linux後臺可以看到執行的過程,最後執行完成後會在控制檯打印出執行的結果。(注意在運行前一定要啓動hive)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章