第1章 MapReduce概述

  • 定义:是一个分布式运算程序的编程框架
  • 优缺点:易于编程、良好的扩展性、高容错性、适合PB级以上数据的离线处理
  • 核心思想:MapReduce 编程模型只能包含一个Map 阶段和一个Reduce 阶段
  • MapReduce进程:
    MrAppMaster,负责整个程序的过程调度及状态协调
    MapTask,负责map阶段的数据处理
    ReduceTask,负责reduce阶段的数据处理
  • 官方WordCount源码:Map 类、Reduce 类、驱动类组成
  • 常用数据序列化类型:Hadoop Writable 类型:String Text、array ArrayWritable,其他对应Writable类型,BytesWritable
  • MapReduce编码规范:mapper阶段,reducer阶段,driver阶段
  • WordCount案例实操:driver类:获取实例和配置信息、三个类的加载、输入输出kv的类型、输入输出路径设置、提交任务

第2章 hadoop序列化

  • 把内存中的对象,转化成字节序列,以便存储到磁盘或网络传输。java的序列化太重量级,包含很多其他额外的信息,hadoop序列化,紧凑,快速,可扩展,互操作(多语言)
  • 自定义bean对象实现序列化接口:
    • 必须实现Writable接口
    • 反序列化必须与序列化顺序一致
    • 如果需要将自己定义的bean放在key中传输,则还需要实现Compareable接口(shuffle过程要对key排序)

第3章 MapReduce框架原理

InputFormat数据输入

  • MapTask并行度由切片数决定;(多少个切片数就有多少个MapTask)
  • FileInputFormat抽象类:切片机制:对每个文件单独切片,不考虑整体,文件大于切片大小1.1倍才会切片,默认切片大小等于block大小;切片大小计算公式:Math.max(minSize, Math.min(maxSize)),blockSize))==blockSize==128M,本地计算是32M,集群上是128M,逻辑上对输入进行改变,小于块大小可能会造成磁盘IO。调切片大小调minSize和maxSize
  • 其常见实现类:
    • TextInputFormat:继承FileInputFormat,框架默认的FileInputFormat实现类,如果有大量小文件,就会产生大量的MapTask,处理效率极其低下。切片机制:按文件切片,KV:按行读取,偏移量(LongWritable),每行的数据(Text)
    • CombineTextInputFormat:继承TextInputFormat,切片机制:将多个小文件从逻辑上规划到一个切片中,用于小文件过多的场景,将多个小文件从逻辑上规划到一个切片中,这样多个小文件就可以交给一个MapTask 处理。切片过程:虚拟存储切片最大值设置m - 虚拟存储 - 切片,虚拟存储:小于m的为一块,大于m小于2m的分两块(防止出现太小切),大于2m的分出一个m,剩下的再切分;切片:小于m的块跟其他合并为一个切片。KV:按行读取,偏移量(LongWritable),每行的数据(Text)
    • KeyValueTextInputFormat:继承FileInputFormat,切片机制:按文件切片。KV:分隔符分割K(Text)V(Text)
    • NLineInputFormat:继承FileInputFormat,切片机制:按n行为一个切片,KV:按n行读取,偏移量(LongWritable),NLine数据(Text)
CombineTextInputFormat,需要在Driver中添加:
job.setInputFormatClass(CombineTextInputFormat.class); //默认TextInputFormat.class
CombineTextInputFormat.setMaxInputSplitSize(job, 4194304); //虚拟存储切片最大值设置4m
注意:虚拟存储切片最大值设置最好根据实际的小文件大小情况来设置具体的值。 KeyValueTextInputFormat,需要在Driver中添加:
conf.set(KeyValueLineRecordReader.KEY_VALUE_SEPERATOR, " "); //设置分割符
job.setInputFormatClass(KeyValueTextInputFormat.class); //默认TextInputFormat.class NLineInputFormat,需要在Driver中添加:
job.setInputFormatClass(NLineInputFormat.class);
NLineInputFormat.setNumLinesPerSplit(job,2); //设置行数

