• MapReduce数据倾斜的解决方式


    数据倾斜:由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点。map /reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完,此称之为数据倾斜。

    Hadoop计算框架的特性:

    • 不怕数据大,怕数据倾斜;
    • job数比较多的作业运行效率相对比较低,如子查询较多;
    • 不会发生数据倾斜的情况:sum,count,max,min

            会发生数据倾斜的情况:group by,count(distinct),小表关联大表

    MapReduce提供Partitioner接口,它的作用就是根据key或value及reduce的数量来决定当前的这对输出数据最终应该交由哪个reduce task处理。默认对key hash后再以reduce task数量取模。默认的取模方式只是为了平均reduce的处理能力,如果用户自己对Partitioner有需求,可以订制并设置到job上。

    用hadoop程序进行数据关联时,常碰到数据倾斜的情况,这里提供一种解决方法。

    自己实现partition类,用key和value相加取hash值:

    方式1:

    源代码:
    
    public int getPartition(K key, V value,
    
                              int numReduceTasks) {
    
        return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
    
      }
    
    修改后
    
    public int getPartition(K key, V value,
    
                              int numReduceTasks) {
    
        return (((key).hashCode()+value.hashCode()) & Integer.MAX_VALUE) % numReduceTasks;
    
      }

    方式2:

    public class HashPartitioner<K, V> extends Partitioner<K, V> {
    
    private int aa= 0;
    
      /** Use {@link Object#hashCode()} to partition. */
    
      public int getPartition(K key, V value,
    
                              int numReduceTasks) {
    
        return (key.hashCode()+(aa++) & Integer.MAX_VALUE) % numReduceTasks;
    
      }

    优化常用手段:

    • 减少job数(合并MapReduce,用Multi-group by)
    • 设置合理的task数,能有效提升性能
    • 数据量大,慎用count(distinct)
    • 对小文件进行合并
  • 相关阅读:
    关于extern对变量的使用
    MediaPipe Android Archive
    MediaPipe框架结构
    bazel构建C++工程
    Ubuntu安装ss(终端+浏览器)
    Ubuntu下MediaPipe的环境配置
    Ubuntu使用frp进行内网穿透
    Ubuntu中ssh-server的安装与开机自启动
    Ubuntu系统挂载新硬盘的方法
    Ubuntu16.04下安装TensorFlow
  • 原文地址:https://www.cnblogs.com/lingluo2017/p/8733638.html
Copyright © 2020-2023  润新知