85.Spark大型电商项目-用户访问session分析-数据倾斜解决方案之使用随机key实现双重聚合

目录

使用随机key实现双重聚合

图解

代码


本篇文章记录用户访问session分析-数据倾斜解决方案之使用随机key实现双重聚合。

使用随机key实现双重聚合

1、原理

第一次聚合(局部聚合):对每一个Key值加上一个随机数,执行第一次reduceByKey聚合操作。

 第二次聚合(双重聚合):去掉Key值的前缀随机数,执行第二次reduceByKey聚合,最终得到全局聚合的结果。

2、使用场景
(1)groupByKey
(2)reduceByKey

比较适合使用这种方式;join,咱们通常不会这样来做,后面会讲三种,针对不同的join造成的数据倾斜的问题的解决方案。

第一轮聚合的时候,对key进行打散,将原先一样的key,变成不一样的key,相当于是将每个key分为多组;

先针对多个组,进行key的局部聚合;接着,再去除掉每个key的前缀,然后对所有的key,进行全局的聚合。

对groupByKey、reduceByKey造成的数据倾斜,有比较好的效果。

如果说,之前的第一、第二、第三种方案,都没法解决数据倾斜的问题,那么就只能依靠这一种方式了。

图解

代码

		/**
		 * 第一步,给每个key打上一个随机数
		 */
		JavaPairRDD<String, Long> mappedClickCategoryIdRDD = clickCategoryIdRDD.mapToPair(

				new PairFunction<Tuple2<Long,Long>, String, Long>() {

					private static final long serialVersionUID = 1L;

					@Override
					public Tuple2<String, Long> call(Tuple2<Long, Long> tuple)
							throws Exception {
						Random random = new Random();
						int prefix = random.nextInt(10);
						return new Tuple2<String, Long>(prefix + "_" + tuple._1, tuple._2);
					}

				});

		/**
		 * 第二步,执行第一轮局部聚合
		 */
		JavaPairRDD<String, Long> firstAggrRDD = mappedClickCategoryIdRDD.reduceByKey(

				new Function2<Long, Long, Long>() {

					private static final long serialVersionUID = 1L;

					@Override
					public Long call(Long v1, Long v2) throws Exception {
						return v1 + v2;
					}

				});

		/**
		 * 第三步,去除掉每个key的前缀
		 */
		JavaPairRDD<Long, Long> restoredRDD = firstAggrRDD.mapToPair(

				new PairFunction<Tuple2<String,Long>, Long, Long>() {

					private static final long serialVersionUID = 1L;

					@Override
					public Tuple2<Long, Long> call(Tuple2<String, Long> tuple)
							throws Exception {
						long categoryId = Long.valueOf(tuple._1.split("_")[1]);  
						return new Tuple2<Long, Long>(categoryId, tuple._2);  
					}

				});

		/**
		 * 第四步,最第二轮全局的聚合
		 */
		JavaPairRDD<Long, Long> clickCategoryId2CountRDD = restoredRDD.reduceByKey(

				new Function2<Long, Long, Long>() {

					private static final long serialVersionUID = 1L;

					@Override
					public Long call(Long v1, Long v2) throws Exception {
						return v1 + v2;
					}

				});

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值