自定义InputFormat:继承FileInputFormat,继承RecordReader

Job提交流程源码
- 创建临时提交文件路径
- 获取切片文件、配置文件、jar包
- 提交资源
- 删除文件路径下的资源

FileInputFormat切片机制:
- 遍历文件;
- 获取文件大小,计算切片大小,判断剩下的是否大于切片的1.1倍,否则就分一块切片。
- 将切片信息写到一个切片规划文件中Job.split

MapReduce工作流程

Shuffle机制

shuffle机制:

1,MapTask收集map方法输出的kv对,放到环形内存缓冲区(默认100M)

2,从缓冲区不断溢出文件,(超过80%溢出或整个切片结束)

3,多个溢出文件会被合并成大的溢出文件

4,在溢出及合并的过程中,会进行分区及排序,(接下来可选:combiner合并分区,压缩,序列化存入磁盘)

5,reducetask会根据自己的分区号,去各个maptask上取结果分区数据

6,reducetask对同一个分区的不同文件再进行合并(归并排序)

7,合并成大文件后shuffle过程也就结束了,后面进行reducetask的逻辑运算(调用用户的reduce())

注意:

缓冲区大小影响mapreduce执行效率,默认100M,参数io.sort.mb

默认分区是key的hashCode对reducetask个数取模得到的,用户没法控制哪个key分到哪个分区(可以自定义Partitioner)

Partition分区

  • 将输出进行分类,默认分区是HashPartitioner,根据key的hashCode和ReduceTask个数取模得到的,用户没法控制哪个key存在哪个分区
  • 使用:自定义Partitioner类,继承Partitioner,重写getPartitioner()方法。在job驱动中设置分区类,ReduceTask个数(大于1小于分区个数会报IO异常,1个可以,大于分区数也可以)

WritableComparable排序

  • 实现这个接口可以让自定义的类型作为key,排序类型:部分排序、全排序、辅助排序、二次排序
  • 使用:在作为key的自定义bean中实现WritableComparable接口,重写compareTo()方法定义排序,在map结束之后就会根据key排序,排序方法就是自定义的

Combiner合并

  • Driver设置job.setCombinerClass(),可以直接使用reducer的类,或者写Combiner类继承Recuder类

GroupingComparator分组排序

  • 对KV进行分组,然后排序输出,比如订单号分组,价格排序,使用bean作为key,定义分组排序的类
  • 使用:继承WritableComparator类,重写compare()方法,定义空参构造器调用父类构造器super(beanClass, true)

MapTask工作机制

ReduceTask工作机制

ReduceTask工作机制:

  1. ---

ReduceTask个数设置:

  • 太多太少效率都不高
  • ReduceTask=0表示没有reduce阶段,输出文件个数等于MapTask个数,MapTask个数有切片数决定
  • ReduceTask默认为1,数量的设置需要根据业务需求、集群性能而定,若计算汇总结果就只能有一个
  • 如果Map阶段不同切片数据量分布不均匀,就会出现数据倾斜(不同MapTask任务量差别很大)
  • 如果分区数不是1,但是ReduceTask个数不是1,则不执行分区;因为在源码中,分区前会先判断ReduceTask个数是否大于1,不大于1不执行分区

OutputFormat数据输出

  • 默认输出是TextOutputFormat,每条记录输出为文本行
  • SequenceFileOutputFormat,一般将其输出作为后续MapReduce的输入,格式紧凑,容易被压缩
  • 自定义Outputformat,控制最终输出的格式和路径:新建输出类继承FileOutputFormat,新建写记录的类继承RecordWriter类,Driver中指定新建输出类

