深入淺出學習Hive

本文是基於CentOS 7.9系統環境,進行hive的學習和使用

一、Hive的簡介

1.1 Hive基本概念

(1) 什麼是hive

Hive是用於解決海量結構化日誌的數據統計工具,是基於Hadoop的一個數據倉庫工具,可以將結構化的數據文件映射爲一張表,並提供類SQL查詢功能
(2) Hive的本質

Hive的本質就是將HQL轉化成MapReduce程序

1.2 Hive優缺點

(1) 優點

  1. 操作接口採用類SQL語法,提供快速開發的能力(簡單、容易)
  2. 避免寫MapReduce程序,減少開發人員的學習成本
  3. Hive優勢在於處理大數據,常用於數據分析,適用於實時性要求不高的場景
  4. hive支持用戶自定義函數,用戶可以根據自己的需求來實現自己的函數

(2) 缺點

  1. Hive執行延遲比較高,對於處理小數據沒有優勢
  2. hive的HQL表達能力有限(迭代式算法無法表達;數據挖掘方面不擅長,由於MapReduce數據處理流程的限制,效率更高的算法卻無法實現)
  3. hive的效率比較低(hive自動生成的MapReduce作業,通常情況下不夠智能化;hive調優比較困難,粒度較粗)

1.3 Hive架構

在這裏插入圖片描述

  • Client 用戶接口

    CLI(command-line interface)、JDBC/ODBC(jdbc訪問hive)、WEBUI(瀏覽器訪問hive)

  • Metastore

    元數據包括:表名、表所屬的數據庫(默認是default)、表的擁有者、列/分區字段、表的類型(是否是外部表)、表的數據所在目錄等;默認存儲在自帶的derby數據庫中,推薦使用MySQL存儲Metastore

  • SQL Parser 解析器

    對SQL語句進行解析,轉換成抽象語法樹AST,並進行語法分析和檢查

  • Physical Plan 編譯器

    將抽象語法樹AST編譯成邏輯執行計劃

  • Query Optimizer 優化器

    對邏輯執行計劃進行優化

  • Execution 執行器

    將邏輯執行計劃轉換成可以運行的物理計劃,也就是MR任務

1.4 Hive工作機制

Hive通過給用戶提供的一系列交互接口,接收到用戶的指令(SQL),使用自己的Driver,結合元數據(MetaStore),將這些指令翻譯成MapReduce,提交到Hadoop中執行,最後,將執行返回的結果輸出到用戶交互接口。
在這裏插入圖片描述

1.5 Hive和數據庫比較

由於 Hive 採用了類似SQL 的查詢語言 HQL(Hive Query Language),因此很容易將 Hive 理解爲數據庫。其實從結構上來看,Hive 和數據庫除了擁有類似的查詢語言,再無類似之處。本文將從多個方面來闡述 Hive 和數據庫的差異。數據庫可以用在 Online 的應用中,但是Hive 是爲數據倉庫而設計的,清楚這一點,有助於從應用角度理解 Hive 的特性。

  • 查詢語言

    由於SQL被廣泛的應用在數據倉庫中,因此,專門針對Hive的特性設計了類SQL的查詢語言HQL。熟悉SQL開發的開發者可以很方便的使用Hive進行開發。

  • 數據存儲位置

    Hive 是建立在 Hadoop 之上的,所有 Hive 的數據都是存儲在 HDFS 中的。而數據庫則可以將數據保存在塊設備或者本地文件系統中。

  • 數據更新

    由於Hive是針對數據倉庫應用設計的,而數據倉庫的內容是讀多寫少的。因此,Hive中不建議對數據的改寫,所有的數據都是在加載的時候確定好的。而數據庫中的數據通常是需要經常進行修改的,因此可以使用 INSERT INTO … VALUES 添加數據,使用 UPDATE … SET修改數據。

  • 執行

    Hive中大多數查詢的執行是通過 Hadoop 提供的 MapReduce 來實現的。而數據庫通常有自己的執行引擎。

  • 執行延遲

    Hive 在查詢數據的時候,由於沒有索引,需要掃描整個表,因此延遲較高。另外一個導致 Hive 執行延遲高的因素是 MapReduce框架。由於MapReduce 本身具有較高的延遲,因此在利用MapReduce 執行Hive查詢時,也會有較高的延遲。相對的,數據庫的執行延遲較低。當然,這個低是有條件的,即數據規模較小,當數據規模大到超過數據庫的處理能力的時候,Hive的並行計算顯然能體現出優勢。

  • 可擴展性

    由於Hive是建立在Hadoop之上的,因此Hive的可擴展性是和Hadoop的可擴展性是一致的(世界上最大的Hadoop 集羣在 Yahoo!,2009年的規模在4000 臺節點左右)。而數據庫由於 ACID 語義的嚴格限制,擴展行非常有限。目前最先進的並行數據庫 Oracle 在理論上的擴展能力也只有100臺左右。

  • 數據規模

    由於Hive建立在集羣上並可以利用MapReduce進行並行計算,因此可以支持很大規模的數據;對應的,數據庫可以支持的數據規模較小。

二、Hive的安裝

2.1 Hive下載

apache-hive-1.2.1-bin.tar.gz


2.2 Hive解壓

tar -xzvf apache-hive-1.2.1-bin.tar.gz -C /opt/module
cd /opt/module
mv apache-hive-1.2.1-bin hive


2.3 配置環境變量

vi /etc/profile
# 添加如下內容
#HIVE_HOME
export HIVE_HOME=/opt/module/hive
export PATH=$PATH:$HIVE_HOME/bin


2.4 修改hive配置文件

cd /opt/module/hive/conf
cp hive-env.sh.template hive-env.sh
vi hive-env.sh
# 添加如下內容
# Set HADOOP_HOME to point to a specific hadoop install directory
HADOOP_HOME=/opt/module/hadoop-2.7.2
# Hive Configuration Directory can be controlled by:
export HIVE_CONF_DIR=/opt/module/hive/conf


2.5 啓動並測試hive

hive


# 創建數據庫
create database test;
# 創建數據表
create table student(id int, name string);
# 插入數據
insert into table student values(1001, "zhangsan");
# 查詢數據
select * from student;
# 刪除數據表
drop table student;
# 刪除數據庫
drop database test;


