mapreduce任务中数据分布倾斜导致reduce负载不均衡的解决方案

本文探讨了MapReduce任务中由于数据分布不均匀导致的reduce节点负载不均衡问题,提出了一种利用随机数实现的解决方案。通过模拟map阶段的分区过程,依据均匀分布原理将key分散到不同reducer,避免了使用一致性哈希算法带来的内存消耗。测试结果显示,即使在key种类有限的情况下,该方案也能实现数据的均匀分布。
摘要由CSDN通过智能技术生成

概述:

从所周知,当需求中数据出现分布不均的情况时,按照hadoop mr任务的默认partition方法,会出现某些机子负载过重的情况,这样会拖慢整个任务进度,有时候甚至会宕机。在这里我介绍一个用随机数解决这个问题的方案,下面是通过代码来模拟map根据partition来分区的情况;

原理(追加)

方案就是运用了数学中均匀分布的原理,举个例子:10个小球,有5个盒子,那么每个小球分配到每个盒子的概率都是相同的,即五分之一,那么例子中小球模拟的是mr中的key,盒子模拟的是reducer。这种方案相对于官方提供的用一致性哈希算法有什么优点呢,我们了解到要使用一致性哈希算法达到均匀分布key,哈希算法中的虚拟桶数在足够多,但是hadoop处理的数据都是十亿级数据,key种类也是千万级以上,如果为了更均匀,必然会耗费更多的内存,但是如果采用这种方案,那么几乎是不需要内存来保存key的状态,而且数据量越大,分布就更加均匀

测试代码

package com.mxq.balance;

import java.util.Vector;

public class UNBalanceData {
   

    private Vector<keyAndNum> keyVector=new Vector<keyAndNum>(10);

    //这里用于生成不均匀数据样本的信息;
    public void intialize(){

        keyAndNum kn=new keyAndNum(1,50);
        this.keyVector.add(kn);

        kn=new keyAndNum(2,100);
        this.keyVector.add(kn);

        kn=new keyAndNum(3,80);
        this.keyVector.add(kn);
        //其中keyAndNum(4,1000020)表示key 4 有1000020个记录;
        kn=new keyAndNum(4,1000020);
        this.keyVector.add(kn);

        kn=new keyAndNum(5,10050);
        this.keyVector.add(kn);

        kn=new keyAndNum(6,200);
        this.keyVector.add(kn);

        kn=new keyAndNum(7,100050);
        this.keyVector.add(kn);

        kn=new keyAndNum(8,250);
        this.keyVector.add(kn);

        kn=new keyAndNum(9,140);
        this.keyVector.add(kn);

        kn=new keyAndNum(10,90);
        this.keyVector.add(kn);
    }
    //获取总样本数是;
    public int getLoop(){
        int loop=0;
        for(int i=0;i<this.keyVector.size();i++){
            loop+=this.keyVector.get(i).getKeyNum();
        }

        return loop;
    }
    //根据initialize生成的信息 生成样本时用;
    public boolean minus(int key){

        for(int i=0;i<this.keyVector.size();i++){
            if(this.keyVector.get(i).getKey()==key){

                if(this.keyVector.get(i).getKeyNum()<1){
                    //System.out.println("key :" +key+"'s num "+this.keyVector.get(i).getKeyNum()+ " ,please check program");
                    return false;
                }else{
                    this.keyVector.get(i).minus();
                    return true;
                }

            }


        }

        return false;
    }




}

//此类是模拟reduce
package com.mxq.balance;

import java.util.Vector;

public class reduceContain {
   

    public Vector<keyAndNum> reduceVec=new Vector<keyAndNum>();

     //根本key来收集各个key在某个reducer的数量;
    public void addKey(int key){
        boolean find=false;
        int index=-1;

        for(int i=0;i<this.reduceVec.size();i++){

            if(this.reduceVec.get(i).getKey()==key)
            {
                find=true;
                index=i;
                break;
            }

        }

        if(find){
            this.reduceVec.get(index).add();
        }else
        {
            keyAndNum kn=new keyAndNum(key,1);
            this.reduceVec.add(kn);
        }


    }

    //获取最终key在某个reducer的样本数
    public int getResult(int key){
        for(int i=0;i<this.reduceVec.size();i++){
            if(this.reduceVec.get(i).getKey()==key){
                return this.reduceVec.get(i).getKeyNum();
            }
        }
        System.out.println("can not find key");

        return 0;
    }

}
//保存key的状态或者配置信息;
package com.mxq.balance;

public 
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值