Join多种应用

  • reduce join:Map端为来自不同表或文件的KV对打标签以区别不同的来源记录,然后用连接字段作为K,其他部分和新加的标志作为V,最后进行输出(toString());Reduce端,以连接字段为K的分组已经完成,只需要在每一个分组中将那些来源于不同源(Map端已打标签)的记录分开,最后进行合并
  • 缺点:合并的操作在reduce阶段完成,reduce端压力太大,map端运算负载很低,资源利用率不高,reduce阶段极易产生数据倾斜,解决办法:map端实现数据合并
  • map join:适用于一张表很小,一张表很大的场景,在Map端提前缓存小表,提前处理业务逻辑,增加Map端业务,减少reduce端压力,尽可能减少数据倾斜,减少Shuffer过程(最耗时间)

计数器应用

  • 计数器API:Hadoop为每个job维护若干计数器,以描述多项指标(调试)

    • 采用枚举方式统计计数,enum MyCounter{A,B}
      对枚举定义的计数器加1:context.getCounter(MyCounter.A).increment(1);
    • 采用计数器组,计数器名称的方式:context.getCounter("countergroup", "counter").incremene(1).

数据清洗(ETL)

  • 在运行核心业务MapReduce 程序之前,往往要先对数据进行清洗,清理掉不符合用户要求的数据。清理的过程往往只需要运行Mapper 程序,不需要运行Reduce 程序。使用哦计数器计数清洗的个数

MapReduce开发总结

第4章 hadoop数据压缩

  • 概述:提高网络带宽和磁盘空间的效率,可以在任意阶段使用压缩(3个);注意:使用压缩减少了磁盘IO也增加了CPU运算负担;原则:运算密集型job少用压缩,IO密集型多用压缩
  • MR支持的压缩编码:deflate,Gzip,bzip2,LZO,Snappy
  • 压缩方式的选择:------Map------Reduce-------
  • 压缩参数的配置:Map前:core-site.xml设置1个参数,Map后Reduce后mapred-site.xml设置2个参数、3个参数
  • 压缩实操案例:数据流的压缩、Map输出端的采用压缩、Reduce输出端采用压缩(Driver中开启压缩,设置压缩格式)

第5章 yarn资源调度器

yarn基本架构:

resourcemanager、nodemanager、container、application master

yarn工作机制

1,MR程序提交到客户端所在的节点

2,客户端的YarnRunner向ResourceManager申请一个application

3,resourcemanager返回资源路径

4,该程序将所需资源提交到hdfs上

5,程序资源提交完毕后,申请运行application master

6,reourcemanager分配一个container并运行application master

7,application master把程序运行所需资源拷贝到本地

8,application master向resourcemanager申请maptask运行的资源

9,resourcemanager分配运行maptask的容器,application master向分配的容器发送启动脚本

10,maptask计算完毕后,application master申请运行reducetask的资源

11,reducetask向maptask节点获取数据,运行reducetask程序

12,程序运行完毕后,mr会向resourcemanager申请注销自己

作业提交过程

资源调度器

  • FIFO
  • 容量调度(默认),多个任务队列,每个队列分配一定的资源,有可能抢占
  • 公平调度,多个任务队列,每个任务队列内的job共享队列的资源,支持抢占,允许调度器终止那些资源超过了公平共享份额的队列的容器(抢占会降低效率)
  • 延迟调度,如果一个应用请求一个节点(一般先是请求本地的),由于本地节点可能没有资源,放宽约束到其他节点上运行,实践发现,如果此时等一小段时间,会增加在请求节点上获得容器的机会,等足够多的其他节点的心跳之后再放松本地约束

任务的推测执行

  • 前提,每个task只能有一个备份任务,当前完成的task必须不小于5%
  • 原理,mr总是选择最低于平均完成时间的任务,以空间换时间;计算每个任务的估计完成时刻t1,计算每个任务的备份任务按照其他已经完成任务的速度执行完成时刻t2,MR总是选择t1-t2最大的任务开启备份任务