2.6 hive的bug

hive默認存儲元數據的數據庫爲derby,不支持併發訪問,多開幾個hive客戶端會出現異常

2.7 MySQL的安裝

hive默認存儲元數據的數據庫爲derby,不支持併發訪問,多開幾個hive客戶端會出現異常,因此需要安裝MySQL數據庫來替換

CentOS 7離線安裝MySQL 5.6

2.8 Hive配置MySQL

cd /opt/module/hive/conf
vi hive-site.xml
# 添加如下內容
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <property>
      <name>javax.jdo.option.ConnectionURL</name>
      <value>jdbc:mysql://192.168.1.101:3306/metastore?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>
</configuration>


2.9 啓動Hive

hive


2.10 Beeline啓動Hive

cd /opt/module/hive/bin
./hiveserver2


打開另一個終端

cd /opt/module/hive/bin
./beeline
!connect jdbc:hive2://hadoop101:10000


只需輸入啓動hadoop的用戶名,不需要密碼

三、Hive的使用

3.1 Hive的交互命令

運行來自命令行的SQL

cd /opt/module/hive
bin/hive -e "select * from test.student;"
bin/hive -e "select * from test.student;">result.log


運行來自文件的SQL

cd /opt/module/hive
vi test.sql
# 添加如下內容
select * from test.student;
# 執行下面命令
bin/hive -f test.sql>result.log


退出hive客戶端

quit;


3.2 Hive數據倉庫位置配置

cd /opt/module/hive/conf
vi hive-site.xml
# 添加如下內容
<property>
    <name>hive.metastore.warehouse.dir</name>
    <value>/user/hive/warehouse</value>
    <description>location of default database for the warehouse</description>
</property>


3.3 查詢後信息顯示配置(可選配)

cd /opt/module/hive/conf
vi hive-site.xml
# 添加如下內容
<property>
    <name>hive.cli.print.header</name>
    <value>true</value>
</property>
<property>
    <name>hive.cli.print.current.db</name>
    <value>true</value>
</property>


3.4 Hive運行日誌信息配置(必須配置)

cd /opt/module/hive/conf
cp hive-log4j.properties.template hive-log4j.properties
vi hive-log4j.properties
# 添加如下內容
hive.log.dir=/opt/module/hive/logs


四、Hive的數據類型

4.1 Hive基本數據類型

hive數據類型 java數據類型 長度 示例
tinyint byte 1byte有符號整數 20
smalint short 2byte有符號整數 20
int int 4byte有符號整數 20
bigint long 8byte有符號整數 20
boolean boolean 布爾類型,true或者false TRUE FALSE
float float 單精度浮點數 3.14159
double double 雙精度浮點數 3.14159
string string 字符系列,可以使用單引號或者雙引號 ‘now is’ “i am a”
timestamp   時間類型  
binary   字節數組  

4.2 Hive集合數據類型

數據類型 描述 語法示例
struct 和c語言中的struct類似,都可以通過“點”符號訪問元素內容。例如,如果某個列的數據類型是STRUCT{first STRING, last STRING},那麼第1個元素可以通過字段.first來引用。 struct() 例如struct<street:string, city:string>
map MAP是一組鍵-值對元組集合,使用數組表示法可以訪問數據。例如,如果某個列的數據類型是MAP,其中鍵->值對是’first’->’John’和’last’->’Doe’,那麼可以通過字段名[‘last’]獲取最後一個元素 map() 例如map<string, int>
array 數組是一組具有相同類型和名稱的變量的集合。這些變量稱爲數組的元素,每個數組元素都有一個編號,編號從零開始。例如,數組值爲[‘John’, ‘Doe’],那麼第2個元素可以通過數組名[1]進行引用。 Array() 例如array
  • 案例

    創建數據文件test.txt

vi test.txt
# 添加如下內容
songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing
yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing


創建表結構文件test.sql

vi test.sql
# 添加如下內容
create table test.test(
name string,
friends array<string>,
children map<string, int>,
address struct<street:string, city:string>
)
row format delimited fields terminated by ','
collection items terminated by '_'
map keys terminated by ':'
lines terminated by '\n';


上傳數據文件test.txt

hdfs dfs -put test.txt /user/hive/warehouse/test.db/test


測試查詢

hive
use test;
select name,friends[1],children["xiao song"],address.city from test;


4.3 類型轉化

Hive的原子數據類型是可以進行隱式轉換的,類似於Java的類型轉換,例如某表達式使用INT類型,TINYINT會自動轉換爲INT類型,但是Hive不會進行反向轉化,例如,某表達式使用TINYINT類型,INT不會自動轉換爲TINYINT類型,它會返回錯誤,除非使用CAST操作。

  • 隱式類型轉換規則如下
  1. 任何整數類型都可以隱式地轉換爲一個範圍更廣的類型,如TINYINT可以轉換成INT,INT可以轉換成BIGINT。
  2. 所有整數類型、FLOAT和STRING類型都可以隱式地轉換成DOUBLE。
  3. TINYINT、SMALLINT、INT都可以轉換爲FLOAT。
  4. BOOLEAN類型不可以轉換爲任何其它的類型。
  • 可以使用CAST操作顯示進行數據類型轉換

    例如CAST(‘1’ AS INT)將把字符串’1’ 轉換成整數1;如果強制類型轉換失敗,如執行CAST(‘X’ AS INT),表達式返回空值 NULL。

select '1'+2, cast('1'as int) + 2;


五、DDL數據庫定義語言

5.1 創建數據庫

CREATE DATABASE [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[WITH DBPROPERTIES (property_name=property_value, ...)];


  • 實例:新建一個名爲test1的數據庫,存儲在HDFS中的 /test 路徑下
create database test1 comment "test1 database" location "/test" with dbproperties("zhangsan"="lisi");


5.2 顯示所有數據庫

show databases;


5.3 過濾顯示數據庫

show databases like 'test';


5.4 顯示指定數據庫的信息

desc database test1;


5.5 顯示指定數據庫的詳細信息

desc database extended test1;


5.6 切換數據庫

use test1;


5.7 修改數據庫

alter database test1 set dbproperties('name'='zhangsan');


5.8 刪除空的數據庫

drop database test1;
drop database if exists test1;


5.9 刪除非空數據庫

drop database test1 cascade;


5.10 創建數據表

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] ## 分區表在HDFS中體現爲分爲多個文件夾
[CLUSTERED BY (col_name, col_name, ...) ## 分區表在HDFS中體現爲一個文件夾下分爲多個文件
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)]
[AS select_statement]


  • 實例:新建一個名爲student1的表,存儲在HDFS中的 /student 路徑下
