MapReduce:N keys,N files(三)数据倾斜优化

还是如何将N个keys写到N个文件的需求。 这次的问题是单个key太大,引起的单个reduce任务执行时间过长,导致整个MR运行时间过长。数据大部分的key在千,万级别,而有几个key在亿,10亿级别。 解决数据倾斜问题的核心是将数据量很大的key,打散变小分配给多个reduce,最好能均匀分布,这样所有的reduce接收相同的数据量,大家执行时间相差不多,就解决了数据倾斜问题。

一个最好的算法或者说处理方式最好与业务无关。既然与业务无关,则需要有个地方统计各个key的数量,然后根据key的数量给其分配reduce的个数。

【尝试一】

规定一个key处理的个数为1w。通过combiner统计各个key的长度,然后将该长度与原key组成新key:

public class SplitTextCombiner extends Reducer<Text,Text,Text,Text> {
    private Text outputKey = new Text();
    private int counter = 0;
    private final int MAX_RECOTD_PER_MAP = 10000;
    //private OrcStruct pair = null;
    protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
//        if (pair == null){
//            pair = (OrcStruct)OrcStruct.createValue(ISTool.getTypeDescription(context.getConfiguration()));
//        }
        for(Text oneValue:values){
            outputKey.set(key.toString() + "&" + counter/MAX_RECOTD_PER_MAP);

            context.write(outputKey, oneValue);
            counter++;
        }
    }
}

这个尝试是失败的。因为MR框架是先经过Partition,再Combiner的。Combiner时数据已经分好reducer了。大key还是分给了一个reducer。我们这边的操作只是将一个大key分为多个小key,没啥作用的。 只能通过partition将大key分为多个小key,而partition的时候是无法知道key的数量。现在的需求是partition之前,需要知道key的数量级。

这个是对mr的处理流程不清晰,才会有这种错误的想法。。

【尝试二】

没办法只能通过指定key的方式分割数据。 在配置中指定大key的分割文件个数n,随机将大key分配到指定的n个文件中。

由于reduce个数的限制,一般一个key只会分配到几个文件中。这里采用随机生成大数,再求余的方式生成随机数:

package is.split;

import org.apache.commons.lang.math.RandomUtils;

public class CreateRandomValue {
    private int begin;
    private int end;
    private final int max = 100000;
    public CreateRandomValue(int begin, int end){
        this.begin = begin;
        this.end = end;
    }

    public int createRandom(){
        int s = (RandomUtils.nextInt(max)%end)%(end-begin+1) + begin;
        return s;
    }
}

比如说我的配置项为(key-文件个数):10000:10,20000:20,3000:30。那么1000分配到第0-9reduce中,2000分配到第10-29reduce中,3000分配到30-59reduce中。避免大key分配到一个reduce,造成数据倾斜。

partition的时候对指定的key采用CreateRandomValue随机生成reduce序号即可。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员的诗和远方

30分钟QUnit入门教程

30分钟让你了解Javascript单元测试框架QUnit,并能在程序中使用。 QUnit是什么 QUnit是一个强大,易用的JavaScript单元测试框架,...

4969
来自专栏跟着阿笨一起玩NET

T4模板语法

T4,即4个T开头的英文字母组合:Text Template Transformation Toolkit。

931
来自专栏积累沉淀

大型数据库技术1

什么是数据库? 在计算机系统中按照一定的数据模型组织、存储和使用相互关联的数据集合。 数据模型 通常是由数据结构、数据操作、完整性约束3部分组成。    ...

2056
来自专栏SDNLAB

码农学ODL之Toaster代码解析

Toaster(烤面包机)是OpenDaylight的一个例子,该例子的目的不是让你如何烤面包,而是借这个例子学习OpenDaylight的特性。在Toaste...

3986
来自专栏机器学习从入门到成神

Pandas使用DataFrame进行数据分析比赛进阶之路(二):日期数据处理:按日期筛选、显示及统计数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35512245/articl...

6601
来自专栏Ceph对象存储方案

简谈RGW的index shard计算

在RGW里面每个存储到rados的Object都需要先计算出对应元数据存储的shard number,之后再将元数据信息更新到shard number对应的Ob...

2696
来自专栏DOTNET

ASP.NET MVC编程——模型

1 ViewModel 是一种专门提供给View使用的模型,使用ViewModel的理由是实体或领域模型所包含的属性比View使用的多或少,这种情况下实体或领域...

3308
来自专栏大数据挖掘DT机器学习

文本分类中语料库的获取——搜狗语料库

这次主要总结搜过语料库的获取,因为老师要求20万数据,而我自己只爬了2万多,所以用到了搜狗的语料库. ? 在这个页面中,我选择的是一个月的数据,别小看一个月...

6738
来自专栏about云

日志分析实战之清洗日志小实例7:查看样本数据,保存统计数据到文件

问题导读 1.如何从所有数据中,抽取样本查看? 2.如何保存结果到hdfs? 3.saveAsTextFile的作用是什么? 上一篇 日志分析实战之清洗...

2945
来自专栏算法+

不用第三方解码库取得图片宽高 附完整C++算法实现代码

在特定的应用场景下,有时候我们只是想获取图片的宽高, 但不想通过解码图片才取得这个信息。 预先知道图片的宽高信息,进而提速图片加载,预处理等相关操作以提升体验。...

4296

扫码关注云+社区

领取腾讯云代金券