-- 表结构
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