Hadoop学习笔记---基本概念


0、前言:      不做过多介绍Hadoop 网上比比皆是,每本书买来一看,第一张都是千篇一律,本文不做过多阐述,希望将此文建立在对hadoop有些了解的基础上,本文的总体流程是,先提出一个subject,然后根据关联将相关联的概念参数一并带出,虽整体不美观,但有助于将相关知识汇总记忆。 1、Hadoop 版本图:            第一个大的主线是社区版的Hadoop路线图,2009年分离出来的分支一值延续到0.20.205 坚持不住了,直接改为1.0.0 了,所以我们现在用的1.x.x的都是基于0.20.205 发展过来的;      而0.21版本走上了另外一条路,其中对Hadoop项目分割成三个独立的模块,分别是HDFS,Common和MapReduce,在这个版本中启用新的节点CheckPointNode 取代SecondaryNameNode,同时添加了一个BackUpNode作为NameNode 的冷备 等新的特性,并对MapReduce API 进行改造,启用新的MapReduce API,但旧API依然可用。      0.22分支其实是对0.21 基础上修复了一些bug,并进行了适度的优化。      0.23 分支其实是一个全新的方向,其实就是HDFS Federation和 MapReduce2.0(YARN)。      还有一个2.0分支,是基于0.23 基础上增加了NameNode HA等 高级特性。      第二个大的主线则是发行版 Cloudera Hadoop 又简称CDH      为什么我们选择1.x.x分支呢,原因很简单他是目前为止唯一有稳定版本的分支。 2、Hadoop 各守护进程      (一)、HDFS方向      NameNode,在目前1.x.x版本系中NameNode只有一个设置参数:fs.default.name,他是整个HDFS的master,他负责管理HDFS文件的元数据信息和文件的目录树,这其中包括两个文件           fsimage:HDFS元数据的镜像文件           editlog:HDFS文件的改动日志      另外NameNode 还负责监控DataNode的健康状况。如果某个DataNode宕机,则将该DataNode上存放的文件副本复制到另外一个全新的节点。      NameNode也记录着所有文件中每个块block所在的数据节点信息,但它并不永久存储这些数据,仅仅是存在内存之中,DataNode 也每个一段时间想NameNode汇报它们所存储块的列表信息,再就是系统重启的时候DataNode也会向Namenode汇报此类信息。      这又说明了一个问题,block越多,NameNode占用内存也就越多,而每个小文件会产生一个单独的block 所以要尽量减少小文件的存在,以降低Namenode的内存压力。      DataNode:从名字上看就是数据节点 也是集群中的slave 节点。每个节点存放数据的一部分。HDFS文件对数据文件进行分块存储,默认数据块的大小是64M,可根据需求适  当调整block的大小 参数:dfs.block.size,但不希望将数据块设置的过小,或者HDFS中的文件过小都会造成HDFS元数据量过大,给NamNode造成压力,也给MapReduce造成不便,解决小文件的问题,可考虑用Archive,或者SequenceFile进行存储。      注意将小文件归档Archive后源文件同时是存在的,所以要手动删除,Archive 归档方式如下:      hadoop archive -archiveName loginlog.har /flume/loginlog /flume      其中loginlog.har 是归档文件名 .har 后缀名必须的,且不能改变,/flume/loginlog 为hdfs 路径,最后一个参数是归档后的文件存放路径。      查看方式两种:      hadoop fs -lsr /flume/loginlog.har ,这种方式显示归档后的时间文件树,包括两个索引文件盒一个数据文件      hadoop fs -lsr har:///flume/loginlog.har 展示出来的结果和原结构树展示是一样的,对于用户来说是透明的。
    •      归档文件并不支持压缩,所以归档后文件和原文件总大小相当。
    •      归档文件支持MapReduce 但是对于MapRecude 来时归档文件是透明的,虽然可以使得很多文件成为一个分片block 但并不能提高效率。
    •      归档文件一旦创建不能修改,除非删除重建。
     SecondaryNameNode:它的作用是定期通过editlog合并到fsimage,以防止editlog过大,它需要占用大量的CPU时间于NameNode相同容量的内存来执行合并操作,它也会保存合并后的fsimage副本,在NameNode发生故障,且元数据无法恢复的时候启用,根据SecondaryNameNode的工作方式,它总是落后NameNode一个editlog的滞后时间。所以这个进程其实也是很忙碌的,所以一般单独放在一个机器上运行。      但有一个默认的参数必须要设置的是dfs.http.address 需要制定 namenode的50070 端口 比如 hadoop46:50070      另外一个参数 fs.checkpoint.dir 必须制定到一个确定的目录,否则其默认目录是${hadoop.tmp.dir}/dfs/namesecondary 再下次重启将会清空这个目录      另外还有一个参数 dfs.secondary.http.address 必须明确指定 secondaryNamenode 的地址 比如 Hadoop47:50090      上述三个参数强烈建议修改,否则SecondaryNamenode 不会正常运作,但是hadoop集群却可以跑起来,但灾难恢复无法实现。      另外我们需要了解SecondaryNamenode 每隔固定的时间做一次检查点,这个时间可手动设定fs.checkpoint.period 默认是3600 单位秒 也就是每一个小时做一次检查点。      这个图有必要贴到下面:                      我的极简理想服务器组成结构如下(至少要6个server的集群):      