第6章 Hadoop企业优化

  • MapReduce程序效率瓶颈

    • 计算机性能(内存,cpu,磁盘,网络)
    • IO操作(数据倾斜,map reduce数设置不合理,小文件过多,大量的不可分的块,溢写次数,合并过多)
  • MapReduce优化方法:主要从以下6个方面:数据输入、Map阶段、Reduce阶段、IO传输、数据倾斜问题、常用调优参数
    • 数据输入:
      - MR运行前合并小文件;大量的小文件会产生大量的Map任务,增大Map装载次数,而任务的装载笔记耗时,从而导致运行缓慢;
      - 可以采用CombineTextInputFormat解决输入端大量小文件问题
    • Map阶段:
      - 减少溢写次数:调整io.sort.mb、sort.spill.percent参数增大出发溢出的上限,减少溢写次数,从而减少磁盘IO
      - 减少合并次数:调整io.sort.factor参数,增大合并的文件数目,减少合并的次数,从而缩短MR处理时间
      - 在Map之后,在不影响业务逻辑的前提下先进行Combine处理(提前Reduce),减少磁盘IO
    • Reduce阶段:
      - 合理设置Map和Reduce个数:太少会导致Task等待,太多会导致Map、Reduce任务间竞争资源,造成处理超时等错误
      - 设置Map和Reduce共存:调整slowstart.completedmaps参数,使用Map运行一定程度后,Reduce也开始运行,减少       Reduce等待时间
      - 规避使用Reduce:Reduce在连接数据集时会产生大量的网络消耗
      - 合理设置reduce端的buffer:默认情况下,数据达到一个阈值buffer中数据就会溢写到磁盘,然后从磁盘中获取数据。      可以通过调整参数使得一部分数据可以直接输入给Reduce,从而减少磁盘IO:mapreduce.reduce.input.buffer.percent,会保留指定比例的数据在buffer中,直接给Reduce
    • IO传输:
      - 采用数据压缩的方式,减少IO时间,安装Snappy和LZO压缩编码器
      - 使用SequenceFile二进制文件
    • 数据倾斜问题:
      - 抽样和范围分区:可以通过对原始数据进行抽样得到的结果来预设分区边界值
      - 自定义分区:基于key进行自定义分区
      - Combine:使用Combine可以大量减少数据倾斜,在可能的情况下,Combine的目的就是聚合并精简数据
      - 采用Map Join,尽量避免使用Reduce Join
    • 常用的调优参数
      - MR中:mapred-site.xml
  • mapreduce.map.memory.mb:一个MapTask 可使用的资源上限( 单位:MB),默认为1024。如果MapTask 实际
    使用的资源量超过该值,则会被强制杀死。
  • mapreduce.reduce.memory.mb:一个ReduceTask 可使用的资源上限( 单位:MB),默认为1024。如果ReduceTask
    实际使用的资源量超过该值,则会被强制杀死。
  • mapreduce.map.cpu.vcores:每个MapTask 可使用的最多cpu core 数目,默认值: 1
  • mapreduce.reduce.cpu.vcores:每个ReduceTask 可使用的最多cpu core 数目,默认值: 1
  • mapreduce.reduce.shuffle.parallelcopies:每个Reduce 去Map 中取数据的并行数。默认值是5
  • mapreduce.reduce.shuffle.merge.percent:Buffer 中的数据达到多少比例开始写入磁盘。默认值0.66
  • mapreduce.reduce.shuffle.input.buffer.percent:Buffer 大小占Reduce 可用内存的比例。默认值0.7
  • mapreduce.reduce.input.buffer.percent:指定多少比例的内存用来存放Buffer 中的数据,默认值是0.0

- Yarn中:yarn-site.xml

  • yarn.scheduler.minimum-allocation-mb:给应用程序Container 分配的最小内存,默认值:1024
  • yarn.scheduler.maximum-allocation-mb:给应用程序Container 分配的最大内存,默认值:8192
  • yarn.scheduler.minimum-allocation-vcores:每个Container 申请的最小CPU 核数,默认值:1
  • yarn.scheduler.maximum-allocation-vcores:每个Container 申请的最大CPU 核数,默认值:32
  • yarn.nodemanager.resource.memory-mb:给Containers 分配的最大物理内存,默认值:8192