create table student1(id int comment "Identity", age int comment "Age") comment "Student" row format delimited fields terminated by '\t' location '/student';


5.11 顯示指定表的信息和創建表時的配置

desc student1;
show create table student1;


5.12 顯示指定表的詳細信息

desc formatted student1;


5.13 外部表和管理表

  • 管理表(managed_table)

刪除表後,存儲在HDFS上的數據也會被刪除

  • 外部表(external_table)

刪除表後,存儲在HDFS上的數據不會被刪除

5.14 將數據表修改爲外部表

alter table student1 set tblproperties('EXTERNAL'='TRUE');


5.15 將數據表修改爲管理表

alter table student2 set tblproperties('EXTERNAL'='FALSE');


5.16 創建分區表

謂詞下退,先走過濾
1. 新建表

create table dept_partition(deptno int, dname string, loc string)
partitioned by (month string)
row format delimited fields terminated by '\t';


2. 加載數據

hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201709');
hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201708');
hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201707');


3. 查詢表數據

select * from dept_partition where month='201709';


4. 聯合查詢表數據

select * from dept_partition where month='201709' union
select * from dept_partition where month='201708' union
select * from dept_partition where month='201707';


5.17 新增分區

hive (default)> alter table dept_partition add partition(month='201705') partition(month='201704');


5.18 刪除分區

hive (default)> alter table dept_partition drop partition(month='201705'), partition(month='201704');


5.19 查詢分區表有多少分區

show partitions dept_partition;


5.20 查詢分區表的結構

desc formatted dept_partition;


5.21 創建二級分區表

  1. 新建表
create table dept_partition2(deptno int, dname string, loc string)
partitioned by (month string, day string)
row format delimited fields terminated by '\t';


  1. 加載數據
load data local inpath '/opt/module/datas/dept.txt' into table
 default.dept_partition2 partition(month='201709', day='13');


5.22 修復分區

msck repair table dept_partition2;


5.23 重命名錶

alter table dept_partition2 rename to dept_partition3;


5.24 添加列

alter table dept_partition add columns(deptdesc string);


5.25 更新列

alter table dept_partition change column deptdesc desc int;


5.26 替換列

alter table dept_partition replace columns(deptno string, dname  
 string, loc string);


六、DML數據庫操作語言

6.1 數據導入

6.1.1 向表中裝載數據

load data [local] inpath '/opt/module/datas/student.txt' [overwrite] into table student [partition (partcol1=val1,…)];
# local:表示從本地加載數據到hive表;否則從HDFS加載數據到hive表
# overwrite:表示覆蓋表中已有數據,否則表示追加

6.1.2 通過查詢語句向表中插入數據

# 基本插入
insert into table student values(1,'wangwu'),(2,'zhaoliu');
# 查詢插入
insert overwrite table student
select id, name from student where id>10;

6.1.3 查詢語句中創建表並加載數據(As Select)

create table if not exists student3 as select id, name from student;

6.1.4 創建表時通過Location指定加載數據路徑

上傳數據至HDFS

hive (default)> dfs -mkdir /student;
hive (default)> dfs -put /opt/module/datas/student.txt /student;

創建表,並指定HDFS上的位置

create external table if not exists student5(id int, name string)
row format delimited fields terminated by '\t'
location '/student;

查詢數據

hive (default)> select * from student5;

6.1.5 Export導出到HDFS上

# 先用export導出後,再將數據導入
import table student2 from '/user/hive/warehouse/export/student';

6.2 數據導出

6.2.1 Insert導出

# 導出到本地
insert overwrite local directory '/opt/module/datas/export/student1'
row format delimited fields terminated by '\t'
select * from student;
# 導出到HDFS
insert overwrite directory '/user/xuzheng/student2'
row format delimited fields terminated by '\t'
select * from student;

6.2.2 Hadoop命令導出到本地

hive (default)> dfs -get /user/hive/warehouse/student/month=201709/000000_0
/opt/module/datas/export/student3.txt;

6.2.3 Hive Shell 命令導出

bin/hive -e 'select * from default.student;' > /opt/module/datas/export/student4.txt;

6.2.4 Export導出到HDFS上

export和import主要用於兩個Hadoop平臺集羣之間Hive表遷移

# 既能導出元數據,也能導出數據
export table default.student to '/user/hive/warehouse/export/student';

6.3 清除數據(不清除元數據)

# Truncate只能刪除管理表,不能刪除外部表中數據
truncate table student;

七、基本查詢

(1)寫SQL語句關鍵字的順序

select
from
join on
where
group by
order by
having
limit

(1)執行SQL語句關鍵字的順序

from
join
on
where
group by(開始使用select中的別名,後面的語句中都可以使用)
avg,sum....
having
select
distinct
order by
limit

(1)謂詞下推

先走過濾,再走查詢
(1)SQL優化

在join on條件中,可以使用子查詢語句僅需優化

select
id,name
from
A join B
on A.id=B.id and A.id>100;
優化後================================
select
id,name
from
(select id,name from A where A.id>100) t1
join B
on t1.id=B.id;

(2) 數據準備

# 創建部門表
create table if not exists dept(deptno int, dname string, loc int)
row format delimited fields terminated by '\t';

# 創建員工表
create table if not exists emp(empno int, ename string, job string, mgr int, hiredate string, sal double, comm double, deptno int)
row format delimited fields terminated by '\t';

# 向部門表導入數據
load data local inpath '/home/xuzheng/dept.txt' into table dept;

# 向員工表導入數據
load data local inpath '/home/xuzheng/emp.txt' into table emp;

(3) 全表和特定列查詢

# 全表查詢
select * from emp;
# 特定列查詢
select empno, ename from emp;

