Hadoop学习笔记

By | 2018年11月26日
版权声明:本文为博主原创文章,转载请注明出处、链接,谢谢。 https://blog.csdn.net/jinliwei1990/article/details/54408067


Hadoop学习笔记

hadoop生态圈
图1 Hadoop架构


Hdfs

Hdfs简介

Hdfs与Hadoop的关系

  Hadoop是一个以一种可靠、高效、可伸缩的方式进行处理的,能够对大量数据进行分布式处理的系统框架。
  Hdfs是开源的,存储着Hadoop应用将要处理的数据,类似于普通的Unix和linux文件系统,不同的是它是实现了google的GFS文件系统的思想,是适用于大规模分布式数据处理相关应用的、可扩展的分布式文件系统。
  Hdfs( Hadoop Distributed File System)是Hadoop项目的核心子项目,是分布式计算中数据存储管理的基础,是基于流数据模式访问和处理超大文件的需求而开发的,可以运行于廉价的商用服务器上。
  它所具有的高容错、高可靠性、高可扩展性、高获得性、高吞吐率等特征为海量数据提供了不怕故障的存储,为超大数据集( Large DataSet)的应用处理带来了很多便利。
  Hdfs是hadoop兼容最好的标准级文件系统。Hadoop是一个框架, HDFS是Hadoop中的一个部件。整个Hadoop的体系结构主要是通过HDFS来实现对分布式存储的底层支持,并通过MapReduce来实现对分布式并行任务处理的程序支持。

Hdfs设计目标

  Hadoop Distributed filesystem是一种分布式应用底层框架,并非单纯用于存储。其设计前提与主要目标是:

  1. 用于海量存储,必须具有良好的可扩展性。
  2. 硬件故障有平常,必须保证:
  3. 自动容错
  4. 故障探测与处理
  5. 数据安全性
  6. 系统可用性
  7. 一次写入多次读取模式
  8. 以文件访问的高吞吐量为目标
  9. 与MapReduce框架紧密结合

Hdfs的优缺点

Hdfs的优点
  1. 处理超大文件
      这里的超大文件通常是指百MB、设置数百TB大小的文件。目前在实际应用中, Hdfs已经能用来存储管理PB级的数据了。
  2. 流式的访问数据
      Hdfs的设计建立在更多地响应“一次写入、多次读写”任务的基础上。这意味着一个数据集一旦由数据源生成,就会被复制分发到不同的存储节点中,然后响应各种各样的数据分析任务请求。在多数情况下,分析任务都会涉及数据集中的大部分数据,也就是说,对Hdfs来说,请求读取整个数据集要比读取一条记录更加高效。
  3. 运行于廉价的商用机器集群上
      Hadoop设计对硬件需求比较低,只须运行在低廉的商用硬件集群上,而无需昂贵的高可用性机器上。廉价的商用机也就意味着大型集群中出现节点故障情况的概率非常高。这就要求设计Hdfs时要充分考虑数据的可靠性,安全性及高可用性。
Hdfs的缺点
  1. 不适合低延迟数据访问
      如果要处理一些用户要求时间比较短的低延迟应用请求,则HDFS不适合。 HDFS是为了处理大型数据集分析任务的,主要是为达到高的数据吞吐量而设计的,这就可能要求以高延迟作为代价。
      改进策略:对于那些有低延时要求的应用程序, HBase是一个更好的选择。
  2. 无法高效存储大量小文件
      因为Namenode把文件系统的元数据放置在内存中,所以文件系统所能容纳的文件数目是由Namenode的内存大小来决定。一般来说,每一个文件、文件夹和Block需要占据150字节左右的空间,所以,如果你有100万个文件,每一个占据一个Block,你就至少需要300MB内存。当前来说,数百万的文件还是可行的,当扩展到数十亿时,对于当前的硬件水平来说就没法实现了。
      改进策略:

    • 利用SequenceFile、MapFile、Har等方式归档小文件,这个方法的原理就是把小文件归档起来管理,HBase就是基于此的。对于这种方法,如果想找回原来的小文件内容,那就必须得知道与归档文件的映射关系。
    • 横向扩展,一个Hadoop集群能管理的小文件有限,那就把几个Hadoop集群拖在一个虚拟服务器后面,形成一个大的Hadoop集群。
    • 多Master设计,这个作用显而易见了。正在研发中的GFS II也要改为分布式多Master设计,还支持Master的Failover,而且Block大小改为1M,有意要调优处理小文件。
  3. 不支持多用户写入及任意修改文件
      在HDFS的一个文件中只有一个写入者,而且写操作只能在文件末尾完成,即只能执行追加操作。目前HDFS还不支持多个用户对同一文件的写操作,以及在文件任意位置进行修改。

