文章目录

  • 一 下载源码
  • 二 自定义函数
  • 2.1 添加随机数前缀函数
  • 2.2 移除前缀函数
  • 2.3 注册函数
  • 三 编译
  • 四 结果
  • 五 测试函数
  • 六 解决数据倾斜问题
  • 6.1 先把uid打散
  • 6.2 第一次聚合
  • 6.3 移除随机数
  • 6.4 第二次聚合


下图是hive-exec模块的编译结果

hive 分组随机选取 hive rand生成随机数_hive编译

因为我们刚刚添加的函数在hive-exec模块下添加自定义函数的,也可以把hive-exec-1.1.0-cdh5.15.1.jar直接上传部署好hive的lib目录下面

hive 分组随机选取 hive rand生成随机数_数据倾斜_02

五 测试函数

查看函数

show functions;

可以看到我们自己定义的两个函数了,如下图

hive 分组随机选取 hive rand生成随机数_自定义函数_03


hive 分组随机选取 hive rand生成随机数_UDF_04


我们看下函数的详细描述,看看文档是不是我们刚刚写的

desc function extended add_random_prefix;

如下图,这些不就是我们刚刚自定义函数写的说明么

hive 分组随机选取 hive rand生成随机数_UDF_05


我们来使用一下这个函数:

select add_random_prefix('hive',10);

自动给我们加上随机数了

hive 分组随机选取 hive rand生成随机数_自定义函数_06


我们再测试一下移除随机数

select remove_random_prefix('9_hive');

hive 分组随机选取 hive rand生成随机数_数据倾斜_07


到这里,说明我们的自定义的函数没有问题

六 解决数据倾斜问题

数据倾斜一般发生在聚合计算的时候,由于相同的key过多导致的,导致有一个task可能会计算的很慢,导致整个job的时间很长

uid

pid

user1

product1

user2

product3

user3

product1

user3

product1

user3

product1

user3

product1

user3

product2

user3

product3

user3

product11

user3

product12

user3

product11

user3

product1

user3

product2

user3

product13

user3

product1

user3

product1

user3

product1

user3

product1

1.上面这个数据,是每个用户购买的产品,现在我们要计算每个用户总共购买了多少产品;
2.从上面的数据可以看出user3用户比较多,如果数量再扩大几十万倍,进行聚合的时候会发生数据倾斜的问题了,那么我们可以用上面两个自定义的函数解决数据倾斜问题

6.1 先把uid打散

打散的意思就是在uid字段的值前面加上随机数

select add_random_prefix(uid,5) as rdm_uid from user_pid;

hive 分组随机选取 hive rand生成随机数_数据倾斜_08

6.2 第一次聚合

把上面一次查询的结果作为临时表,对打散后的uid进行第一次聚合

select rdm_uid, count(1) as cnt from
	(select add_random_prefix(uid,5) as rdm_uid from user_pid) a
group by rdm_uid;

hive 分组随机选取 hive rand生成随机数_hive 分组随机选取_09

6.3 移除随机数

现在可以用移除随机数的函数,把上面的结果uid前面的随机数进行移除

select remove_random_prefix(rdm_uid) as uid, cnt from
	(select rdm_uid, count(1) as cnt from
	(select add_random_prefix(uid,5) as rdm_uid from user_pid) a
group by rdm_uid) b;

hive 分组随机选取 hive rand生成随机数_hive编译_10

6.4 第二次聚合

把上面的结果作为临时表,把uid作为分组条件,对cnt进行求和,就可以得到我们的结果

select uid, sum(cnt) as total_cnt from
	(select remove_random_prefix(rdm_uid) as uid, cnt from
	(select rdm_uid, count(1) as cnt from
	(select add_random_prefix(uid,5) as rdm_uid from user_pid) a
	group by rdm_uid) b) c
group by uid;

hive 分组随机选取 hive rand生成随机数_自定义函数_11


到此数据倾斜解决