Hadoop基础概念介绍
基于YARN的配置信息, 参见: http://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop-yarn/
hadoop入门 - 基础概念
HDFS (Hadoop Distributed File System)
HDFS
是Hadoop框架的子模块, 采用master-slave结构, 一个HDFS Cluster由一个NameNode(管理系统元数据), 和多个DataNode(存放数据文件)组成. 文件将被分割成多块, 存储在一组DataNode中.
NameNode用来操作文件命名空间的文件或目录操作. 如打开, 关闭, 重命名等等. 同时它需要确定文件块与DataNode的映射.
DataNode负责来自文件系统Client的读写请求. 同时还要执行文件块的创建, 删除, 和来自NameNode的块复制指令.
Client读写文件的工作模式: Clients先和NameNode联系, 取得文件原数据(metadata)或者文件修改数据, 然后直接和DataNodes进行文件读写操作.
JobTracker
Hadoop用于分发MapReduce任务到特定节点的一个服务. 分发的优先级是先把任务给数据所在的节点, 其次给数据所在rack中的节点.
rack: 一份数据, 分割后分布存放在不同节点中, 这些节点组成一个rack.
工作流程:
1. Client提交jobs到JobTracker
2. JobTracker和NameNode联系, 确定数据所在位置.
3. JobTracker按分发的优先级顺序, 找到数据所在位置附近的TaskTracker.
4. JobTracker把作业提交到选中的TaskTracker节点.
5. 若任务失败, TaskTracker会通知JobTracker, JobTracker决定如何处理. 重新分发给其他节点, 对该TaskTracker做一定的标记以避免再次出现问题.
6. 各个节点计算完毕, JobTracker会更新自己的状态, Client app可以对其询问相关结果.
潜在问题, JobTracker是MapReduce的关键点, 如果它出现问题, 会导致所以jobs挂起.
TaskTracker
接收MapReduce任务的节点. 主要功能是
1 .资源管理
每个TaskTracker都有一组slot, 用于表明可接收的任务数量. 当JobTracker试图分发任务时, 首先会检查数据文件所在的节点上是否有空的slot, 如果没有, 则考虑分发给数据文件所在的rack中的某个节点.
TaskTracker会每隔几分钟给JobTracker发送一次状态更新, 包括可用的slot数量.
2. 作业调度, 监控:
对任务进行Map, Reduce和Shuffle操作.
TaskTracker会为每个任务启动一个独立的JVM进程, 然后监控各个任务进程, 捕捉输出结果和返回代码, 并将执行结果告知JobTracker.
MapReduce
是Hadoop MapReduce Engine 用来在集群中分发作业的关键算法.
由Map(映射)和Reduce(规约)两个函数式编程的概念组成.
Map
将input data(单个key-value对)转换成一组key-value对: map(key1,value) -> list<key2,value2>
注意: output的key可以和input的不同; output的多个entries可以使用同一个key.
Reduce
对特定的某个key对应的所以value值取出来, 生成一个新的list, 称为reduced output. reduce(key2, list<value2>) -> list<value3>
MapReduce引擎的核心概念
每个Map和Reduce都是独立的. 分布式系统对每份数据都会做多个拷贝, 并分发到不同的机器, 这样任何一个机器出问题都不容易导致整个计算被拖延.
不足之处
1. JobTracker是MapReduce的关键点, 可能引发单点故障. 并且JobTracker负责的任务过多, 导致资源消耗大, 当Job数量非常多的时候, 会造成很大的内存开销, 增加JobTracker出问题的风险. 一般认为MapReduce V1最多只能支持4000个左右的节点.
2. TaskTracker以Map/Reduce的Task数目作为资源的表示, 不考虑cpu/内存的占用情况, 如果两个大内存消耗的Task被调度到了一起, 很容易出现OOM.
3. TaskTracker把资源强制划分为Map Task Slot和Reduce Task Slot, 如果系统中只有Map Task或者只有Reduce Task时, 就会导致集群资源利用率很低.
4. 强制升级更新导致用户体验差.
5. 如果没有新的数据加入, 那么我们可以把计算结果做index, 这样下次同样的操作, 比如查询,就能很快从数据库得到答案. 但是如果数据持续被更新, 我们必须重新运行MR作业来确保index也得到更新, 当数据更新频率达到一定程度, MapReduce的工作原理迟早会导致资源不足.
6. 所有的Map操作没有完成之前, 任何一个Reduce操作都是无法开始的.
7. 通常我们会发现Reduce的输出总是小于Map的输入, 意味着我们用很大的datasource来生成很小的values.
8. 为了做到最大化并发, 作业中的Map和Reduce必须是无序的: 任何一个Map和Reduce都不能依赖于它们的MapReduce作业所生成的数据. 因此计算顺序无法控制.
YARN (aka MapReduce NextGen, aka MRv2)
Apache Hadoop YARN (Yet Another Resource Negotiator)
YARN是对MapReduce框架的重构(API和Interface兼容MRv1), 主要包括:
把JobTracker的两个主要功能(资源管理和作业调度/监控)分成了两个独立的部分 - RM和AM.
1. ResourceManager (RM) - 资源管理
从全局来对应用进行基础计算资源(内存, 带宽等等)管理, 这里说的应用要么是传统意义上的MapReduce作业, 要么是作业的有向无环图(DAG).
它又有两个主要部分:
-
Scheduler(S):
让RM根据所选的Policy(capacity guarantees, fairness, etc), 将资源分配给各个应用. 它让RM成为一个纯粹的调度器, 它在执行过程中, 不会去做Monitoring和tracking status等工作. 此外, 它也不会去重启因应用失败或者硬件错误而运行失败的任务. 调度工作是基于每个应用的资源需求来合理安排的, 包括CPU, 内存, 带宽, 磁盘空间等等.
调度器的插件可以将集群资源分配给多个队列和应用程序. 这些插件有:Capacity Scheduler(能力调度), Fair Scheduler(公平调度), 等等. 其中, 能力调度支持队列继承/层级支持, 为子队列之间共享集群资源提供更好的可控性和可预测性.
-
ApplicationsManager(ASM):
RM使用该组件来接受作业提交, 并为每个应用分配合适的容器来运行对应的AM, 同时管理AM, 在AM运行失败时提供service来重启AM所在的容器或者去其他机器重启一个AM.
2. ApplicationMaster(AM/AppMst) - 作业调度/监控
管理应用的调度和协调. 它会跟调度器索要运行应用所需的资源容器, 跟踪容器状态, 监控进程.
3. NodeManager
它是框架在每台机器上的代理, 负责容器的状态维护. 监视容器的资源状况, 并告知RM/Scheduler.
总结
RM是一个中心服务, 它调度并启动每个Job所对应的AM, 监控AM的存在状况. 它接受JobSubmitter提交的作业, 根据作业的上下文信息, 和NodeManager提供的容器状态信息, 为AM提供一个容器.
AM则负责一个Job生命周期内的所有工作, 包括对task的监控, 重启等等, 类似以前的JobTracker. 不同的是每个Job都有一个AM, 它们分散在RM以外的机器上, 也即, JobTracker也被分布式化了, 它们由RM中的ASM来统一监控, 一旦任何一个机器的AM出问题, ASM可以重启这个AM, 或者在其他机器上重启一个AM. 从而防止了单点故障的可能.
YARN相比MRv1, 配置和全局变量, 启停脚本都有变化, 详细参见:
http://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop-yarn/
hadoop入门 - 案例
统计词频编辑
如果想统计下过去10年计算机论文出现最多的几个单词,看看大家都在研究些什么,那收集好论文后,该怎么办呢?
方法一:我可以写一个小程序,把所有论文按顺序遍历一遍,统计每一个遇到的单词的出现次数,最后就可以知道哪几个单词最热门了.这种方法在数据集比较耗时,是非常有效的,而且实现最简单,用来解决这个问题很合适.
方法二:写一个多线程程序,并发遍历论文.
这个问题理论上是可以高度并发的,因为统计一个文件时不会影响统计另一个文件.当我们的机器是多核或者多处理器,方法二肯定比方法一高效.但是写一个多线程程序要比方法一困难多了,我们必须自己同步共享数据,比如要防止两个线程重复统计文件.
方法三:把作业交给多个计算机去完成.
我们可以使用方法一的程序,部署到N台机器上去,然后把论文集分成N份,一台机器跑一个作业.这个方法跑得足够快,但是部署起来很麻烦,我们要人工把程序copy到别的机器,要人工把论文集分开,最痛苦的是还要把N个运行结果进行整合(当然我们也可以再写一个程序).
方法四:让MapReduce来帮帮我们吧!
MapReduce本质上就是方法三,但是如何拆分文件集,如何copy程序,如何整合结果这些都是框架定义好的.我们只要定义好这个任务(用户程序),其它都交给MapReduce.