Hdfs的安全性和速度

  Hdfs以流处理访问模式来存储文件,在使用流处理方式下,每个文件在系统里都能找到它的本地化映像。将大文件分成一个个的小文件(文件块),并备份每个分块文件, 分块冗余,本地校验。冗余后的分块文件还有个额外功能,只要冗余的分块文件中有一份是完整的,经过多次协同调整后,其他分块文件也将完整。
  Hadoop是处理大数据的,因此hdfs假设用户提供的文件是巨大的,而且这些大文件是不用搬来搬去的。Hdfs提供文件的一次写入,多次读取
  专注读取功能,由多台机器同时读取,影响读取性能的是网络速度和机器读取速度,当集群数量巨大,文件巨大时, Hdfs的集群优势能得到发挥。

Hdfs的主要组件

  Hdfs体系结构中有两类节点:一类是NameNode,又叫”元数据节点”;另一类是DataNode,又叫”数据节点”。这两类节点分别承担Master和Worker具体任务的执行节点。
  Hdfs采用主从(Master/Slave)结构模型,一个Hdfs集群是由一个NameNode和若干个DataNode组成的(在最新的Hadoop2.2版本已经实现多个NameNode的配置-这也是一些大公司通过修改hadoop源代码实现的功能,在最新的版本中就已经实现了)。NameNode作为主服务器,管理文件系统命名空间和客户端对文件的访问操作。DataNode管理存储的数据。Hdfs支持文件形式的数据。
  元数据:又称中介数据、中继数据,为描述数据的数据(data about data),主要是描述数据属性(property)的信息,是数据的数据。
  元数据节点(namenode),用来管理文件系统的命名空间,将所有的文件和文件夹的元数据保存在一个文件系统树中。
  这些信息也会在硬盘上保存成以下文件:命名空间镜像(namespace image)及修改日志(edit log),还保存了一个文件包括哪些数据块,分布在哪些数据节点上。然而这些信息并不存储在硬盘上,而是在系统启动的时候从数据节点收集而成的。

元数据节点(NameNode)

  Namenode是一个中心服务器,在早期是单一节点,现在发展为多节点设计,负责管理文件系统的名字空间(namespace)以及客户端对文件的访问。
  NameNode负责文件元数据的操作,DataNode负责处理文件内容的读写请求,跟文件内容相关的数据流不经过NameNode,只会询问它跟那个DataNode联系,否则NameNode会成为系统的瓶颈。
  副本存放在那些DataNode上由NameNode来控制,根据全局情况做出块放置决定,读取文件时NameNode尽量让用户先读取最近的副本,降低带块消耗和读取时延
  Namenode全权管理数据块的复制,它周期性地从集群中的每个Datanode接收心跳信号和块状态报告(Blockreport)。接收到心跳信号意味着该Datanode节点工作正常。块状态报告包含了一个该Datanode上所有数据块的列表。
  安全模式是NameNode的一种状态,在这个阶段,文件系统不允许有任何修改。安全模式的目的是在系统启动时检查各个DataNode上数据块的有效性,同时根据策略对数据块进行必要的复制或删除,当数据块最小百分比数满足的最小副本数条件时,会自动退出安全模式。
  系统显示“Name node is in safe mode”,说明系统正处于安全模式,这时只需要等待20秒(或更多)即可,也可以通过下面的命令退出安全模式:– hadoop dfsadmin –safemode leave
  
  元节点的目录结构

  • VERSION文件是java properties文件,保存了HDFS的版本号。
  • fsimage文件,也即命名空间映像文件,是内存中的元数据在硬盘上的checkpoint,它是一种序列化的格式,并不能够在硬盘上直接修改。
  • 当文件系统客户端(client)进行写操作时,首先把它记录在修改日志中(edit log)
  • layoutVersion是一个负整数,保存了HDFS的持续化在硬盘上的数据结构的格式版本号。
  • namespaceID是文件系统的唯一标识符,是在文件系统初次格式化时生成的。
  • cTime
  • storageType表示此文件夹中保存的是元数据节点的数据结构。

