spark oom(out of memory)问题

https://blog.csdn.net/yhb315279058/article/details/51035631

https://www.cnblogs.com/yanshw/p/11988347.html

1 driver内存不够

增加 Driver 内存

1
--driver-memory MEM         Memory for driver (e.g. 1000M, 2G) (Default: 1024M). 

1 读入数据太大

解决思路是增加 Driver 内存

1
2
3
4
5
from pyspark import SparkContext
sc = SparkContext(master='yarn')
rdd = sc.parallelize(range(300000000))
# spark-submit --master yarn-client --driver-memory 512M driver_oom.py 内存溢出
# spark-submit --master yarn-client --driver-memory 3G driver_oom.py 可以执行

2 数据回传太大,也就是聚合到driver的数据太大

解决思路是分区输出,具体做法是 foreach

1
2
3
4
5
rdd = sc.parallelize(range(100))
rdd.flatMap(lambda x: ['%d'%x*50 for _ in range(100000)]).collect() # 内存溢出

def func(x): print(x)
rdd.flatMap(lambda x: ['%d'%x*50 for _ in range(100000)]).foreach(func) # 分区输出

2 excutor内存不够

通用的解决办法就是增加 Executor 内存 但这并不一定是最好的办法

1 map 过程产生大量对象

解决思路是减少每个 task 的大小,从而减少每个 task 的输出

具体做法是在 会产生大量对象的 map 操作前 添加 repartition(重新分区) 方法,分区成更小的块传入 map

1
2
3
4
rdd.flatMap(lambda x: ['%d'%x*50 for _ in range(100000000)]).count()      # 100 * 100000000 个对象,内存溢出
rdd.flatMap(lambda x: len(['%d'%x*50 for _ in range(100000000)])).sum() # 内存溢出

rdd.repartition(1000000).flatMap(lambda x: ['%d'%x*50 for _ in range(100000000)]).count()

2 shuffle导致

shuffle内存溢出的情况可以说都是shuffle后发生数据倾斜,单个文件过大导致

参考数据倾斜解决方案

电商业务

1 SPU,SKU

SPU(Standard Product Unit):是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息集合。

SKU = Stock Keeping Unit(库存量基本单位)。现在已经被引申为产品统一编号的简称,每种产品均对应有唯一的SKU号。

例如:iPhoneX手机就是SPU。一台银色、128G内存的、支持联通网络的iPhoneX,就是SKU。

hql常见操作

1 with…as…

https://www.jianshu.com/p/d518e9f5d5f9

1 好处

​ a. 提高代码可读性

​ 结构清晰

​ b. 优化执行速度

​ 子查询结果存在内存中,不需要重复计算

2 用法

1
with table_name as(子查询语句) 其他sql;
1
2
3
4
with temp as (
select * from xxx
)
select * from temp;

2 视图

与基本表不同,它是一个虚表。在数据库中,存放的只是视图的定义,而不存放视图包含的数据项,这些项目仍然存放在原来的基本表结构中。

视图是只读的,不能向视图中插入或加载或改变数据

作用:

1 便捷

通过引入视图机制,用户可以将注意力集中在其关心的数据上(而非全部数据),这样就大大提高了用户效率与用户满意度,而且如果这些数据来源于多个基本表结构,或者数据不仅来自于基本表结构,还有一部分数据来源于其他视图,并且搜索条件又比较复杂时,需要编写的查询语句就会比较烦琐,此时定义视图就可以使数据的查询语句变得简单可行。

2 安全

定义视图可以将表与表之间的复杂的操作连接和搜索条件对用户不可见,用户只需要简单地对一个视图进行查询即可,故增加了数据的安全性,但不能提高查询效率。

创建

1
2
3
4
5
6
7
8
CREATE VIEW [IF NOT EXISTS] view_name [(column_name [COMMENT column_comment], ...) ]
[COMMENT table_comment]
AS SELECT ...

hive> CREATE VIEW emp_30000 AS
> SELECT * FROM employee
> WHERE salary>30000;

删除

1
DROP VIEW view_name

函数

1 系统函数

https://www.studytime.xin/article/hive-knowledge-function.html

1 get_json_object

https://blog.csdn.net/weixin_43412569/article/details/105290637

2 nvl

空值判断转换函数

https://blog.csdn.net/a850661962/article/details/101209028

3 coalesce

https://blog.csdn.net/yilulvxing/article/details/86595725

1
select coalesce(success_cnt,period,1) from tableA

当success_cnt不为null,那么无论period是否为null,都将返回success_cnt的真实值(因为success_cnt是第一个参数),当success_cnt为null,而period不为null的时候,返回period的真实值。只有当success_cnt和period均为null的时候,将返回1。

4 collect_list和collect_set

https://blog.csdn.net/weixin_30230059/article/details/113324945

https://blog.csdn.net/qq_44104303/article/details/117551807

它们都是将分组中的某列转为一个数组返回,不同的是collect_list不去重而collect_set去重。

5 named_struct

https://blog.csdn.net/weixin_43597208/article/details/117554838

做字段拼接

