--
表结构
create table
t_wordcount
(
line string
)
row
format delimited
lines terminated by
'\n'
;
--
加载数据
load data
inpath
'/yjx/harry.txt'
into table
t_wordcount;
--
处理方案
select
regexp_replace
(
line,
"\[\^0-9a-zA-Z\`\'\\-\\s\]"
,
""
)
from
t_wordcount;
select
split
(
regexp_replace
(
line,
"\[\^0-9a-zA-Z\`\'\\-\\s\]"
,
""
)
,
"\\s+"
)
from
t_wordcount;
select
explode
(
split
(
regexp_replace
(
line,
"\[\^0-9a-zA-Z\`\'\\-
\\s\]"
,
""
)
,
"\\s+"
))
word
from
t_wordcount;
select
word,
count
(
word
)
from
t_wordcount, lateral
view
explode
(
split
(
regexp_replace
(
line,
"\[\^0-9a-zA-Z\`\'\\-\\s\]"
,
""
)
,
"\\s+"
))
wordtable
as
word
group by
word;
4.2 天气系统
4.2.1 指标
每个市每天的最高温度和最低温度和平均温度
每天每个省最热的城市是那一个?
查询出每个省份每个月最高的三个温度和日期 ,最低的三个温度和日期?
综合每月数据查询出那个城市的 上报日期与创建日期
延迟最高?
查询出
7
月份全国晴天最多的省份
4.2.2 样例数据
1199,
广东
,
广州市
,440100,
多云
,25,
西南
,≤3,97,3/6/2020 01:52:18,3/6/2020 02:00:01
1207,
广东
,
南沙区
,440115,
多云
,25,
北
,≤3,97,3/6/2020 02:52:19,3/6/2020 03:00:01
1212,
北京
,
海淀区
,110108,
晴
,20,
北
,≤3,60,3/6/2020 02:56:18,3/6/2020 03:00:01
1225,
广东
,
天河区
,440106,
阴
,25,
东
,≤3,97,3/6/2020 02:52:19,3/6/2020 03:00:01
1229,
广东
,
广州市
,440100,
阴
,25,
东
,≤3,97,3/6/2020 02:52:18,3/6/2020 03:00:01
1237,
广东
,
南沙区
,440115,
多云
,25,
东
,≤3,99,3/6/2020 03:52:18,3/6/2020 04:00:01
1247,
广东
,
南海区
,440605,
阴
,25,
东南
,≤3,92,3/6/2020 03:52:11,3/6/2020 04:00:01
1257,
广东
,
越秀区
,440104,
阴
,25,
北
,≤3,97,3/6/2020 03:52:19,3/6/2020 04:00:01
1260,
北京
,
密云区
,110118,
晴
,17,
东
,≤3,83,3/6/2020 03:56:15,3/6/2020 04:00:01
1273,
上海
,
闵行区
,310112,
雨
,25,
南
,≤3,94,3/6/2020 04:53:46,3/6/2020 05:00:01
1274,
上海
,
青浦区
,310118,
雨
,25,
南
,≤3,94,3/6/2020 04:53:46,3/6/2020 05:00:01
1281,
北京
,
顺义区
,110113,
晴
,18,
东北
,≤3,79,3/6/2020 04:56:16,3/6/2020 05:00:01
1293,
北京
,
东城区
,110101,
晴
,19,
东
,≤3,76,3/6/2020 05:56:20,3/6/2020 06:00:15
4.2.3 处理方案
--
创建表
create table
t_weather
(
id
int
,
province string,
city string,
adcode
int
,
weather string,
temperature
int
,
winddirection string,
windpower string,
humidity
int
,
reporttime string,
createtime string
)
row
format delimited
fields terminated by
','
lines terminated by
'\n'
;
--
载入数据
load data
inpath
'/yjx/weather.txt'
into table
t_weather;
--
解决方案 每个市每天的最高温度和最低温度和平均温度
select
*
from
t_weather
limit
0
,
10
;
select
UNIX_TIMESTAMP
(
reporttime,
'dd/MM/yyyy HH:mm:ss'
)
from
t_weather
limit
0
,
10
;
select
from_unixtime
(
UNIX_TIMESTAMP
(
reporttime,
'dd/MM/yyyy
HH:mm:ss'
)
,
'yyyyMMdd'
)
from
t_weather
limit
0
,
10
;
select
adcode , from_unixtime
(
UNIX_TIMESTAMP
(
reporttime,
'dd/MM/yyyy
HH:mm:ss'
)
,
'yyyyMMdd'
)
,
max
(
temperature
)
,
min
(
temperature
)
,
avg
(
temperature
)
from
t_weather
group by
adcode , from_unixtime
(
UNIX_TIMESTAMP
(
reporttime,
'dd/MM/yyyy
HH:mm:ss'
)
,
'yyyyMMdd'
)
;
--
解决方案 每天每个省最热的城市是那一个?
select
province,city,from_unixtime
(
UNIX_TIMESTAMP
(
reporttime,
'dd/MM/yyyy
HH:mm:ss'
)
,
'yyyyMMdd'
)
ymd,temperature,
max
(
temperature
)
over
(
partition by
province,from_unixtime
(
UNIX_TIMESTAMP
(
reporttime,
'dd/MM/yyyy
HH:mm:ss'
)
,
'yyyyMMdd'
)
order by
temperature
)
mt
from
t_weather ;
select
province,city,ymd,temperature
from
(
select
province,city,from_unixtime
(
UNIX_TIMESTAMP
(
reporttime,
'dd/MM/yyyy
HH:mm:ss'
)
,
'yyyyMMdd'
)
ymd,temperature,row_number
()
over
(
partition by
province,from_unixtime
(
UNIX_TIMESTAMP
(
reporttime,
'dd/MM/yyyy
HH:mm:ss'
)
,
'yyyyMMdd'
)
order by
temperature
desc
)
rn
from
t_weather
)
hottable
where
hottable
.rn
<=
1
;
六、数据倾斜
6.1 定义
数据倾斜,即单个节点任务所处理的数据量远大于同类型任务所处理的数据量,导致该节点成为整
个作业的瓶颈,这是分布式系统不可能避免的问题。
从本质来说,导致数据倾斜有两种原因:
一是任务读取大文件,最常见的就是读取压缩的不可分割的大文件。
二是任务需要处理大量相同键的数据。
set
mapred
.reduce.tasks
=
3
;
set
mapred
.reduce.tasks
;
0-hive.fetch.task.conversion=more;
将
hive
拉取的模式设置为
more
模式
1-hive.exec.mode.local.auto
决定
Hive
是否应该自动地根据输入文件大小,在本地运行(在
GateWay
运行)
;
2-hive.auto.convert.join
:是否根据输入小表的大小,自动将
Reduce
端的
Common Join
转化为
Map Join
,从而加快大表关联小表的
Join
速度。 默认:
false
。
3-mapred.reduce.tasks
:所提交
Job
的
reduer
的个数,使用
Hadoop Client
的配置。 默认
是
-1
,表示
Job
执行的个数交由
Hive
来分配;
mapred.map.tasks:
设置提交
Job
的
map
端个数;
4-hive.map.aggr=true
开启
map
端聚合;
hive.groupby.skewindata=true
:决定
group by
操作是否支持倾斜的数据。
原理是,在
Group by
中,对一些比较小的分区进行合并,默认是
false
;
5-hive.merge.mapredfiles
:是否开启合并
Map/Reduce
小文件,对于
Hadoop 0.20
以前的版
本,起一首新的
Map/Reduce Job
,对于
0.20
以后的版本,则是起使用
CombineInputFormat
的
MapOnly Job
。 默认是:
false
;
6-hive.mapred.mode
:
Map/Redure
模式,如果设置为
strict
,将不允许笛卡尔积。 默认
是:
'nonstrict'
;
7-hive.exec.parallel
:是否开启
map/reduce job
的并发提交。
默认
Map/Reduce job
是顺序执行的,默认并发数量是
8
,可以配置。默认是:
false
;
8-hive.exec.dynamic.partition =true
:是否打开动态分区。 需要打开,默认:
false
;
set hive.exec.dynamic.partition.mode=nonstirct
数据含有大量无意义的数据,例如空值
(NULL)
、空字符串等
含有倾斜数据在进行聚合计算时无法聚合中间结果,大量数据都需要经过
Shuffle
阶段的
处理,引起数据倾斜。
数据在计算时做多维数据集合,导致维度膨胀引起的数据倾斜。
两表进行
Join
,都含有大量相同的倾斜数据键。
6.2.
原因
当集群的数据量增长到一定规模,有些数据需要归档或者转储,这时候往往会对数据进行压缩
;
当对文件使用
GZIP
压缩等不支持文件分割操作的压缩方式,在日后有作业涉及读取压缩后的文件
时,该压缩文件只会被一个任务所读取。
如果该压缩文件很大,则处理该文件的
Map
需要花费的时间会远多于读取普通文件的
Map
时间,该
Map
任务会成为作业运行的瓶颈。
七、Hive企业级优化
Hive
优化的核心思想:把
Hive SQL
当做
Mapreduce
程序去优化。
7.1. Fetch
我们之前是不是说过
select * from
表;这样的
sql
语句是不会产生
MR
任务的,这涉及到一个
fetch
(抓取)的概念。
hive-default.xml.template hive.fetch.task.conversion-->
默认
more
如果
none
那么每次执行
select * from
都是执行
MapReduce
7.2.
本地模式
hive.exec.mode.local.auto=true
7.3.
并行执行
set hive.exec.parallel=true; //
打开任务并行执行
set hive.exec.parallel.thread.number=16; //
同一个
sql
允许最大并行度
7.4.
严格模式
开启严格模式需要修改
hive.mapred.mode
值为
strict
,开启严格模式可以禁止
3
种类型的查询。
防止用户执行低效率的
SQL
查询
对于分区表,除非
where
语句中含有分区字段过滤条件来限制范围,否则不允许执行
对于使用了
order by
语句的查询,要求必须使用
limit
语句
限制笛卡尔积的查询。
7.5. JVM
重用
JVM
重用可以使得
JVM
实例在同一个
job
中重新使用
N
次。
N
的值可以在
Hadoop
的
mapred-site.xml
文件中进行配置。
通常在
10-20
之间,具体多少需要根据具体业务场景测试得出。
很难避免小文件的场景或
task
特别多的场景,这类场景大多数执行时间都很短
7.6.
表的优化(小表与大表)
Hive
默认第一个
(
左面的
)
表是小表,然后将其存放到内存中,然后去与第二张表进行比较
现在优化后小表前后无所谓
7.7.
表的优化(大表与大表)
针对于空值,可以将空值随机设置一个不影响结果的值
将来
reduce
的时候可以分区到不同的
reduce
,减少压力
7.8. mapside
聚合
默认情况下,
Map
阶段同一
Key
数据分发给一个
reduce
,当一个
key
数据过大时就倾斜了。
并不是所有的聚合操作都需要在
Reduce
端完成,很多聚合操作都可以先在
Map
端进行部分聚合,
最后在
Reduce
端得出最终结果。
开启
Map
端聚合参数设置
是否在
Map
端进行聚合,默认为
True
hive.map.aggr = true
在
Map
端进行聚合操作的条目数目
hive.groupby.mapaggr.checkinterval = 100000
有数据倾斜的时候进行负载均衡(默认是
false
)
hive.groupby.skewindata = true
当选项设定为
true
,生成的查询计划会有两个
MR Job
。
分两次进行
mapredue,
第一次随机分获取中间结果
,
第二次正常分,获取最终结果
7.9. Count(Distinct)
防止所有的数据都分到一个
Reduce
上面
首先使用
Group By
对数据进行分组,然后在统计
7.10.
防止笛卡尔积
行列过滤
(
列裁剪
)
当表关联的时候,优先使用子查询对表的数据进行过滤
,
这样前面表关联数据就是少的,减少关联的次数
工作上经常用到的
hivesql
小技巧
多表关联时要多用
union all ,
多表
union all
会优化成一个
job
。
修改表结构要用
REPLACE COLUMNS
。使用
add colmns
数据为空,这时因为元数据库没有更
新
注意
Hive
中
NULL
和
’ ‘
的区别,不管哪一种做相加的时候都会变成
null
去列参数
set hive.support.quoted.identifiers=none;
(membership_level|extra_info)?+.+
查询切记加
limit