(4) 列別名

select ename as name, deptno dn from emp;

(5)算術運算符
運算符 描述
A + B A和B相加
A - B A和B相減
A * B A和B相乘
A / B A和B相除
A % B A對B取餘
A & B A和B按位取餘
A|B A和B按位取或
A ^ B A和B按位取異或
~A A按位取反

select sal +1 from emp;

(6)常用函數

# 求總行數
select count(*) cnt from emp;
# 求最大值
select max(sal) max_sal from emp;
# 求最小值
select min(sal) min_sal from emp;
# 求總和
select sum(sal) sum_sal from emp;
# 求平均值
select avg(sal) avg_sal from emp;

(7) Limit語句

select * from emp limit 5;

(8)where語句

# where子句中不能使用字段別名
select * from emp where sal >1000;

(9)比較運算符
操作符 支持的數據類型 描述
A = B 基本數據類型 如果A等於B則返回TRUE,反之返回FALSE
A <=> B 基本數據類型 如果A和B都爲NULL,則返回TRUE,其他的和等號(=)操作符的結果一致,如果任一爲NULL則結果爲NULL
A<>B, A!=B 基本數據類型 A或者B爲NULL則返回NULL;如果A不等於B,則返回TRUE,反之返回FALSE
A<B 基本數據類型 A或者B爲NULL,則返回NULL;如果A小於B,則返回TRUE,反之返回FALSE
A<=B 基本數據類型 A或者B爲NULL,則返回NULL;如果A小於等於B,則返回TRUE,反之返回FALSE
A>B 基本數據類型 A或者B爲NULL,則返回NULL;如果A大於B,則返回TRUE,反之返回FALSE
A>=B 基本數據類型 A或者B爲NULL,則返回NULL;如果A大於等於B,則返回TRUE,反之返回FALSE
A [NOT] BETWEEN B AND C 基本數據類型 如果A,B或者C任一爲NULL,則結果爲NULL。如果A的值大於等於B而且小於或等於C,則結果爲TRUE,反之爲FALSE。如果使用NOT關鍵字則可達到相反的效果。
A IS NULL 所有數據類型 如果A等於NULL,則返回TRUE,反之返回FALSE
A IS NOT NULL 所有數據類型 如果A不等於NULL,則返回TRUE,反之返回FALSE
IN(數值1, 數值2) 所有數據類型 使用 IN運算顯示列表中的值
A [NOT] LIKE B STRING 類型 B是一個SQL下的簡單正則表達式,也叫通配符模式,如果A與其匹配的話,則返回TRUE;反之返回FALSE。B的表達式說明如下:‘x%’表示A必須以字母‘x’開頭,‘%x’表示A必須以字母’x’結尾,而‘%x%’表示A包含有字母’x’,可以位於開頭,結尾或者字符串中間。如果使用NOT關鍵字則可達到相反的效果。
A RLIKE B, A REGEXP B STRING 類型 B是基於java的正則表達式,如果A與其匹配,則返回TRUE;反之返回FALSE。匹配使用的是JDK中的正則表達式接口實現的,因爲正則也依據其中的規則。例如,正則表達式必須和整個字符串A相匹配,而不是隻需與其字符串匹配。

# 查詢出薪水等於5000的所有員工
select * from emp where sal = 5000;
# 查詢工資在500到1000的員工信息
select * from emp where sal between 500 and 1000;
# 查詢comm爲空的所有員工信息
select * from emp where comm is null;
# 查詢工資是1500或5000的員工信息
select * from emp where sal IN (1500, 5000);

(10)like和rlike

**rlike:**帶有正則表達式的like語句
正則匹配 描述
\ 轉義
^ 一行的開頭
^R 匹配以R爲開頭的行
$ 匹配一行的結尾
R$ 匹配以R爲結尾的行

  • 表示上一個子式匹配0次或多次,貪心匹配
    Zo* Zo Zoo Zooo
    . 匹配一個任意的字符
    .* 匹配任意字符串
    [] 匹配某個範圍內的字符
    [a-z] 匹配一個a-z之間的字符
    [a-z]* 匹配任意字母字符串
# 查找以2開頭薪水的員工信息
select * from emp where sal LIKE '2%';
# 查找第二個數值爲2的薪水的員工信息
select * from emp where sal LIKE '_2%';
# 查找薪水中含有2的員工信息
select * from emp where sal RLIKE '[2]';

(11)邏輯運算符
操作符 描述
and 邏輯並
or 邏輯或
not 邏輯否

# 查詢薪水大於1000,部門是30
select * from emp where sal>1000 and deptno=30;
# 查詢薪水大於1000,或者部門是30
select * from emp where sal>1000 or deptno=30;
# 查詢除了20部門和30部門以外的員工信息
select * from emp where deptno not IN(30, 20);

八、分組

8.1 group by語句

# 計算emp表每個部門的平均工資
select t.deptno, avg(t.sal) avg_sal from emp t group by t.deptno;
# 計算emp每個部門中每個崗位的最高薪水
select t.deptno, t.job, max(t.sal) max_sal from emp t group by
t.deptno, t.job;

8.2 having語句

having和where不同點

where後面不能寫分組函數,而having後面可以使用分組函數  
having只用於group by分組統計語句


# 求每個部門的平均工資
select deptno, avg(sal) from emp group by deptno;
# 求每個部門的平均薪水大於2000的部門
select deptno, avg(sal) avg_sal from emp group by deptno having
avg_sal > 2000;

九、join語句

9.1 等值join

# 根據員工表和部門表中的部門編號相等,查詢員工編號、員工名稱和部門名稱;
select e.empno, e.ename, d.deptno, d.dname from emp e join dept d on e.deptno = d.deptno;

9.2 表的別名

# 合併員工表和部門表
select e.empno, e.ename, d.deptno from emp e join dept d on e.deptno = d.deptno;

9.3 內連接

# 只有進行連接的兩個表中都存在與連接條件相匹配的數據纔會被保留下來
select e.empno, e.ename, d.deptno from emp e join dept d on e.deptno = d.deptno;

9.4 左外連接

# JOIN操作符左邊表中符合WHERE子句的所有記錄將會被返回
select e.empno, e.ename, d.deptno from emp e left join dept d on e.deptno = d.deptno;