- Shuffle中:mapred-site.xml,Yarn启动之前配置好

  • mapreduce.task.io.sort.mb:Shuffle 的环形缓冲区大小,默认100m
  • mapreduce.map.sort.spill.percent:环形缓冲区溢出的阈值,默认80%

- 容错相关

  • mapreduce.map.maxattempts:每个Map Task 最大重试次数,一旦重试参数超过该值,则认为Map Task 运行失败,默认值:4。
  • mapreduce.reduce.maxattempts:每个Reduce Task 最大重试次数,一旦重试参数超过该值,则认为Map Task 运行失败,默认值:4。
  • mapreduce.task.timeout:Task 超时时间,经常需要设置的一个参数,该参数表达的意思为:如果一个Task 在一定时间内没有任何进入,即不会读取新的数据,也没有输出数据,则认为该Task 处于Block 状态,可能是卡住了,也许永远会卡住,为了防止因为用户程序永远Block 住不退出,则强制设置了一个该超时时间(单位毫秒),默认是600000。如果你的程序对每条输入数据的处理时间过长(比如会访问数据库,通过网络拉取数据等),建议将该参数调大,该参数过小常出现的错误提示是“ AttemptID:attempt_14267829456721_123456_m_000224_0 Timed out after 300 secsContainer killed by theApplicationMaster.”。
  • HDFS小文件优化方法

    • 弊端:HDFS 上每个文件都要在NameNode 上建立一个索引,大小约为150byte,这样当小文件比较多的时候,就会产生很多的索引文件,一方面会大量占用NameNode 的内存空间,另一方面就是索引文件过大使得索引速度变慢。
    • 解决方案:
      - Hadoop Archive,将多个小文件打包成一个har文件
      - SequenceFile由一些列二进制kv组成,如果key为文件名,value为内容,则可以将大批小文件合并成一个大文件
      - CombineFileInputFormat,一种新的InputFormat,将多个文件合并成一个单独的切片
      - 开启JVM重用,对于大量小文件的job,原理:Map在JVM上运行完毕后,会继续运行其他Map,设置map.reduce.job,jvm.numtasks在10-20之间

第7章 MapReduce扩展案例

  • 倒排索引案例:有多个文件,每个文件里有多个单词,求每个单词在各个文件中出现的次数
  • TopN案例
  • 找博客共同好友案例

Hadoop - MapReduce学习笔记(详细)的更多相关文章

  1. Hadoop入门学习笔记---part3

    2015年元旦,好好学习,天天向上.良好的开端是成功的一半,任何学习都不能中断,只有坚持才会出结果.继续学习Hadoop.冰冻三尺,非一日之寒! 经过Hadoop的伪分布集群环境的搭建,基本对Hado ...

  2. Hadoop入门学习笔记---part2

    在<Hadoop入门学习笔记---part1>中感觉自己虽然总结的比较详细,但是始终感觉有点凌乱.不够系统化,不够简洁.经过自己的推敲和总结,现在在此处概括性的总结一下,认为在准备搭建ha ...

  3. Hadoop入门学习笔记---part1

    随着毕业设计的进行,大学四年正式进入尾声.任你玩四年的大学的最后一次作业最后在激烈的选题中尘埃落定.无论选择了怎样的选题,无论最后的结果是怎样的,对于大学里面的这最后一份作业,也希望自己能够尽心尽力, ...

  4. Hadoop入门学习笔记---part4

    紧接着<Hadoop入门学习笔记---part3>中的继续了解如何用java在程序中操作HDFS. 众所周知,对文件的操作无非是创建,查看,下载,删除.下面我们就开始应用java程序进行操 ...

  5. Hadoop之MapReduce学习笔记(二)

    主要内容: mapreduce编程模型再解释: ob提交方式: windows->yarn windows->local : linux->local linux->yarn: ...

  6. Hadoop之MapReduce学习笔记(一)

    主要内容:mapreduce整体工作机制介绍:wordcont的编写(map逻辑 和 reduce逻辑)与提交集群运行:调度平台yarn的快速理解以及yarn集群的安装与启动. 1.mapreduce ...

  7. Hadoop入门学习笔记(一)

    Week2 学习笔记 Hadoop核心组件 Hadoop HDFS(分布式文件存储系统):解决海量数据存储 Hadoop YARN(集群资源管理和任务调度框架):解决资源任务调度 Hadoop Map ...

  8. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  9. MapReduce学习笔记

    一.MapReduce概述 MapReduce 是 Hadoop 的核心组成, 是专用于进行数据计算的,是一种分布式计算模型.由Google提出,主要用于搜索领域,解决海量数据的计算问题. MapRe ...