从元数据节点( secondary namenode)

  从元数据节点并不是元数据节点出现问题时候的备用节点,它和元数据节点负责不同的事情。其主要功能就是周期性将元数据节点的命名空间镜像文件和修改日志合并,以防日志文件过大。合并过后的命名空间镜像文件也在从元数据节点保存了一份,以防元数据节点失败的时候,可以恢复。

数据节点(datanode)

  数据节点是文件系统中真正存储数据的地方。客户端(client)或者元数据信息(namenode)可以向数据节点请求写入或者读出数据块。其周期性的向元数据节点回报其存储的数据块信息。
  一个数据块在DataNode以文件存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。
  DataNode启动后向NameNode注册,通过后,周期性( 1小时)的向NameNode上报所有的块信息。
  心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个DataNode 的心跳,则认为该节点不可用。
  集群运行中可以安全加入和退出一些机器。
  
  数据节点的目录结构

  • blk_保存的是HDFS的数据块,其中保存了具体的二进制数据。
  • blk_.meta保存的是数据块的属性信息:版本信息,类型信息,和checksum
  • 当一个目录中的数据块到达一定数量的时候,则创建子文件夹来保存数据块及数据块属性信息。

文件

  Hdfs中的文件概念和与单磁盘文件系统相似,数据按照文件存储在集群中,由Hdfs统一管理。
  用户可以创建、删除、移动或重命名文件,当文件创建、写入和关闭之后不能修改文件内容。
  在Hdfs系统中,文件是分块存储的。块是存储的最小单位,Hdfs默认定义其大小为64MB。
  每个块有多个副本存储在不同的机器上,副本数可在文件生成时指定(默认3)。
  与单磁盘文件系统相似,存储在 HDFS上的文件均存储为多个块,不同的是,如果某文件大小没有到达64MB,该文件也不会占据整个块空间。
  在分布式的Hdfs集群上, Hadoop系统保证一个块存储在一个datanode上。
  从内部来看,文件被分成若干个数据块,这若干个数据块存放在一组DataNode上。NameNode执行文件系统的命名空间,如打开、关闭、重命名文件或目录等,也负责数据块到具体DataNode的映射。DataNode负责处理文件系统客户端的文件读写,并在NameNode的统一调度下进行数据库的创建、删除和复制工作。NameNode是所有Hdfs元数据的管理者,用户数据永远不会经过NameNode。

Hdfs数据流

HDFS体系结构图
图2 Hdfs数据流

  图4中涉及三个角色:NameNode、DataNode、Client。NameNode是管理者,DataNode是文件存储者、Client是需要获取分布式文件系统的应用程序。文件块的放置:一个Block会有三份备份,一份在NameNode指定的DateNode上,一份放在与指定的DataNode不在同一台机器的DataNode上,一根在于指定的DataNode在同一Rack上的DataNode上。备份的目的是为了数据安全,采用这种方式是为了考虑到同一Rack失败的情况,以及不同数据拷贝带来的性能的问题。
  
文件写入:

  1. Client向NameNode发起文件写入的请求。
  2. NameNode根据文件大小和文件块配置情况,返回给Client它管理的DataNode的信息。
  3. Client将文件划分为多个block,根据DataNode的地址,按顺序将block写入DataNode块中。

文件读取:

  1. Client向NameNode发起读取文件的请求。
  2. NameNode返回文件存储的DataNode信息。
  3. Client读取文件信息。 

不同节点管理不同的块信息
  NameNode是主节点,存储文件的元数据如文件名,文件目录结构,文件属性(生成时间,副本数,文件权限),以及每个文件的块列表以及块所在的DataNode等等。
  DataNode在本地文件系统存储文件块数据,以及块数据的校验和。
  
Namenode中记录了数据的信息
  NameNode是主节点,存储当我们执行hadoop fs -put aa.txt /bb.txt,则aa.txt会被复制为集群的/bb.txt。查看系统的log日志hadoop-$usernamenamenode-*.log,可以看到类似于:
  2014-09-07 08:39:12,506 INFO org.apache.hadoop.hdfs.StateChange: BLOCK* NameSystem.addStoredBlock: blockMap updated: 127.0.0.1:50010 is added to blk_5715489406767973176_1455 size 32
  这样的信息,里面记录有分配block的元数据信息和block号(blk_5715489406767973176)。
  