区别于struct,struct 是集合数据类型,一般用于建表,named_struct是字段拼接函数,一般用于查询

6 array_contains()

1
array_contains(array,值)

判断array中是否包含某个值,包含返回true,不包含返回false

7 cast

https://www.jianshu.com/p/999176fa2730

显式的将一个类型的数据转换成另一个数据类型

1
Cast(字段名 as 转换的类型 )

2 用户自定义函数

UDF(User-Defined-Function):单入单出
UDTF(User-Defined Table-Generating Functions):单入多出
UDAF(User Defined Aggregation Function):多入单出
https://blog.csdn.net/qq_40579464/article/details/105903405

1.编写代码

jar不能随意编写,需要和hive对齐接口,可以借助工具import org.apache.hadoop.hive.ql.exec.UDF;

1
2
1 public class classname extends UDF
2 编写evalute

https://blog.csdn.net/eyeofeagle/article/details/83904147

2.打包
3.导入hive
复制到hdfs上
Hive安装目录的lib目录下
4.创建关联
add jar hdfs://localhost:9000/user/root/hiveudf.jar
create temporary function my_lower as ‘com.example.hive.udf.LowerCase’;
5.使用

hql udf的使用和普通内置函数一样,比如有udf1

1
select udf1(col1) from table1

加载数据

https://www.cnblogs.com/bjlhx/p/6946422.html

https://blog.csdn.net/m0_49092046/article/details/109251015

1 load

1
load data [local] inpath ‘/opt/module/datas/student.txt’ [overwrite] | into table tabName [partition (partcol1=val1,…)];

(1)load data:表示加载数据
(2)local:表示从本地加载数据到 hive 表;否则从 HDFS 加载数据到 hive 表
(3)inpath:表示加载数据的路径
(4)overwrite:表示覆盖表中已有数据,否则表示追加
(5)into table:表示加载到哪张表
(6)tabName:表示具体的表
(7)partition:表示上传到指定分区

例子:

1
load data inpath '/origin_data/gmall/log/topic_log/2020-06-14' into table ods_log partition(dt='2020-06-14')

2 INSERT

https://help.aliyun.com/document_detail/73775.html

insert into 和insert overwrite

1
2
3
4
5
6
1
insert into table student partition(month='20201022') values(1,'zhangsan');
2
insert overwrite table student partition(month='20201023')
select id, name from student where month='20201023';

建表

https://www.jianshu.com/p/4f60f3c923fe

0 CREATE TABLE

https://blog.csdn.net/Thomson617/article/details/86153924

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CREATE EXTERNAL TABLE dim_sku_info (
`id` STRING COMMENT '商品id',
`price` DECIMAL(16,2) COMMENT '商品价格',
`sku_name` STRING COMMENT '商品名称',
`sku_desc` STRING COMMENT '商品描述',
`weight` DECIMAL(16,2) COMMENT '重量',
`is_sale` BOOLEAN COMMENT '是否在售',
`spu_id` STRING COMMENT 'spu编号',
`spu_name` STRING COMMENT 'spu名称',
`category3_id` STRING COMMENT '三级分类id',
`category3_name` STRING COMMENT '三级分类名称',
`category2_id` STRING COMMENT '二级分类id',
`category2_name` STRING COMMENT '二级分类名称',
`category1_id` STRING COMMENT '一级分类id',
`category1_name` STRING COMMENT '一级分类名称',
`tm_id` STRING COMMENT '品牌id',
`tm_name` STRING COMMENT '品牌名称',
`sku_attr_values` ARRAY<STRUCT<attr_id:STRING,value_id:STRING,attr_name:STRING,value_name:STRING>> COMMENT '平台属性',
`sku_sale_attr_values` ARRAY<STRUCT<sale_attr_id:STRING,sale_attr_value_id:STRING,sale_attr_name:STRING,sale_attr_value_name:STRING>> COMMENT '销售属性',
`create_time` STRING COMMENT '创建时间'
) COMMENT '商品维度表'

1 EXTERNAL

关键字可以让用户创建一个外部表,默认是内部表

2 字段的数据类型

https://blog.csdn.net/weixin_46941961/article/details/108551512

https://blog.csdn.net/weixin_43215250/article/details/90034169

集合数据类型:Array、Map和Struct

1.分区

https://www.jianshu.com/p/5dbbaea8ff41

PARTITIONED BY (dt string)

0 分类

静态分区SP(static partition)
动态分区DP(dynamic partition)

静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。

