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

来源:互联网 发布:spark 编程 编辑:程序博客网 时间:2024/06/12 01:01
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的集群):
     
服务器守护进程说明server1namenodenamenode节点server2jobtracker任务主节点server3secondary namenodesecondary namenodedserver1datanode tasktracker数据节点dserver2datanode tasktracker数据节点dsdrver3datanode 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
0 0