服务器 守护进程 说明
server1 namenode namenode节点
server2 jobtracker 任务主节点
server3 secondary namenode secondary namenode
dserver1 datanode tasktracker 数据节点
dserver2 datanode tasktracker 数据节点
dsdrver3 datanode tasktracker 数据节点
     数据块block      上面说到了HDFS数据块的概念 默认是64M 也就是参数dfs.block.size 这个block其实是HDFS读写的最小单位,但HDFS中可能有很多小文件不足64M,那会占用多大的空间呢?根据它实际的文件大小占用合适的空间,不多占用。为什么一个块设置这么大,linux文件系统从512k 到4M不等,64M对于后者来说,可以用巨大来形容。那为什么这么设置呢?      其最主要目的是减少寻址开销,块设置的      
     (二)、MapReduce方向      JobTracker:跟NameNode 相比这个就是MapReduce 的master      负责调度分配每一个子任务task运行于TaskTracker上,如果发现有失败的task就重新分配其任务到其他节点。一般情况应该把JobTracker部署在单独的机器上。JobTracker与TaskTracker有心跳维系。      TaskTracker:TaskTracker 负责JobTracker分配的任务的运行(干活的)。      TaskTracker是运行在多个节点上的slaver服务。TaskTracker主动与JobTracker通信,接收作业,并负责直接执行每一个任务,为了减少网络带宽TaskTracker最好运行在HDFS的DataNode上。    说到作业了,自然离不开作业调度器,阐述一下MapReduce Job的作业调度器。      I、MapReduce默认的作业调度器是FIFO 即先进先出的:      即来了作业即把任务Put进一个队列中,然后异步任务会从这个队列中取出要执行的任务,遵循先进先出的规则。在这个FIFO中MapReduce支持把任务设置优先级,共分为5个优先级,但Job不支持抢占slot 所以设置的优先级就是让其插队,在没有运行的task中插队,已经在运行的task不做干预。这样能保证优先级高的任务提前运行。      1、VERY_HIGH      2、HIGH      3、NORMAL  默认是NORMAL 优先级。      4、LOW      5、VERY_LOW    II、Fair Scheduler(公平调度器)      针对FIFO 来说不能很好的平衡多用户的作业调度。      多用户作业中,每个作业都被放在每个用户自己的作业池中,提交作业数超过另外一个用户的用户,不会因此而比后者获得更多的集群资源,可以用map和reduce任务槽数来定制作业池的最小容量,也可以将每个池设置全中。      Fair Scheduler 支持抢占,如果一个池在特定的一段时间内未得到公平的资源共享,它会中止(暂停)运行池中的得到过多资源的任务,以便把任务槽让给其它运行资源不足的池。需要设置属性 mapred.jobtracker.taskScheduler 设置为org.apache.hadoop.mapred.FairScheduler      上面是基本概念,具体配额在什么地方设置:      公平调度器有两处配置文件——算法参数在mapred-site.xml中设置,还有一个单独的称为配额文件(allocation file)的XML文件(fair-scheduler.xml),可以用来配置资源池、最小共享资源、运行作业限制和抢占超时时间。配额文件在运行期间会定期被重新加载,这可以让你修改资源池的设置而不用重启Hadoop集群。          对于仅需要在用户间获取等同共享的最小化安装,你就不需要去配置配额文件了。如果对配额文件进行了配置,你需要设置mapred-site.xml中的mapred.fairscheduler.allocation.file(下面描述)参数告诉调度器怎么去找到配额文件。如${HADOOP_CONF_HOME}/fair-scheduler.xml           公平调度器支持批量分配作业到相应的任务节点,但对于小的作业来说,反而造成任务的不均衡,比如只有6个task 我设置同时分配6个task到不同的节点,反而造成单一节点太忙碌,而其他节点无任务分配。           更多的说明再发行版的文档中有更多的介绍,此处了解概念即可。      III、Capacity Scheduler(计算能力调度器)(部分摘自董的博客),简单介绍,多了不说,我不是十分了解底层的结构。           Capacity Scheduler 支持一下特性:           (1)计算能力保证。支持多个队列,某个作业可被提交到某一个队列中,每个对列可配置一定比例的计算资源。且所有提交到队列中的作业共享该队列中的资源           (2)灵活性。空闲资源会分配到那些未达到资源使用上限的的队列,当某个未到达资源上限的队列需要资源时,一旦出现空闲资源时,便会分配给他们。           (3)支持优先级。在单一队列中支持作业优先级调度,这点跟简单FIFO优先级调度是一致的。           (4)多重租赁。综合考虑多个约束,防止单个作业、用户独占队列或者集群中的资源           (5)基于资源调度。支持资源密集作业,允许作业资源的使用量高于默认值,进而可容纳不同资源需求的作业,当前仅支持内存资源的调度。           同样需要在mapred-site.xml中配置 mapred.jobtracker.taskScheduler 设置为 org.apache.hadoop.mapred.CapacityScheduler           如需简单基本最小化安装,不需要配额文件,否则跟Fair Scheduler 一样需要设置配额文件           mapred.fairscheduler.allocation.file 来指定配额文件 Capacity 配额文件  capacity-scheduler.xml  如:${HADOOP_CONF_HOME}/capacity-scheduler.xml

相关内容