美文网首页
2-HDFS(分布式文件系统)

2-HDFS(分布式文件系统)

作者: 小帅明3号 | 来源:发表于2022-04-06 10:12 被阅读0次

    一、简介

    • 简介
      HDFS是Hadoop非常重要的核心之一,它也是由Doug Cutting基于Google公司03年10月开源的论文GFS做的开源实现,发展到目前为止,HDFS的运用非常广泛,基本上很多大数据平台大部分都会选用HDFS(或者类似HDFS)这样的分布式文件系统、来作为海量数据存储的一个解决方案。
      最初在设计HDFS时的背景是当时设备的存储和读写性能都很差,并且单一设备运行稳定性低的情况,于是HDFS在设计之初就是为了解决大规模、海量数据的存储以及读写,并且尽可能的保证设备的稳定性。
      image.png
    • 优缺点
      HDFS的优势有哪些?
      1. 高容错性,HDFS提供了非常好的“副本冗余机制”,简单来说就是一份数据在HDFS当中存放,包含它自身在内至少会有(默认)三个副本类似随机的存放在集群不同的服务器上,并且当其中一台服务器宕机、当前这台服务器上数据丢失,但HDFS会自动再将缺失的副本再通过copy的方式、保证数据的副本不会低于三个。
      2. 可构建在廉价的商业服务器上,基于第一条高容错性的优势,HDFS可以搭建在低成本的廉价服务器上,而没有必要选择非常昂贵的服务器上,因为即使廉价服务器稳定性相对较差,但是集群规模成百上千台宕机一台、两台对于整个HDFS集群来说,基本上没有任何的影响。
      3. 适合海量数据存储,分布式架构设计、HDFS可支持几万台服务器的集群规模,乘以每台服务器磁盘容量、整个HDFS文件系统容量非常之大,并且他所支持存放的单个数据文件GB、TB、PB级别都没有任何问题。
      4. 适合批处理,它是通过“移动计算而非移动数据”来进行设计,会把数据存放位置暴露给计算框架,从而在海量数据计算过程中,数据在何处便在何处计算,避免了数据跨网络、结点移动拷贝的工作,很大限度的提升计算速度。
      5. 流式数据访问,一次写入、多次读取。文件一旦写入完成、不能修改,仅仅只支持追加。保证了数据的一致性。
      以上便是HDFS的一些优势,基于这些优势HDFS适用于以下几个场景:
      1. 适合大文件存储、海量数据存储
      2. 适合批量数据访问
      HDFS适用于“大文件存储、海量数据存储”、“批量数据访问”这些场景,但是HDFS本身设计上也有他的劣势、或者不擅长的一些场景:
      1. 低延时数据访问,这里的“低延时”指的是例如毫秒级别要将数据写入HDFS、或毫秒级别读取HDFS内数据,这个它是做不到的。它的优势是在“高吞吐率”的场景,也就是在某一时间内大量写入、读取数据,但是毫秒级这种低延时它是支持不了的。
      2. 并发写入、随机修改,HDFS当中文件只能有一个写、不支持多个线程同时写入一个文件。写好的文件只支持追加功能,并不支持文件的随机写入。
      3. 小文件存储,小文件问题是大家在大数据领域需要格外注意的问题。首先撇开HDFS来说,假如10GB数据容量,10个1GB的数据集、1w个1M的数据集,占用存储空间相同,让你在这两种数据集中找到其中一个数据文件,明显第二种场景非常耗时,也就是说小文件存储之后,在寻址的时间开销会非常之高、以至于会高于读取时间。此外,回到HDFS当中来考虑,HDFS当中每一个数据文件都会对应有一份元数据信息需要存放,大家可以把元数据信息先简单理解为就是文件的一些基本信息(如文件名称、大小、权限等),一个文件对应一条元数据信息,当你存储的都是一些小文件、文件个数会急速增长,对应元数据也就需要更多的空间来存储,并且元数据是在内存介质中存储,这样一来会非常浪费内存资源、显然是不适用的。所以,在使用HDFS过程当中一定要注意“小文件”的这个问题。
      image.png

    二、原理

    • 系统架构
      首先HDFS的架构是一个经典的主/从架构设计,在这张图当中NameNode是主节点,DataNode是从节点,HDFS Client是客户端、HDFS提供了比较丰富的客户端像cli、api、gui等等支持,SecondaryNameNode相当于辅助NameNode工作的一个节点、但并不是NameNode的备份结点(这个一定要注意区分)。
      NameNode,他作为主从架构当中的主节点,其实主要负责接受客户端提交过来的读写请求、以及一些类似管理的工作,比如说,数据存到HDFS当中每个文件都会对应一份元数据信息(先可以简单认为元数据信息记录了文件的一系列基本属性、后边紧接着会展开介绍),这些元数据信息都是存放在NameNode的内存区域内、由NameNode来进行维护。
      DataNode,他作为一个从节点出现,主要负责数据的存放。数据文件写入到HDFS当中会切分为小的数据块block(也就是图中DataNode方框中紫色、橙色、红色等小的方块),这些数据块会存放在DataNode节点上。在一个HDFS集群当中DataNode结点可以有任意多台,当然要根据你文件系统的数据量来确定,并且后期如果容量不足的情况下,也支持DataNode结点动态添加、扩容。
      NameNode与DataNode之间的连线,DataNode在运行过程当中一直会和NameNode结点保持通信。一方面,在DataNode启动时,会给NameNode上报自己服务器上有哪些数据块、也就是block的位置存放信息,NameNode接收到这些block位置信息会维护好一份完整的元数据信息,从而找到具体数据存放在哪些DataNode上;另一方面,运行过程当中,DataNode会每隔3秒定时和NameNode做一次心跳,从而NameNode可以知道DataNode的运行状况。
      image.png
      一个10G的文件上传到HDFS中,首先,会在客户端处进行切分,切分成一个个Block块,默认情况下Block块的大小是128M。
      这些切分后的Block块,会以多副本的形式均匀放置到DataNode中。
      数据存放在DataNode中后,主节点NameNode需要知道这份文件具体切分了多少Block块和每个Block块具体存放的位置。所以NameNode节点保存有一份元数据来记录这些信息。
      image.png
      ActiveNameNode是主节点,它的具体功能是管理整个集群,是当前活动的管理节点。
      作为管理节点,管理命名空间和元数据信息,管理Block副本策略。并处理客户端读写请求,为DataNode分配任务。
      Standby Namenode是Master的热备节点,并负责定期合并元数据文件
      image.png
      NameNode元数据文件分为edits和fsimage。在内存中最新的元数据是fsimage和edits的合并。Standby NameNode会定期将fsimage和edits合并成一个新的fsimage文件,保证edits文件不会特别大。
      DataNode是Slave节点,具体功能请见PPT的描述部分。
      image.png
      Block数据块是HDFS最小存储单元,文件写入HDFS时会被切分成若干个Block,默认为128M,且备份3个副本。
      Client是客户端,包括文件切分,并与NameNode和DataNode进行交互,从NameNode获取元数据信息,向DataNode交互进行数据的读取或写入。
      image.png
    • 存储机制
      Block是HDFS的最小存储单元,默认大小为128M,可以自定义修改,但是要注意修改的一些影响,块太大和太小都可能会影响性能。
      Block存储到DataNode上,会以多副本的形式进行存储,默认副本数为3,通过机架感知和副本均匀分布的策略保证数据的高可用性。数据存储之后,对应的元数据会保存在NameNode中。
      image.png
      Block文件在DataNode本地磁盘中的目录结构。其中:
      ·BP-random integer-NameNode-IP address-creation time:BP代表BlockPool,就是Namenode的VERSION中的集群唯一blockpoolID
      ·finalized/rbw:其中finalized目录用于实际存储Block文件,finalized用于存 放Block文件以及Block元数据文件;rbw是“replica being written”的意思,该目录用于存储用户当前正在写入的数据
      ·VERSION:VERSION文件是java属性文件,保存了HDFS的基本信息
      ·blk_前缀文件:HDFS中的文件块本身,存储的是原始文件内容
      ·in_use.lock:防止一台机器同时启动多个Datanode进程导致目录数据不一致
      image.png
      block切分之后,会有三个副本,三个副本之间完全都是一样的没有任何区别,注意他们之间并没有“主备”这样的区分。他们会存放到不同的DataNode节点上。如图所示,左右两个为两个机架,在机架上分别放置多台服务器作为DataNode。block在放置的时候,如果默认为三个副本,首先,第一个随机选择一台负载比较低、资源比较空闲的DataNode;然后,第二个会在不同的机架上随机找一台服务器;最后,第三个会在和第二个副本服务器相同的机架上,找另外一台服务器存放。
      image.png
      元数据信息持久化,包含有两种文件:第一个是fsimage文件,大家可以把它理解为是一个内存的快照,他会将内存当中除去block位置存放信息之外的所有元数据信息持久化写到一个磁盘当中的文件内;第二个是edits文件,这种文件可以理解为是日志记录文件。为什么有了fsimage内存快照、还需要有edits文件呢?因为如果每次对于文件系统有操作,元数据信息就有可能发生变化,那么每次变化都去更新一下fsimage文件,显然成本非常之高而且性能也不好,所以fsimage并不会实时去发生变化,那么后边这些操作则通过edits文件做一个记录。
      image.png
      元数据持久化文件在DataNode本地磁盘中的目录结构:
      • fsimage_前缀文件:即fsimage文件,之所以有多个是因为他定时要做合并,所以会保留有多份fsimage文件
      • edits_前缀文件:即edits文件。
      • VERSION:VERSION文件是java属性文件,保存了HDFS的基本信息
      • seen_txid:是存放transactionId的文件,format之后是0,它代表的是namenode里面的edits_*文件的尾数,namenode重启的时候,会按照seen_txid的数字,循序从头跑edits_0000001~到seen_txid的数字。
      看一下他们的名称命名规则,fsimage名称中一大串数字是合并时的一个id标识,edits文件名当中通过下划线分割前后分别代表合并前、后的id标识。
      image.png
      如图所示,左右分别为NameNode以及SecondaryNameNode。整个合并流程为,NameNode在磁盘中有fsimage,集群在运行过程当中,客户端各项操作记录会写入到edits文件内,当触发合并时,SecondaryNameNode会主动从NameNode中通过HttpGet方式将edits和fsimage文件拷贝并存放在本地磁盘中,然后开始合并,合并过程其实就是将该fsimage加载到内存当中,然后逐条执行edits日志中的各项操作、来更新内存里的元数据信息,全部日志执行完成后,此时内存当中的元数据信息便是触发合并那个时间点一份完整的元数据信息,再往后,SecondaryNameNode将内存当中元数据持久化(做快照)产生一个新的fsimage文件,再通过Http Post方式将这个新的fsimage文件发送给NameNode,NameNode接收到新的fsimage文件启用新的fsimage文件。并且在触发合并的时候,NameNode除会把fsimage、edits交给SecondaryNameNode去合并,与此同时还会生成一个空的edits文件,SecondaryNameNode在做合并的整个过程中,所有客户端的操作都会记录在这个新的空edits文件中,直到SecondaryNameNode把新的fsimage文件推给NameNode,NameNode会同时将新的fsimage、以及新的edits文件启用整个合并过程完成结束。
      这边是HDFS元数据合并的机制,在运行过程中HDFS会定期触发整个合并流程,从而会保证fsimage文件越来越大、但edits文件会在比较的一个范围内,这样一个效果。
      image.png
    • 读写操作
      写流程详细描述:客户端在写文件时,首先通过FileSystem的create函数发出创建文件请求,Distributed FileSystem通过RPC协议将该请求发送给NameNode,NameNode此时会对写请求做权限判断,不满足权限则直接返回,满足则在文件系统的命名空间中创建一个新的文件,Distributed FileSystem返回DFSOutputStream给客户端,用于写数据,DFSOutputStream在客户端将数据分成block块,写入Data Queue,之后由Data Streamer读取,然后通知NameNode节点分配DataNode,用来存储数据块,每块默认备份3块,被分配的Datanode放到一个pipeline里面。Data Streamer将数据块写入pipeline中的第一个数据节点,第一个DataNode将数据块发送到第二个DataNode,第二个DataNode将数据块发送给第三个DataNode。DFSOutputStream将已经发送出去的数据块保存在ack queue,等待pipeline中的Datanode告知数据是否写入成功。如果数据在写入DataNode的过程中失败,则首先关闭pipeline,将ack queue中的数据块放入data queue的开始,当前正在写入的Datanode被NameNode标示,失效的Datanode在重启后能察觉到该数据块是过时的,会删除该数据块,而失效的DataNode会从pipeline中移除,data queue中剩余的数据块会写入pipeline中的另外两个Datanode中。在写入完毕后close FSDataInputStream,并通知NameNode写入完毕。
      image.png
      image.png
      读流程详细描述:客户端在读取文件时,首先通过FileSystem的open函数发出打开文件请求,Distributed FilesSystem通过RPC协议将该请求发送给NameNode,获得存放文件的数据块信息,对于每一个数据块,NameNode都会返回所有保存数据块的DataNode的地址,客户端会从网络拓扑最近的那个DataNode中读取数据块。Distributed FileSystem会将从选出的最近的DataNode上打开一个FSDataInputStream并返回给客户端,用来读取数据。客户端通过调用FSDataInputStream的read函数开始读取数据,当此block数据块读取完毕后,关闭此流与DataNode的连接,然后连接此文件下一个block数据块距离最近的DataNode,然后进行读取。当客户端读取完毕数据后,调用FSDataInputStream的close函数,关闭该流。
      image.png
      image.png
    • 安全模式
      安全模式是HDFS所处的一种特殊状态,在这种状态下,文件系统只接受读数据请求,而不接受删除、修改等变更请求。在NameNode主节点启动时,HDFS首先进入安全模式,DataNode在启动的时候会向namenode汇报可用的block等状态,当整个系统达到安全标准时,HDFS自动离开安全模式。
      核心的配置项:dfs.namenode.safemode.threshold-pct: 副本数达到最小要求的block占系统总block数的百分比,当实际比例超过该配置后,才能离开安全模式(但是还需要其他条件也满足)。默认为0.999f,也就是说符合最小副本数要求的block占比超过99.9%时,并且其他条件也满足才能离开安全模式。如果为小于等于0,则不会等待任何副本达到要求即可离开。如果大于1,则永远处于安全模式。其他配置项一般默认不启用,先不做讨论。
      image.png
      触发安全模式的原因有多种,其实本质上是导致了上报率缺失。
      故障排查可以有多种方式,如果是DataNode挂掉,则需要将DataNode进行重启,如果是NameNode磁盘空间不足,需要清理NameNode磁盘。
      image.png
    • 高可用
      HDFS在设计上有一些优势和劣势,劣势主要是NameNode内存受限,可以使用联邦机制解决。NameNode单点故障的问题,可以用HA解决。
      image.png
      Hadoop2.x中对NameNode实现了高可用。思考一下PPT中实现高可用的细节问题。
      image.png
      高可用的本质是在主节点宕机之后,从热备节点可以立马代替宕机的主节点接管集群,保证服务是不中断的。那对于NameNode来说,如果要立马接管集群并且保证服务不中断,那就需要元数据保持一致。
      在QJM这种高可用方案中,Journal集群可以实现edits共享,实现Master主备节点的元数据同步。
      Journal集群需要部署奇数台,每次edits文件的写入都需要半数以上的节点返回成功才代表成功。保证edits元数据文件的高可用。
      image.png
      如图所示:
      3、 我们可以看到此时集群一共有两台NameNode、分别处于Active、Standby状态,Active状态的NameNode相当于处于工作状况、对集群负责管理并且接受客户端请求,另外一台Standby状态的NameNode处于一个等待状况如果Active的出现问题由它来负责接管集群。
      4、 JournalNode集群,它负责管理NameNode日志edits文件的管理,也就是ActiveNameNode写日志是直接写入到JournalNode集群上。
      5、 ZKFC – ZookeeperFailoverController,每台NameNode服务器上都会运行一个ZKFC进程,主要负责两个任务:监控当前NameNode运行状况信息、与Zookeeper集群保持心跳并将这些信息汇报给Zookeeper集群;控制NameNode Active、Standby状态的切换管理。
      6、 Zookeeper集群,实际中也是部署2N+1台,核心也是通过Paxos算法,在HDFS集群中主要负责接收到ZKFC汇报的NameNode健康信息做“选举”,“选举”哪一台NameNode应该是Active状态。
      7、 最下边是DataNode集群,负责数据的存储,但是区别于1.x的设计、在2.x集群中DataNode上报block信息会同时上报给两台NameNode。
      HDFS运行过程中,如果Active的NameNode运行出现故障,此时当前NameNode上的ZKFC会将异常的健康信息汇报给Zookeeper集群,或者NameNode这台服务器宕机,Zookeeper集群长时间接收不到ZKFC的数据,都会得知第一台NameNode运行出现了问题。此时,Zookeeper集群会做选举、推选第二台NameNode作为Active的NameNode来接管集群,之后Zookeeper先通知给第二台NameNode上的ZKFC,由ZKFC将当前这台NameNode状态从Standby切换为Active。fsimage文件在第二台NameNode上有一份,运行过程中edits文件一直写在JournalNode集群上、第二台NameNode可以直接拿到这些edits文件,状态切换之后,便可以先将fsimage加载内存,然后一条一条执行edits日志内容,并且集群在运行过程中DataNode会将各自服务器上block信息汇报给第一台和第二台,第二台上缓存有这些block信息再将它和内存当中部分原数据信息进行拼接。当这些操作全部执行完成之后,此时第二台NameNode内存当中元数据信息和第一台NameNode出现故障时内存当中元数据信息完全一致,这样整个HA便达到了。
      image.png

    三、操作命令

    文件系统命令语法详见PPT描述。有hadoop fs和hdfs dfs两种命令,hadoop fs使用广泛,除了可以操作Hdfs还可以操作本地文件系统。hdfs dfs则只能操作hdfs文件系统。
    因为要操作HDFS,所以需要使用URI来定位HDFS位置。URI的具体格式见PPT中描述。如果配置了hdfs客户端,则可以使用简写的形式,否则需使用全写形式。


    image.png

    对hdfs的操作命令详见PPT中所示。这些命令与shell操作本地文件系统是很相似的。只是多了hadoop fs或hdfs dfs这样的“前缀”。


    image.png
    对hdfs的操作命令详见PPT中所示。这些命令可以按照对linux文件系统的操作进行类比。
    image.png

    四、运维管理

    • 命令管理
      hdfs namenode [-format [-clustered cid] [-force] [-nonInteractive] ] | [-recover [-force] ] 一般我们不需要操作,可能高权限的系统管理员才会用到。
      image.png
      hdfs namenode -report 查看关于HDFS集群容量及占用空间大小、DataNode运行状况、各节点磁盘使用情况等信息的报告。
      image.png
      hdfs fsck – 全称file ststem check,用于检查HDFS上文件和目录的健康状态、获取文件的block块信息和位置信息等。
      image.png
      使用FSCK检查文件系统状况,可以看到文件系统具体的Block情况,主要关注Corrupt blocks这个参数,表示坏块的数量。
      image.png
      image.png
      Decommission or Recommission 退役、服役,命令行使用较少,web方式可能使用较多。命令行方式执行时需要先定义好退役的节点,在hdfs-site.xml中通过dfs.hosts.exclude项指定配置文件目录,执行hdfs dfsadmin –refreshNodes命令,执行过程中后台会进行block的移动,将即将退役的节点上将block移动到其他DataNode节点。
      image.png
      在Transwarp Manager中可以使用图形化界面进行退役和服役的操作。上下箭头分别代表服役和退役。
      image.png
      hdfs balancer 各DataNode block分配均匀、负载均衡。场景:集群新增节点之后,新节点上block分配相对较少,这时候可以通过该命令让各个DataNode上block分配相对均匀一些。
      image.png
      可以使用数据重分布命令进行数据重分布的操作。
      image.png
      数据重分布的带宽默认限制在1M/s,可以使用命令修改数据重分布的带宽
      image.png
      可以使用分布式拷贝命令可以在hdfs集群之间进行大规模数据拷贝,数据在拷贝时使用的会使用mapreduce进行处理。
      image.png
      可以使用命令对HDFS进行配额限制,限制目录下的文件数量和文件大小。
      image.png
      使用命令进行配额限制。
      image.png
      image.png
      对HDFS目录进行快照的操作,快照会存储在源文件夹下命名为.snapshot/,恢复时直接cp拷贝即可。
      image.png
    • 系统监控
      image.png
      可以在50070端口查看原生WEB监控界面。
      image.png

    相关文章

      网友评论

          本文标题:2-HDFS(分布式文件系统)

          本文链接:https://www.haomeiwen.com/subject/lrnncrtx.html