9.5 右外連接

# JOIN操作符右邊表中符合WHERE子句的所有記錄將會被返回
select e.empno, e.ename, d.deptno from emp e right join dept d on e.deptno = d.deptno;

9.6 滿外連接

# 將會返回所有表中符合WHERE語句條件的所有記錄。如果任一表的指定字段沒有符合條件的值的話,那麼就使用NULL值替代
select e.empno, e.ename, d.deptno from emp e full join dept d on e.deptno = d.deptno;

9.7 多表連接

**創建位置表 **

create table if not exists location(loc int, loc_name string)
row format delimited fields terminated by '\t';

導入數據

load data local inpath '/home/xuzheng/location.txt' into table location;

多表連接查詢

SELECT e.ename, d.dname, l.loc_name
FROM emp e
JOIN dept d
ON d.deptno = e.deptno
JOIN location l
ON d.loc = l.loc;

9.8 笛卡爾積

hive中嚴禁使用笛卡爾積

產生笛卡爾的條件

省略連接條件  
連接條件無效  
所有表中的所有行互相連接


9.9 連接謂詞中不支持or

hive join目前不支持在on子句中使用謂詞or

十、排序

10.1 全局排序

排序規則

asc: 升序  
desc:降序

# 查詢員工信息按工資升序排列
select * from emp order by sal;
# 查詢員工信息按工資降序排列
select * from emp order by sal desc;

10.2 按照別名排序

# 按照員工薪水的2倍排序
select ename, sal*2 twosal from emp order by twosal;

10.3 多個列排序

# 按照部門和工資升序排序
select ename, deptno, sal from emp order by deptno, sal;

10.4 每個MapReduce內部排序

Sort By:對於大規模的數據集order by的效率非常低。在很多情況下,並不需要全局排序,此時可以使用sort by,按照分區排序。

Sort by爲每個reducer產生一個排序文件。每個Reducer內部進行排序,對全局結果集來說不是排序。

# 設置reduce個數
set mapreduce.job.reduces=3;
# 查看設置reduce個數
set mapreduce.job.reduces;
# 根據部門編號降序查看員工信息
select * from emp sort by deptno desc;
# 將查詢結果導入到文件中(按照部門編號降序排序)
insert overwrite local directory '/home/xuzheng/datas/sortby-result' select * from emp sort by deptno desc;

10.5 分區排序

Distribute By: 在有些情況下,我們需要控制某個特定行應該到哪個reducer,通常是爲了進行後續的聚集操作。distribute by 子句可以做這件事。distribute by類似MR中partition(自定義分區),進行分區,結合sort by使用。

對於distribute by進行測試,一定要分配多reduce進行處理,否則無法看到distribute by的效果。

# 設置reduce個數
set mapreduce.job.reduces=3;
# 先按照部門編號分區,再按照員工編號降序排序
select * from emp distribute by deptno sort by empno desc;

排序規則

distribute by的分區規則是根據分區字段的hash碼與reduce的個數進行模除後,餘數相同的分到一個區  
Hive要求DISTRIBUTE BY語句要寫在SORT BY語句之前

10.6 Cluster By

當distribute by和sorts by字段相同時,可以使用cluster by方式

cluster by除了具有distribute by的功能外還兼具sort by的功能。但是排序只能是升序排序,不能指定排序規則爲ASC或者DESC

# 按照部門編號分區排序
select * from emp cluster by deptno;
# 與上面語句等價
select * from emp distribute by deptno sort by deptno;

十一、分桶及抽樣查詢

11.1 分桶表數據存儲

創建分桶表

create table stu_buck(id int, name string)
clustered by(id)
into 4 buckets
row format delimited fields terminated by '\t';

創建臨時表

create table stu(id int, name string)
row format delimited fields terminated by '\t';

導入數據至臨時表

load data local inpath '/home/xuzheng/student.txt' into table stu;

設置強制分桶

set hive.enforce.bucketing=true;

設置reduce個數

# 讓hive自己去決定分桶個數
set mapreduce.job.reduces=-1;

導入數據至分桶表

insert into stu_buck select * from stu;

11.2 分桶抽樣查詢