随机推荐

  1. 新手如何入门linux,linux原来还可以这么学

    前言 在这个只有cangls和小白两人的小房间中,展开了一次关于学习方法的讨论. 小白:cangls啊,我想请教一个问题,您是如何记住那么多linux命令的. cangls:我啊,别人都看我的小电影, ...

  2. gin框架中设置信任代理IP并获取远程客户端IP

    package main import ( "fmt" "github.com/gin-gonic/gin" ) func main() { gin.SetMo ...

  3. limit概述

    5.limit 5.1.limit是将查询结果集的一部分取出来,通常使用在分页查询中 分页作用是为了提高用户体验,可以一页一页翻页看 5.2.limit用法:(非常重要) 完整用法:limit sta ...

  4. 什么是以特性为核心的持续交付|阿里巴巴DevOps实践指南

    编者按:本文源自阿里云云效团队出品的<阿里巴巴DevOps实践指南>,扫描上方二维码或前往:https://developer.aliyun.com/topic/devops,下载完整版电 ...

  5. React 世界的一等公民 - 组件

    猪齿鱼Choerodon平台使用 React 作为前端应用框架,对前端的展示做了一定的封装和处理,并配套提供了前端组件库Choerodon UI.结合实际业务情况,不断对组件优化设计,提高代码质量. ...

  6. 如何在 VS Code 中为 Java 类生成序列化版本号

    前言 IDEA 提供自动生成序列化版本号的功能,其实 VS Code 也可以,只是默认关闭了这个功能,下面就来看看如何开启这个功能吧. 配置过程 首先需要保证 VS Code 上安装了提供 Java ...

  7. 微信 CLI 工具正式发布 v1.0

    前言 为了让开发者可以更加方便舒适地获取到微信开发的资源,今天我们基于 Senparc.Weixin SDK 正式发布了基于 .NET 的微信 CLI 工具:Weixin.CLI(v1.0). 通过 ...

  8. Luogu_P2048

    超级钢琴 有 \(n\) 个音符,编号从 \(1\) 到 \(n\) .第 \(i\) 个音符的美妙度为 \(A_i\) . 我们要找到 \(k\) 段不同超级和弦组成的乐曲,每段乐曲的连续音符个数 ...

  9. .NET 诞生已20周年,您的 .NET 技能是否还停留在2010 年?

    20年来,我们见证了超过上千万.NET 开发员,当前有600万.NET 开发者正在使用.NET技术构建各类解决方案.今天,IT市场对.NET 开发人员的需求达到了前所未有的程度,特别是在中国,各大公司 ...

  10. 连接mysql出现“Unable to load authentication plugin 'caching_sha2_password”错误

    这是mysql 8.0版本才出现的问题,原因是mysql 8.0 默认使用 caching_sha2_password 身份验证机制 -- 从原来的 mysql_native_password 更改为 ...