AmosCloud

Library

Have a Question?

If you have any question you can ask below or enter what you are looking for!

day04_hadoop_MR

日志分析案例

  • 需求1:统计每天每小时的IP(去重)数量

    • 我们观察到输出的数据自动的按照Map输出的Key进行排序
    • 结论:MR框架会在MAP->Reduce的过程中按照Key对数据进行排序
  • 需求2:要求需求1输出的结果按照数量进行正序排列

    • 是否需要聚合? 不需要聚合-不需要reduce
    • 将需要排序的数据放在Map输出的Key位置上,让框架自动排序
  • 需求3:要求需求1输出的结果按照数量进行降序排列

    • 发现:

      1. 放在Map的Key位置的Bean都实现了Comparable接口,而Comparable接口中的compareTo()方法可以完成对象的大小比较,也就可以控制升序和降序
      2. 放在Map的Key位置的Bean都实现了Writable接口,Writable接口是用来让我们写的Bean支持Hadoop的序列化
    • 尝试:

      1. 自己写一个Bean,让他可以排序,可以序列化,并且排序的逻辑是倒序
      2. 然后把这个Bean放在Map输出的Key的位置上
      3. 在Bean中的comparaTo方法中根据需要排序的字段的个数,可以实现多次排序

自定义对象的序列化

  1. 必须实现Writable接口
  2. 反序列化时,需要反射调用空参构造函数,所以必须有空参构造
  3. 重写序列化方法
  4. 重写反序列化方法
  5. 注意反序列化的顺序和序列化的顺序完全一致
  6. 要想把结果显示在文件中,需要重写toString(),且用”\t”分开,方便后续用
  7. 如果需要将自定义的bean放在key中传输,则还需要实现comparable接口,因为mapreduce框中的shuffle过程一定会对key进行排序
  • 需求3 统计每个IP出现的次数,按照ip的开头数字将结果输出到不同文件中

    • 分析:
      需要找到一种方式可以控制输出文件的数量
      需要找到一种方式可以控制某个数据往那个文件里输出

    • 输出文件数量:

      1. 如果MR没有Reduce,由MapTask的线程数(实例数)的数量来决定
        Map在我们的案例中,因为都是小文件,所以每个文件占一个block,Map根据block的数量启动线程数
      2. 如果有Reduce,由ReduceTask线程决定
        Reduce的数量由程序员在Driver中去设置他
        如果设置了超过1的Reduce数量 数据就会被分散到多个Reduce中处理
    • Partioner
      在Map结束之后MR框架还会对数据进行分区
      每个分区数据 单独进入一个Reduce进行处理

    • 分区怎么分的?
      默认的 MR使用HashPartitioner ,他按照Map输出的数据的Key的hash和我们设置的Reducetask的数量求模
      比如reduce数量设置为3 模的结果最多就是0 1 2

    • 我们可以自己实现一个Partitioner,让数据按照我们想要的方式进行分区

    • 问题: 我们自己写的Partitioner将来产生的分区数量可能和我们设置的reduce数量不一样
      分区数 > reduce数 有一些分区没有reduce处理 报错
      reduce数> 分区数 有一些reduce没有可接入的数据 这些收不到数据的reudce会空跑
      分区数 = reduce数 一一对应

    一般来说分区编号建议从0开始依次增加
    因为框架比较呆,他的分区永远从0开始编号

    • 案例中
      分区器 一共返回了9中分区编号 1~9
      reduce设置9个 会出错

You must be logged in to post a comment.