tablesample((bucket x out of y)

y必須是table總bucket數的倍數或者因子。hive根據y的大小,決定抽樣的比例。例如,table總共分了4份,當y=2時,抽取(4/2=)2個bucket的數據,當y=8時,抽取(4/8=)1/2個bucket的數據

# 按照id抽樣查詢,將數據分4份,每一份取第1個數據
select * from stu_buck tablesample(bucket 1 out of 4 on id);

十二、其他常用查詢函數

12.1 空字段賦值

函數說明  
NVL:給值爲NULL的數據賦值,它的格式是NVL( value,default\_value)。它的功能是如果value爲NULL,則NVL函數返回default\_value的值,否則返回value的值,如果兩個參數都爲NULL ,則返回NULL。

# 如果員工的comm爲NULL,則用-1代替
select comm,nvl(comm, -1) from emp;

# 如果員工的comm爲NULL,則用領導id代替
select comm, nvl(comm,mgr) from emp;

12.2 時間類

date_format格式化時間

select date_format('2019-06-12', 'yyyy-MM-dd');

date_add時間相加天數

select date_add('2019-06-12', 5);
select date_add('2019-06-12', -5);

date_sub時間相減天數

select date_sub('2019-06-12', 5);
select date_sub('2019-06-12', -5);

兩個時間相減得天數

select datediff('2019-06-12', '2019-06-10');

替換函數

select regexp_replace('2019/06/12', '/', '-');

12.3 CASE WHEN

數據準備

姓名 部門 性別
悟空 A 男
大海 A 男
宋宋 B 男
鳳姐 A 女
婷姐 B 女
婷婷 B 女

創建表

create table emp_sex(name string, dept_id string, sex string)
row format delimited fields terminated by "\t";

導入數據

load data local inpath '/home/xuzheng/emp_sex.txt' into table emp_sex;

查詢語句

# 求出不同部門男女各多少人。結果如下:
select
dept_id,
sum(case sex when '男' then 1 else 0 end) male_count,
sum(case sex when '女' then 1 else 0 end) female_count
from
emp_sex
group by
dept_id;

12.4 行轉列

數據準備

姓名 星座 血型
孫悟空 白羊座 A
大海 射手座 A
宋宋 白羊座 B
豬八戒 白羊座 A
鳳姐 射手座 A

**需求  **
把星座和血型一樣的人歸類到一起。結果如下:

射手座,A 大海|鳳姐
白羊座,A 孫悟空|豬八戒
白羊座,B 宋宋|蒼老師

創建本地constellation.txt

vi constellation.txt
孫悟空 白羊座 A
大海 射手座 A
宋宋 白羊座 B
豬八戒 白羊座 A
鳳姐 射手座 A

創建hive表

create table person_info(name string, constellation string, blood_type string)
row format delimited fields terminated by "\t";

導入數據

load data local inpath "/home/xuzheng/constellation.txt" into table person_info;

查詢語句

select
t1.base,
concat_ws('|', collect_set(t1.name)) name
from
(select
name,
concat(constellation, ",", blood_type) base
from
person_info) t1
group by
t1.base;

12.5 列轉行

數據準備

電源 分類
《疑犯追蹤》 懸疑,動作,科幻,劇情
《Lie to me》 懸疑,警匪,動作,心理,劇情
《戰狼2》 戰爭,動作,災難

**需求  **
將電影分類中的數組數據展開。結果如下:

《疑犯追蹤》 懸疑
《疑犯追蹤》 動作
《疑犯追蹤》 科幻
《疑犯追蹤》 劇情
《Lie to me》 懸疑
《Lie to me》 警匪
《Lie to me》 動作
《Lie to me》 心理
《Lie to me》 劇情
《戰狼2》 戰爭
《戰狼2》 動作
《戰狼2》 災難

創建本地movie.txt

vi movie.txt
《疑犯追蹤》 懸疑,動作,科幻,劇情
《Lie to me》 懸疑,警匪,動作,心理,劇情
《戰狼2》 戰爭,動作,災難

創建hive表

create table movie_info(movie string, category array<string>)
row format delimited fields terminated by "\t"
collection items terminated by ",";

導入數據

load data local inpath "/home/xuzheng/movie.txt" into table movie_info;

查詢語句

select
movie,
category_name
from
movie_info lateral view explode(category) table_tmp as category_name;

12.6 窗口函數

數據準備

姓名 購買日期 價格
jack 2017-01-01 10
tony 2017-01-02 15
jack 2017-02-03 23
tony 2017-01-04 29
jack 2017-01-05 46
jack 2017-04-06 42
tony 2017-01-07 50
jack 2017-01-08 55
mart 2017-04-08 62
mart 2017-04-09 68
neil 2017-05-10 12
mart 2017-04-11 75
neil 2017-06-12 80
mart 2017-04-13 94

創建本地business.txt

vi business.txt

創建hive表

create table business(name string, orderdate string,cost int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

導入數據

load data local inpath "/home/xuzheng/business.txt" into table business;

按需求查詢數據

查詢在2017年4月份購買過的顧客及總人數

select name,count(*) over ()
from business
where substring(orderdate,1,7) = '2017-04'
group by name;

查詢顧客的購買明細及月購買總額

select name,orderdate,cost,sum(cost) over(partition by name, month(orderdate)) from business;

上述的場景, 將每個顧客的cost按照日期進行累加

select name,orderdate,cost,
sum(cost) over() as sample1,--所有行相加
sum(cost) over(partition by name) as sample2,--按name分組,組內數據相加
sum(cost) over(partition by name order by orderdate) as sample3,--按name分組,組內數據累加
sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row ) as sample4 ,--和sample3一樣,由起點到當前行的聚合
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING and current row) as sample5, --當前行和前面一行做聚合
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING AND 1 FOLLOWING ) as sample6,--當前行和前邊一行及後面一行
sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING ) as sample7 --當前行及後面所有行
from business;

查詢每個顧客上次的購買時間

select name,orderdate,cost,
lag(orderdate,1,'1900-01-01') over(partition by name order by orderdate ) as time1, lag(orderdate,2) over (partition by name order by orderdate) as time2
from business;

查詢前20%時間的訂單信息

select * from (
select name,orderdate,cost, ntile(5) over(order by orderdate) sorted
from business
) t
where sorted = 1;

over函數中的2種組合

select
name,
orderdate,
cost,
sum(cost) over(distribute by name sort by orderdate)
from
business;

select
name,
orderdate,
cost,
sum(cost) over(partition by name order by orderdate)
from
business;

12.7 Rank

函數說明

RANK() 排序相同時會重複,總數不會變 1 1 3 4  
DENSE_RANK() 排序相同時會重複,總數會減少 1 1 2 3  
ROW_NUMBER() 會根據順序計算 1 2 3 4


數據準備

姓名 科目 成績
孫悟空 語文 87
孫悟空 數學 95
孫悟空 英語 68
大海 語文 94
大海 數學 56
大海 英語 84
宋宋 語文 64
宋宋 數學 86
宋宋 英語 84
婷婷 語文 65
婷婷 數學 85
婷婷 英語 78

需求  
計算每門學科成績排名  
創建本地score.txt

vi score.txt

創建hive表

create table score(
name string,
subject string,
score int)
row format delimited fields terminated by "\t";

導入數據

load data local inpath '/home/xuzheng/score.txt' into table score;

按需求查詢數據

select name,
subject,
score,
rank() over(partition by subject order by score desc) rp,
dense_rank() over(partition by subject order by score desc) drp,
row_number() over(partition by subject order by score desc) rmp
from score;

12.8 系統函數

查看系統提供的函數

show functions;

顯示指定函數的用法

desc function upper;

詳細介紹指定函數的具體用法

desc function extended split;

十三、自定義函數UDF

13.1 自定義函數類型

  • UDF函數(user-defined function)

一進一出的函數

  • UDAF函數(user-defined aggregation function)

多進一出的函數,例如count、max、min

  • UDF函數(user-defined table-generating functions)

一進多出的函數,例如later view explore()炸裂函數

13.2 創建項目導入依賴

<dependencies>
	<dependency>
		<groupId>org.apache.hive</groupId>
		<artifactId>hive-exec</artifactId>
		<version>1.2.1</version>
	</dependency>