1 静态分区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
--建表
DROP TABLE IF EXISTS dwd_display_log;
CREATE EXTERNAL TABLE dwd_display_log(
`area_code` STRING COMMENT '地区编码',
`brand` STRING COMMENT '手机品牌',
`channel` STRING COMMENT '渠道',
`is_new` STRING COMMENT '是否首次启动',
`model` STRING COMMENT '手机型号',
`mid_id` STRING COMMENT '设备id',
`os` STRING COMMENT '操作系统',
`user_id` STRING COMMENT '会员id',
`version_code` STRING COMMENT 'app版本号',
`during_time` BIGINT COMMENT 'app版本号',
`page_item` STRING COMMENT '目标id ',
`page_item_type` STRING COMMENT '目标类型',
`last_page_id` STRING COMMENT '上页类型',
`page_id` STRING COMMENT '页面ID ',
`source_type` STRING COMMENT '来源类型',
`ts` BIGINT COMMENT 'app版本号',
`display_type` STRING COMMENT '曝光类型',
`item` STRING COMMENT '曝光对象id ',
`item_type` STRING COMMENT 'app版本号',
`order` BIGINT COMMENT '曝光顺序',
`pos_id` BIGINT COMMENT '曝光位置'
) COMMENT '曝光日志表'
PARTITIONED BY (`dt` STRING)
STORED AS PARQUET
LOCATION '/warehouse/gmall/dwd/dwd_display_log'
TBLPROPERTIES('parquet.compression'='lzo');
--加载数据
insert overwrite table dwd_display_log partition(dt='2020-06-14')
select
get_json_object(line,'$.common.ar'),
get_json_object(line,'$.common.ba'),
get_json_object(line,'$.common.ch'),
get_json_object(line,'$.common.is_new'),
get_json_object(line,'$.common.md'),
get_json_object(line,'$.common.mid'),
get_json_object(line,'$.common.os'),
get_json_object(line,'$.common.uid'),
get_json_object(line,'$.common.vc'),
get_json_object(line,'$.page.during_time'),
get_json_object(line,'$.page.item'),
get_json_object(line,'$.page.item_type'),
get_json_object(line,'$.page.last_page_id'),
get_json_object(line,'$.page.page_id'),
get_json_object(line,'$.page.source_type'),
get_json_object(line,'$.ts'),
get_json_object(display,'$.display_type'),
get_json_object(display,'$.item'),
get_json_object(display,'$.item_type'),
get_json_object(display,'$.order'),
get_json_object(display,'$.pos_id')
from ods_log lateral view explode_json_array(get_json_object(line,'$.displays')) tmp as display
where dt='2020-06-14'
and get_json_object(line,'$.displays') is not null;

2 动态分区

注意分区字段dt数据来源于date_format(create_time,’yyyy-MM-dd’)

和静态分区比较,建表的时候没区别,加载数据有区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
--建表
DROP TABLE IF EXISTS dwd_comment_info;
CREATE EXTERNAL TABLE dwd_comment_info(
`id` STRING COMMENT '编号',
`user_id` STRING COMMENT '用户ID',
`sku_id` STRING COMMENT '商品sku',
`spu_id` STRING COMMENT '商品spu',
`order_id` STRING COMMENT '订单ID',
`appraise` STRING COMMENT '评价(好评、中评、差评、默认评价)',
`create_time` STRING COMMENT '评价时间'
) COMMENT '评价事实表'
PARTITIONED BY (`dt` STRING)
STORED AS PARQUET
LOCATION '/warehouse/gmall/dwd/dwd_comment_info/'
TBLPROPERTIES ("parquet.compression"="lzo");
--加载数据
insert overwrite table dwd_comment_info partition (dt)
select
id,
user_id,
sku_id,
spu_id,
order_id,
appraise,
create_time,
date_format(create_time,'yyyy-MM-dd')
from ods_comment_info
where dt='2020-0

2 LOCATION

LOCATION ‘/warehouse/gmall/ods/ods_log’

指定数据在hdfs上的存储位置

3 ROW FORMAT

https://www.imooc.com/article/12213

https://blog.csdn.net/S_Running_snail/article/details/84258162

指定数据切分格式

ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’

4 STORED AS

https://blog.csdn.net/ZZQHELLO2018/article/details/106175887

指定存储方式

行式存储:TEXTFILE 、SEQUENCEFILE 列式存储: ORC、PARQUET

5 TBLPROPERTIES

https://blog.csdn.net/yangguosb/article/details/83651073

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-CreateTableCreate/Drop/TruncateTable

TBLPROPERTIES是表的一些属性,HIVE内置了一部分属性,使用者也可以在创建表时进行自定义;

TBLPROPERTIES (“parquet.compression”=”lzo”);

sql增删改查

https://blog.csdn.net/Zhangxichao100/article/details/55099118

1 增

1 insert

insert into table (姓名,性别,出生日期) values (‘王伟华’,’男’,’1983/6/15’)

insert into table (‘姓名’,’地址’,’电子邮件’)select name,address,email from Strdents

2 SELECT INTO

1
2
3
SELECT column_name
INTO newtable
FROM table1;

2 删

1 delete

删除数据某些数据

delete from table where name=’王伟华’

2 truncate

删除整个表的数据

truncate table addressList

3 改

1 update

update table set 年龄=18 where 姓名=’王伟华’

4 查

1 select

数仓主题和主题域

https://blog.csdn.net/qq_22473611/article/details/116702667

1 主题域、主题、实体的关系

主题域下面可以有多个主题,主题还可以划分成更多的子主题,主题和主题之间的建设可能会有交叉现象,而实体则是不可划分的最小单位

2 主题域划分

1 按照业务系统划分

2 按照业务过程划分

3 按照部门划分


:D 一言句子获取中...