• hadoop集群分区及缓存随笔


    1、分区是必须要经历Shuffle过程的,没有Shuffle过程无法完成分区操作
    2、分区是通过MapTask输出的key来完成的,默认的分区算法是数组求模法:
    --------------数组求模法:
    -----------将Map的输出Key调用hashcode()函数得到的哈希吗(hashcode),此哈希吗是一个数值类型
    ,将此哈希吗数值直接与整数的最大值(Integer.MAXVALUE)取按位与(&)操作,将与操作的结果与ReducerTask
    的数量取余数,将此余数作为当前Key落入的Reduce节点的索引
    -------------------------
    Integer mod = (Key.hashCode()&Integer.MAXVALUE)%NumReduceTask;

    被除数=34567234
    NumReduceTas=3
    ----结果:
    0、1、2 这三个数作为Reduce节点的索引
    数组求模法是有HashPartitioner类来实现的,也是MapReduce分区的默认算法

    hadoop集群性能和效率:
    ------------
    1、数据量需要达到一定的数量级,使用hadoop集群来处理才是划算的
    2、集群的计算性能取决于任务数量的多少,设置任务数量必须充分考虑到集群的计算能力(比如:物理节
    点数量):
    -------
    A、Map设置的任务数量作为最小值参考,与切片数量对比,取两者大值
    B、Reduce的任务数量默认是1,如果设置了任务数量,则启用设置的任务数量
    -------
    3、不管MapTask还是ReduceTask,只要任务数量越多则并发能力越强,处理效率会在一定程度上越高,但
    是,设置设置的任务数量必须参考集群中的物理节点数量,如果设置的任务数量过多,会导致每个物理节点上分摊的
    任务数量过多,处理器并发每个任务产生的计算开销越大,任务之间因处理负载导致相互之间的影响很大,任务失败
    率上升,计算性能反而下降(因为任务失败会重置),因此在设计MapTask与ReduceTask任务数量时必须权衡利弊,
    折中考虑...

    两张表链接操作(分布式缓存):
    -------
    假设:
    ------其中一张A表,只有20条数据记录
    另外一张非常大,上亿的记录数量
    ----------------------------------
    策略:
    将数据集小的文件直接装载到内存,然后迭代大文件记录

    分布式缓存的两种角度理解(针对较小数据集):
    -----------------
    1、将文件不切块,直接存储到各个节点上的本地磁盘中,这种模式的缓存只是减少了网络IO,磁盘IO并没
    有减少
    2、将文件不切块,直接存储到各个节点上的任务进程内存中,(MapTask进程,JVM会开辟一块任务内存)
    ,这种模式的缓存从根本上取消了该文件的读取IO操作

    从集群中读取文件缓存到本地内存中:
    代码:
    -------1、
    //从本地磁盘读取数据到内存中缓存起来,之后在Map方法的迭代中可直接使用
    Configuration conf = context.getConfiguration();

    // 下面是直接从集群路径中读取文件缓存到本地的内存中的操作方式
    //FileSystem fs = FileSystem.get(conf);
    URI[] uris = context.getCacheFiles();
    URI uri=uris[0];

    Path clusterPath=new Path(uri);
    FileSystem fs=clusterPath.getFileSystem(conf);

    InputStream fis = fs.open(clusterPath);
    String line=null;
    BufferedReader br=null;
    try {
    br=new BufferedReader(new InputStreamReader(fis));
    while(null!=(line=br.readLine())){
    String[] fields=line.split("\s+");
    smallMap.put(fields[0], fields[1]);
    }
    } catch (Exception e) {
    // TODO: handle exception
    }finally{
    if(br!=null)br.close();
    }

    --------2、
    //获取缓存文件的本地路径
    Configuration conf = context.getConfiguration();
    String[] localPaths = conf.getStrings(MRJobConfig.CACHE_LOCALFILES);
    Path[] path = StringUtils.stringToPath(localPaths);

    Path localPath=path[0];
    URI localurl=localPath.toUri();
    File fp=new File(localurl);

    String line=null;
    BufferedReader br=null;
    try {
    br=new BufferedReader(new InputStreamReader(new FileInputStream(fp)));
    while(null!=(line=br.readLine())){
    String[] fields=line.split("\s+");
    smallMap.put(fields[0], fields[1]);
    }
    } catch (Exception e) {
    // TODO: handle exception
    }finally{
    if(br!=null){
    br.close();
    }
    }

  • 相关阅读:
    用react的ReactCSSTransitionGroup插件实现简单的弹幕动画
    composer安装yii2问题总结
    记阿里笔试经历
    JVM, JRE,JDK 的区别
    HTML
    Http协议
    操作系统和网络基础知识
    网络基础之网络协议
    计算机硬件知识
    计算机硬件历史
  • 原文地址:https://www.cnblogs.com/pandazhao/p/8058953.html
Copyright © 2020-2023  润新知