</dependencies>

13.3 創建一個類繼承與UDF

package com.inspur.hive;

import org.apache.hadoop.hive.ql.exec.UDF;

public class Lower extends UDF {
	public int evaluate(String line) {
		if (line == null) {
		return 0;
		} else {
		return line.length();
		}
	}
	public int evalute(Number line) {  
		if (line == null) {  
			return 0;  
		} else {  
			return line.toString().length();  
		}  
	}

	public int evalute(Boolean line) {  
		if (line == null) {  
			return 0;  
		} else {  
			return line.toString().length();  
		}  
	}  
}

13.4 打成jar包,並上傳集羣

在這裏插入圖片描述

13.5 臨時上傳jar包至hive,退出時失效

add jar /home/lytdev/1.jar;

13.6 創建自定義函數

create function mylen as "com.inspur.hive.Lower";

13.7 測試自定義函數

select ename, mylen(ename) from emp;

十四、壓縮與存儲

14.1 開啓Map輸出階段壓縮

開啓hive中間傳輸數據壓縮功能

hive (default)>set hive.exec.compress.intermediate=true;

開啓mapreduce中map輸出壓縮功能

hive (default)>set mapreduce.map.output.compress=true;

設置mapreduce中map輸出數據的壓縮方式

hive (default)>set mapreduce.map.output.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;

執行查詢語句

hive (default)> select count(ename) name from emp;

14.2 開啓Reduce輸出階段壓縮

開啓hive最終輸出數據壓縮功能

hive (default)>set hive.exec.compress.output=true;

開啓mapreduce最終輸出數據壓縮

hive (default)>set mapreduce.output.fileoutputformat.compress=true;

設置mapreduce最終數據輸出壓縮方式

hive (default)> set mapreduce.output.fileoutputformat.compress.codec =
org.apache.hadoop.io.compress.SnappyCodec;

設置mapreduce最終數據輸出壓縮爲塊壓縮

hive (default)> set mapreduce.output.fileoutputformat.compress.type=BLOCK;

測試一下輸出結果是否是壓縮文件

hive (default)> insert overwrite local directory
'/home/xuzheng/distribute-result' select * from emp distribute by deptno sort by empno desc;

14.3 文件存儲格式

Hive支持的存儲數據的格式主要有:TEXTFILE 、SEQUENCEFILE、ORC、PARQUET

14.4 列式存儲和行式存儲

  • 行存儲的特點

查詢滿足條件的一整行數據的時候,列存儲則需要去每個聚集的字段找到對應的每個列的值,行存儲只需要找到其中一個值,其餘的值都在相鄰地方,所以此時行存儲查詢的速度更快。

  • 列存儲的特點

因爲每個字段的數據聚集存儲,在查詢只需要少數幾個字段的時候,能大大減少讀取的數據量;每個字段的數據類型一定是相同的,列式存儲可以針對性的設計更好的設計壓縮算法。

  • TEXTFILE和SEQUENCEFILE的存儲格式都是基於行存儲的;
  • ORC和PARQUET是基於列式存儲的;
  • ORC常用於MapReduce,PARQUET常用於spark。

14.5 存儲和壓縮結合

創建一個非壓縮的的ORC存儲方式

創建一個orc表

create table log_orc_none(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
row format delimited fields terminated by '\t'
stored as orc tblproperties ("orc.compress"="NONE");

插入數據

insert into table log_orc select * from log_text;

查看錶中數據大小

dfs -du -h /user/hive/warehouse/log_orc/;

創建一個SNAPPY壓縮的ORC存儲方式

創建一個orc表

create table log_orc_snappy(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)
row format delimited fields terminated by '\t'
stored as orc tblproperties ("orc.compress"="SNAPPY");

插入數據

insert into table log_orc_snappy select * from log_text;

查看錶中數據大小

dfs -du -h /user/hive/warehouse/log_orc_snappy/;

**存儲方式和壓縮總結  **

在實際的項目開發當中,hive表的數據存儲格式一般選擇:orc或parquet。壓縮方式一般選擇snappy,lzo

十五、企業級調優

15.1 Fetch抓取

  • Fetch抓取

Hive中對某些情況的查詢可以不必使用MapReduce計算。例如:SELECT * FROM employees;在這種情況下,Hive可以簡單地讀取employee對應的存儲目錄下的文件,然後輸出查詢結果到控制檯。

  • Fetch參數配置
<property>
	<name>hive.fetch.task.conversion</name>
	<value>more</value>
	<description>
	Expects one of [none, minimal, more].
	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 incurs RS), lateral views and joins.
	0. none : disable hive.fetch.task.conversion
	1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only
	2. more : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
	</description>
</property>

案例實操1
把hive.fetch.task.conversion設置成none,然後執行查詢語句,都會執行mapreduce程序

set hive.fetch.task.conversion=none;
select * from emp;
select ename from emp;
select ename from emp limit 3;

案例實操2
把hive.fetch.task.conversion設置成more,然後執行查詢語句,如下查詢方式都不會執行mapreduce程序

set hive.fetch.task.conversion=more;
select * from emp;
select ename from emp;
select ename from emp limit 3;

15.2 本地模式

意義
Hive可以通過本地模式在單臺機器上處理所有的任務。對於小數據集,執行時間可以明顯被縮短
開啓本地模式

# 開啓本地mr
set hive.exec.mode.local.auto=true;
# 設置local mr的最大輸入數據量,當輸入數據量小於這個值時採用local mr的方式,默認爲134217728,即128M
set hive.exec.mode.local.auto.inputbytes.max=50000000;
# 設置local mr的最大輸入文件個數,當輸入文件個數小於這個值時採用local mr的方式,默認爲4
set hive.exec.mode.local.auto.input.files.max=10;

15.3 小表、大表join

新版的hive已經對小表JOIN大表和大表JOIN小表進行了優化。小表放在左邊和右邊已經沒有明顯區別。

15.3.1 需求

測試大表join小表和小表join大表的效率

15.3.2 建大表、小表和join大表的語句

(1)創建大表

create table bigtable(id bigint, time bigint, uid string, keyword string, url_rank int, click_num int, click_url string) row format delimited fields terminated by '\t';