Datanode记录了具体的数据
  在另一个日志中hadoop-$username-datanode-*.log可以看到对应的datanode打印出相应的log:
  2011-09-07 08:39:12,495 INFO org.apache.hadoop.hdfs.server.datanode. DataNode: Receiving block blk_5715489406767973176_1455 src: /127.0.0.1:48492 dest: /127.0.0.1:50010
  HDFS的namenode只存储整个文件系统的元数据镜像,这个镜像由配置dfs.name.dir指定, datanode则存有文件的metainfo和具体的分块,存储路径由dfs.data.dir指定。


HBase

HBase简介

  最初HBase是Hadoop自身的数据库,是Google Bigtable的一个开源实现,HBase是个分布式的、面向列的数据存储模型。
HBase在Hadoop中的架构
图3 HBase在Hadoop中的架构

  • 列式数据库
  • 分布式的数据库
  • 严格一致性读写
  • 可以使用SHELL,WEB, API等方式访问
  • 高可用性
  • NoSQL数据库

HBase逻辑模型

  • 行健:唯一标识表中数据
  • 列族:若干个列(属性、限定符)的集合
  • 时间戳:标识数据的更新时间
  • 值:数据值
  • 更新:将修改后的数据以新版本的形式插入到表中。
  • 删除:将欲删除的数据以新版本的形式插入表中,并做删除标记。
    Hbase的逻辑模型
    图4 Hbase的逻辑模型

      HBase表可视为Key-Value表,Key: 行健+列族+列+时间戳,Value: 数据值,如:
      <key1+conlumn-family2+column1+t3, hello>
      <key2+conlumn-family2+column3+t3, dfdf>

与传统数据库差异

  1. Hbase适合大量插入同时又有读的情况。输入一个Key获取一个value或输入一些key获得一些value。
  2. Hbase的瓶颈是硬盘传输速度。Hbase的操作,它可以往数据里面insert,也可以update一些数据,但update的实际上也是insert,只是插入一个新的时间戳的一行。Delete数据,也是insert,只是insert一行带有delete标记的一行。Hbase的所有操作都是追加插入操作。Hbase是一种日志集数据库。它的存储方式,像是日志文件一样。它是批量大量的往硬盘中写,通常都是以文件形式的读写。这个读写速度,就取决于硬盘与机器之间的传输有多快。而Oracle的瓶颈是硬盘寻道时间。它经常的操作时随机读写。要update一个数据,先要在硬盘中找到这个block,然后把它读入内存,在内存中的缓存中修改,过段时间再回写回去。由于你寻找的block不同,这就存在一个随机的读。硬盘的寻道时间主要由转速来决定的。而寻道时间,技术基本没有改变,这就形成了寻道时间瓶颈。
  3. Hbase中数据可以保存许多不同时间戳的版本(即同一数据可以复制许多不同的版本,准许数据冗余,也是优势)。数据按时间排序,因此Hbase特别适合寻找按照时间排序寻找Top n的场景。找出某个人最近浏览的消息,最近写的N篇博客,N种行为等等,因此Hbase在互联网应用非常多。
  4. Hbase的局限。只能做很简单的Key-value查询。它适合有高速插入,同时又有大量读的操作场景。而这种场景又很极端,并不是每一个公司都有这种需求。在一些公司,就是普通的OLTP(联机事务处理)随机读写。在这种情况下,Oracle的可靠性,系统的负责程度又比Hbase低一些。而且Hbase局限还在于它只有主键索引,因此在建模的时候就遇到了问题。比如,在一张表中,很多的列我都想做某种条件的查询。但却只能在主键上建快速查询。所以说,不能笼统的说那种技术有优势。
  5. Oracle是行式数据库,而Hbase是列式数据库。列式数据库的优势在于数据分析这种场景。数据分析与传统的OLTP的区别。数据分析,经常是以某个列作为查询条件,返回的结果也经常是某一些列,不是全部的列。在这种情况下,行式数据库反应的性能就很低效。
      行式数据库:Oracle为例,数据文件的基本组成单位:块/页。块中数据是按照一行行写入的。这就存在一个问题,当我们要读一个块中的某些列的时候,不能只读这些列,必须把这个块整个的读入内存中,再把这些列的内容读出来。换句话就是:为了读表中的某些列,必须要把整个表的行全部读完,才能读到这些列。这就是行数据库最糟糕的地方。
      列式数据库:是以列作为元素存储的。同一个列的元素会挤在一个块。当要读某些列,只需要把相关的列块读到内存中,这样读的IO量就会少很多。通常,同一个列的数据元素通常格式都是相近的。这就意味着,当数据格式相近的时候,数据就可以做大幅度的压缩。所以,列式数据库在数据压缩方面有很大的优势,压缩不仅节省了存储空间,同时也节省了IO。(这一点,可利用在当数据达到百万、千万级别以后,数据查询之间的优化,提高性能,示场景而定)

