• hive两大表关联优化试验


    呼叫结果(call_result)与销售历史(sale_history)的join优化:
    CALL_RESULT: 32亿条/444G

    SALE_HISTORY:17亿条/439G

    • 原逻辑
      Map: 3255 Reduce: 950 Cumulative CPU: 238867.84 sec HDFS Read: 587550313339 HDFS Write: 725372805057 SUCCESS 28.1MIN

    • 开启中间结果压缩
      set hive.exec.compress.intermediate=true;
      set mapred.map.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec

      Map: 3255 Reduce: 950 Cumulative CPU: 268479.06 sec HDFS Read: 587548211067 HDFS Write: 725372805057 SUCCESS 31.6MIN
      从结果看cpu的耗时增加,这是压缩解压缩过程的消耗;HDFS读取量略有减少,可能是因为源表是RCFile存储,本身已经压缩导致,因此整体时间上没有明显减少。

    • 开启中间和最终压缩
      set hive.exec.compress.intermediate=true;
      set mapred.map.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec
      set hive.exec.compress.output=true;
      set mapred.output.compression.codec=org.apache.hadoop.io.compress.GZipCodec

      Map: 3255 Reduce: 950 Cumulative CPU: 264034.27 sec HDFS Read: 587546058107 HDFS Write: 136021543504 SUCCESS 24.7MIN
      从结果看HDFS write明显减少近6倍,整体运行时间有所降低

    • 设置map数量减少一倍
      set mapred.max.split.size=512000000
      Map: 1684 Reduce: 950 Cumulative CPU: 191656.39 sec HDFS Read: 585689265249 HDFS Write: 725372805057 SUCCESS 22.9MIN
      map数减少一倍后,消耗cpu资源减少;整体运行时间略有下降

    • 只开启JVM重用(10)
      set mapred.job.reuse.jvm.num.tasks=10;
      Map: 3255 Reduce: 950 Cumulative CPU: 259683.41 sec HDFS Read: 587550076795 HDFS Write: 725372805057 SUCCESS 28.9MIN
      CPU开销增加,总运行时间没有变化

    • 减少map数并设置JVM重用(10)
      Map: 1684 Reduce: 950 Cumulative CPU: 223036.3 sec HDFS Read: 585692215905 HDFS Write: 725372805057 SUCCESS 29.4MIN 效果不大

    • 减少map数并开启压缩
      Map: 1684 Reduce: 950 Cumulative CPU: 251331.5 sec HDFS Read: 585697165921 HDFS Write: 136021488023 SUCCESS 26.1MIN
      开启中间压缩,对于输入数据量有少许减少,但是cpu开销增大,对于单stage任务总体不理想

    • 减少map数并开启最终压缩
      Map: 1687 Reduce: 951 Cumulative CPU: 234941.99 sec HDFS Read: 586512467704 HDFS Write: 136164828062 SUCCESS 24.8MIN
      只开启结果压缩,cpu资源消耗较之前有所减少,写入数据量明显降低,性能有提升

    总体来看,效果都不明显;hive默认使用reduce side join,当两个表中有一个较小的时候可以考虑map join ,但这两个表都是大表,可以尝试使用bucket map join;基本处理方法是将两个表在join key上做hash bucket,将较小表(sale_history)的bucket设置为较大表(call_result)的数倍。这样数据就会按照join key做hash bucket。这样做的话,小表依然会复制到各个节点上,map join的时候,小表的每一组bucket加载成hashtable,与对应的大表bucket做局部join。
    如果两表的join key 都具有唯一性(是主键关联),还可以进一步做sort merge bucket map join ;做法是两表都做bucket的基础上,每个bucket内部还要进行排序,这样做得好处就是在两边的bucket要做局部join的时候,用类似merge sort算法中的merge操作一样把两个bucket顺序遍历一下即可。
    然而以上两种方法经过测试依然没有太好的性能表现;稳定在20min之内已经不错了,又要考虑从源库抽取数据如何保留等问题,最终无法采用,后经过和业务系统沟通,两表每天数据量巨大,业务系统不会更新历史数据,每个表当天的数据是一一对应的,即当天的呼叫和销售历史是对应的,因此将程序优化为当天增量数据关联,数据下降几个数量级,自然不存在性能问题;
    所以,优化无止境,不一定非技术手段不可,首先基于业务逻辑做优化,要做到业务与技术相结合。

  • 相关阅读:
    今天的收获
    【转载】sourceinsight使用技巧
    我的第一份工作
    IBatis的使用
    Struts2学习笔记(十九) 验证码
    Struts2学习笔记(十七) 文件下载(File Download)
    Struts2学习笔记(十六) 文件上传(File Upload)
    Struts2学习笔记(十八) 防止表单重复提交
    Struts2学习笔记(十四) 输入校验(下)
    Struts2学习笔记(十一) 类型转换(Type Conversion)(上)
  • 原文地址:https://www.cnblogs.com/itboys/p/6695044.html
Copyright © 2020-2023  润新知