(2)創建小表

create table smalltable(id bigint, time bigint, uid string, keyword string, url_rank int, click_num int, click_url string) row format delimited fields terminated by '\t';

(3)創建join後的表

create table jointable(id bigint, time bigint, uid string, keyword string, url_rank int, click_num int, click_url string) row format delimited fields terminated by '\t';

(4)導入數據

load data local inpath '/home/xuzheng/bigtable' into table bigtable;
load data local inpath '/home/xuzheng/smalltable' into table smalltable;

(5)關閉mapjoin功能(默認是打開的)

set hive.auto.convert.join = false;

(6)執行小表JOIN大表語句

insert overwrite table jointable
select b.id, b.time, b.uid, b.keyword, b.url_rank, b.click_num, b.click_url
from smalltable s
join bigtable b
on b.id = s.id;

(7)執行結果

MapReduce Total cumulative CPU time: 31 seconds 100 msec
No rows affected (52.897 seconds)

(8)執行大表JOIN小表語句

insert overwrite table jointable
select b.id, b.time, b.uid, b.keyword, b.url_rank, b.click_num, b.click_url
from bigtable b
join smalltable s
on s.id = b.id;

(9)執行結果

MapReduce Total cumulative CPU time: 29 seconds 790 msec
No rows affected (50.443 seconds)

(10)注意
大表放在左邊 left join 小表,可以走mapjoin進行優化;
如果使用 join,也就是inner join 大表小表的左右順序無所謂,都會進行優化

15.4 大表和大表join

15.4.1 空key過濾

進行空值過濾時,放在子查詢中

insert overwrite table jointable select n.* from (select * from nullidtable where id is not null ) n left join ori o on n.id = o.id;

15.4.2 空key替換

有時雖然某個key爲空對應的數據很多,但是相應的數據不是異常數據,必須要包含在join的結果中,此時我們可以表a中key爲空的字段賦一個隨機的值,使得數據隨機均勻地分不到不同的reducer上,避免數據傾斜,數據傾斜會導致MapTask或者ReduceTask執行不了,從而導致整個MR任務執行不了。

insert overwrite table jointable
select n.* from nullidtable n full join ori o on
case when n.id is null then concat('hive', rand()) else n.id end = o.id;

15.5 開啓mapjoin參數配置

  • 設置自動選擇Mapjoin
set hive.auto.convert.join = true; #默認爲true

  • 大表小表的閾值設置(默認25M一下認爲是小表)
set hive.mapjoin.smalltable.filesize=25000000

當服務器內容256GB時,可以增大該參數配置

15.6 group by

默認情況下,Map階段同一Key數據分發給一個reduce,當一個key數據過大時就傾斜了。並不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端進行部分聚合,最後在Reduce端得出最終結果。

  • 是否在Map端進行聚合,默認爲True
set hive.map.aggr = true

  • 在Map端進行聚合操作的條目數目
set hive.groupby.mapaggr.checkinterval = 100000

  • 有數據傾斜的時候進行負載均衡(默認是false)
set hive.groupby.skewindata = true

15.7 Count(Distinct) 去重統計

數據量小的時候無所謂,數據量大的情況下,由於COUNT DISTINCT的全聚合操作,即使設定了reduce task個數,set mapred.reduce.tasks=100;hive也只會啓動一個reducer。這就造成一個Reduce處理的數據量太大,導致整個Job很難完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替換:

# count(distinct)方式
select count(distinct id) from bigtable;
# group by方式,必須先設置reduce數量,否則也是默認一個reduce
set mapreduce.job.reduces = 5;
select count(id) from (select id from bigtable group by id) a;

15.8 MR優化

  • 合理設置Map數
set hive.map.aggr = true

  • 開啓小文件合併
# CombineHiveInputFormat具有對小文件進行合併的功能
set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
# 在map-only任務結束時合併小文件,默認true
set hive.merge.mapfiles = true;
# 在map-reduce任務結束時合併小文件,默認false
set hive.merge.mapredfiles = true;
# 合併文件的大小,默認256M
set hive.merge.size.per.task = 268435456;
# 當輸出文件的平均大小小於該值時,啓動一個獨立的map-reduce任務進行文件merge
set hive.merge.smallfiles.avgsize = 16777216;

  • 合理設置Reduce數
# 調整reduce個數方法一
# 每個Reduce處理的數據量默認是256MB
hive.exec.reducers.bytes.per.reducer=256000000
# 每個任務最大的reduce數,默認爲1009
hive.exec.reducers.max=1009
# 計算reducer數的公式
N=min(參數2,總輸入數據量/參數1)
# 調整reduce個數方法二
# 在hadoop的mapred-default.xml文件中修改,設置每個job的Reduce個數
set mapreduce.job.reduces = 15;

15.9 開啓並行執行

  • 設置任務並行度
# 打開任務並行執行
set hive.exec.parallel=true;
# 同一個sql允許最大並行度,默認爲8。
set hive.exec.parallel.thread.number=16;

15.10 JVM重用

JVM重用是Hadoop調優參數的內容,其對Hive的性能具有非常大的影響,特別是對於很難避免小文件的場景或task特別多的場景,這類場景大多數執行時間都很短

<property>
	<name>mapreduce.job.jvm.numtasks</name>
	<value>10</value>
	<description>How many tasks to run per jvm. If set to -1, there is
	no limit.
	</description>
</property>

15.11 推測執行

在分佈式集羣環境下,因爲程序Bug(包括Hadoop本身的bug),負載不均衡或者資源分佈不均等原因,會造成同一個作業的多個任務之間運行速度不一致,有些任務的運行速度可能明顯慢於其他任務(比如一個作業的某個任務進度只有50%,而其他所有任務已經運行完畢),則這些任務會拖慢作業的整體執行進度。爲了避免這種情況發生,Hadoop採用了推測執行(Speculative Execution)機制,它根據一定的法則推測出“拖後腿”的任務,併爲這樣的任務啓動一個備份任務,讓該任務與原始任務同時處理同一份數據,並最終選用最先成功運行完成任務的計算結果作爲最終結果。

<property>
	<name>mapreduce.map.speculative</name>
	<value>true</value>
</property>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章