MapReduce

MapReduce简介

  MapReduce框架是由一个单独运行在主节点上的JobTracker和运行在每个集群从节点上的TaskTracker共同组成。主节点负责调度构成一个作业的所有任务,这些任务分布在不同的不同的从节点上。主节点监视它们的执行情况,并重新执行之前失败的任务。从节点仅负责由主节点指派的任务。当一个Job被提交时,JobTracker接受到提交作业和配置信息之后,就会将配置信息等分发给从节点,同时调度任务并监控TaskTracker的执行。JobTracker可以运行于集群中的任意一台计算机上。TaskTracker负责执行任务,它必须运行在DataNode上,DataNode既是数据存储节点,也是计算节点。JobTracker将map任务和reduce任务分发给空闲的TaskTracker,这些任务并行运行,并监控任务运行的情况。如果JobTracker出了故障,JobTracker会把任务转交给另一个空闲的TaskTracker重新运行。
  HDFS和MR共同组成Hadoop分布式系统体系结构的核心。HDFS在集群上实现了分布式文件系统,MR在集群上实现了分布式计算和任务处理。HDFS在MR任务处理过程中提供了文件操作和存储等支持,MR在HDFS的基础上实现了任务的分发、跟踪、执行等工作,并收集结果,二者相互作用,完成分布式集群的主要任务。
  Hadoop上的并行应用程序开发是基于MR编程框架。MR编程模型原理:利用一个输入的key-value对集合来产生一个输出的key-value对集合。MR库通过Map和Reduce两个函数来实现这个框架。用户自定义的map函数接受一个输入的key-value对,然后产生一个中间的key-value对的集合。MR把所有具有相同的key值的value结合在一起,然后传递个reduce函数。Reduce函数接受key和相关的value结合,reduce函数合并这些value值,形成一个较小的value集合。通常我们通过一个迭代器把中间的value值提供给reduce函数(迭代器的作用就是收集这些value值),这样就可以处理无法全部放在内存中的大量的value值集合了。
MapReduce
MapReduce
  流程简而言之,大数据集被分成众多小的数据集块,若干个数据集被分在集群中的一个节点进行处理并产生中间结果。单节点上的任务,map函数一行行读取数据获得数据的(k1,v1),数据进入缓存,通过map函数执行map(基于key-value)排序(框架会对map的输出进行排序)执行后输入(k2,v2)。每一台机器都执行同样的操作。不同机器上的(k2,v2)通过merge排序的过程(shuffle的过程可以理解成reduce前的一个过程),最后reduce合并得到,(k3,v3),输出到HDFS文件中。
  在reduce之前,可以先对中间数据进行数据合并(Combine),即将中间有相同的key的<key,value>对合并。Combine的过程与reduce的过程类似,但Combine是作为map任务的一部分,在执行完map函数后仅接着执行。Combine能减少中间结果key-value对的数目,从而降低网络流量。


数据管理

Hive

  Hive是建立在Hadoop上的数据仓库基础架构。它提供了一系列的工具,用来进行数据提取、转换、加载,这是一种可以存储、查询和分析存储在Hadoop中的大规模数据机制。可以把Hadoop下结构化数据文件映射为一张成Hive中的表,并提供类sql查询功能,除了不支持更新、索引和事务,sql其它功能都支持。可以将sql语句转换为MapReduce任务进行运行,作为sql到MapReduce的映射器。提供shell、JDBC/ODBC、Thrift、Web等接口。优点:成本低可以通过类sql语句快速实现简单的MapReduce统计。作为一个数据仓库,Hive的数据管理按照使用层次可以从元数据存储、数据存储和数据交换三个方面介绍。

Pig:

  Pig的语言层包括一个叫做PigLatin的文本语言,Pig Latin是面向数据流的编程方式。Pig和Hive类似更侧重于数据的查询和分析,底层都是转化成MapReduce程序运行。区别是Hive是类SQL的查询语言,要求数据存储于表中,而Pig是面向数据流的一个程序语言。

参考文献

  1. Hive,Hbase,HDFS等之间的关系
  2. Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别
  3. Thinking in BigData(八)大数据Hadoop核心架构HDFS+MapReduce+Hbase+Hive内部机理详解

发表评论