分布式文件系统HDFS

分布式文件系统HDFS

HDFS是一个分布式文件系统,具有良好的扩展性、容错性以及易用的API。核心思想是将文件切分成等大的数据块,以多副本的形式存储到多个节点上。HDFS采用了经典的主从软件架构,其中主服务被称为NameNode,管理文件系统的元信息,而从服务被称为DataNode,存储实际的数据块,DataNode与NameNode维护了周期性的心跳,为了防止NameNode出现单点故障,HDFS允许一个集群中存在主备NameNode,并通过ZooKeeper完成Active NameNode的选举工作。HDFS提供了丰富的访问方式,用户可以通过HDFS shell,HDFS API,数据收集组件以及计算框架等存取HDFS上的文件。

一、分布式文件系统背景

在大数据场景中,存在两种解决方案:纵向扩展(scale-up)和横向扩展(scale-out)。
纵向扩展利用现有的存储系统,通过不断增加存储容量来满足数据增长的需求;
横向扩展则是以网络连接的节点为单位扩大存储容量(集群)。
由于纵向扩展存在价格昂贵、升级困难以及总存在物理瓶颈等问题,大数据领域通常会采用横向扩展方案。横向扩展的难点在于如何构建一个分布式文件系统,解决以下这些问题。

  • 因故障导致丢失数据:横向扩展集群中采用的节点通常是普通的商用服务器,因机械故障、网络故障、人为失误、软件bug等原因导致服务器宕机或服务挂掉是常见的现象,这就要求分布式文件系统能够很好地处理各种故障。(即良好的容错性)。
  • 文件通常较大:在大数据应用场景中,GB级别的文件是很常见的,且这样的文件数量极多,这与传统文件系统的使用场景是很不同的,这就要求分布式文件系统在IO操作以及块大小方面进行重新设计。
  • 一次写入多次读取:一部分文件是通过追加方式产生的,且一旦产生之后不会再随机修改,只是读取(且为顺序读取),也就是说,这些文件是不可修改的。

二、分布式文件系统

1、文件级别的分布式系统

基于现有文件系统的主从架构(Master/Slaves):给定N个网络互联的节点,每个节点上装有linux操作系统,且配有一定量的内存和硬盘,选出一个节点作为Master,记录文件的元信息,其他节点作为Slave,存储实际的文件。为了确保数据的可靠性,将每个文件保存到三个不同节点上。

当客户端(Client)需要写入一个文件时,首先与Master通信,获取文件存放节点列表,如果该文件是合法的(比如不存在重名文件等),则Master根据一定的负载均衡策略将三个节点位置信息发回客户端,这时客户端与这三个Slave节点建立网络连接,将文件写入对应的三个节点,读文件过程类似。
该系统从一定程度上能够解决分布式存储问题,但存在以下两个不足:
1)难以负载均衡:该分布式文件系统以文件为单位存储数据。由于用户的文件大小往往是不统一的,难以保证每个节点上的存储负载是均衡的。
2)难以并行处理:一个好的分布式文件系统不仅能够进行可靠的数据存储,还应考虑如何上层计算引擎高效的分析。由于数据是以文件为单位存储的,当多个分布在不同节点上的任务并行读取一个文件时,会使得存储文件的节点出口网络带宽成为瓶颈,从而制约上层计算框架的并行处理效率。

2、块级别的分布式系统

为了解决文件级别分布式系统存在的不足,块级别的分布式文件系统出现了,这类系统核心思想时将文件分成等大的数据块(128MB),并以数据块为单位存储到不同节点上,进而解决文件级别的分布式系统存在的负载均衡和并行处理问题。

  • master:负责存储和管理元信息,包括整个文件系统的目录树、文件的块列表,以及每个块存放节点列表等。
  • Slave:存储实际的数据块,并与Master维持心跳信息,汇报自身健康状态以及负载情况等。
  • Client:用户通过客户端与Master和Slave交互,完成文件系统的管理和文件的读写等。
    HDFS正是一种块级别的分布式文件系统。

分布式文件系统HDFS_第1张图片

三、HDFS基本架构

HDFS采用了主从架构,主节点被称为NameNode,只有一个,管理元信息和所有从节点,从节点称为DataNode,通常存在多个存储实际的数据块,HDFS各组件功能如下:
分布式文件系统HDFS_第2张图片

1.NameNode

NameNode是HDFS集群管理者,负责管理文件系统元信息和所有DataNode。
1)管理元信息:NameNode维护着整个文件系统的目录树,各个数据块信息等。
2) 管理DataNode:DataNode周期性向NameNode汇报心跳以表明自己活着,一旦NameNode发现某个DataNode出现故障,会在其他存活DataNode上重构丢失的数据块。

一个HDFS集群中只存在一个对外服务的NameNode,称为Active NameNode,为了防止单个NameNode出现故障后导致整个集群不可用,用户可启动一个备用NameNode,称为Standby NameNode,为了实现NameNode HA(High Availability,高可用),需解决好两者的切换和状态同步问题。
1)主/备切换:HDFS提供了手动方式和自动方式完成主备NameNode切换,手动方式是通过命令显示修改NameNode角色完成的,通常用于NameNode滚动升级。自动模式是通过ZooKeeper实现的,可在主NamNode不可用时,自动将备用NameNode提升为主NameNode,以保证HDFS不间断对外提供服务。

2)状态同步:主/备NameNode并不是通过强一致协议保证状态一致的,而是通过第三方的共享存储系统。主NameNode将EditLog(修改日志,比如创建和修改文件)写入共享存储系统,备用NameNode则从共享存储系统中读取这些修改日志,并重新执行这些操作,以保证与主NameNode的内存信息一致。

目前HDFS支持两种共享存储系统:NFS(Network File System)和QJM(Quorum Journal Manager),其中QJM是HDFS内置的高可用日志存取系统,其基本原理是用2N+1台JournalNode存储EditLog,每次写数据操作大多数(大于等于N+1)返回成功确认即认为该次写成功,该算法所能容忍的是最多有N台机器挂掉,QJM能够构建在普通商用机器之上,比NFS更加廉价,因此受众更广。

2.DataNode

DataNode存储实际的数据块,并周期性通过心跳向NameNode汇报自己的状态信息。

3.Client

用户通过客户端与NameNode和DataNode交互,完成HDFS管理(比如服务启动与停止)和数据读写等操作。文件的分块操作也是在客户端完成的。
当向HDFS写入文件时,客户端首先将文件切分成等大的数据块(默认一个数据块大小为128MB),之后从NameNode上领取三个DataNode地址,并在它们之间建立数据流水线,进而将数据块流式写入这些节点。

分布式文件系统HDFS_第3张图片
NameNode Federation机制:
随着数据块和访问量的增加,单个NameNode会成为制约HDFS扩展性的瓶颈,为了解决该问题,HDFS提供了NameNode Federation机制,允许一个集群中存在多个对外服务的NameNode,各自管理目录树的一部分(对目录水平分片)。需要注意的是,在NameNode Federation中,每个主NameNode均存在单点故障问题,需为之分配一个备用NameNode。为了向用户提供统一的目录命名空间,HDFS在NameNode Federation之上封装了一层文件系统视图ViewFs,可将一个统一的目录命名空间映射到多个NameNode上。

四、HDFS关键技术

1.容错性设计

HDFS内置了良好的容错性设计策略,以降低各种故障情况下数据丢失的可能性。

  • NameNode故障:NameNode内存中记录了文件系统的元信息,这些元信息一旦丢失,将导致整个文件系统数据不可用。HDFS允许为每个Active NameNode分配一个Standby NameNode,以防止单个NameNode宕机后导致元信息丢失和整个集群不可访问。
  • DataNode故障:每个DataNode保存了实际的数据块,这些数据块在其他DataNode上存在相同的副本。DataNode能通过心跳机制向NameNode汇报状态信息,当某个DataNode宕机后,NameNode可在其他节点上重构该DataNode上的数据块,以保证每个文件的副本数在正常水平线上。
  • 数据块校验:DataNode保存数据时,会同时生成一个校验码。当存取数据块时,如果发现校验码不一致,则认为该数据块已经损坏,NameNode会通过其他节点上的正常副本重构受损的数据块。

2.副本放置策略

数据块副本放置策略直接决定了每个数据块多个副本存放节点的选择,在保证写性能较优的情况下,尽可能提高数据的可靠性。

一个集群由多个机架构成,每个机架由16~64个物理节点组成,机架内部的节点是通过内部交换机通信的,机架之间的节点是通过外部节点通信的。
HDFS默认采用的三副本放置策略:

  • 客户端与DataNode同节点:上层计算框架处理HDFS数据时,每个任务实际上就是一个客户端,任务运行在与DataNode相同的计算节点上(HDFS和YARN同节点部署)。三副本放置策略如下:第一个副本写到同节点的DataNode上,另外两个副本写到另一个相同机架的不同DataNode上。
  • 客户端与DataNode不同节点:当HDFS之外的应用程序向HDFS写数据时,HDFS会随机选择一个DataNode作为第一个副本放置节点,其他两个副本写到另一个相同机架的不同DataNode上。

3.集中式缓存管理

HDFS允许用户将一部分目录或文件缓存在off-heap内存中,以加速对这些数据的访问效率,该机制被称为集中式缓存管理,引入带来了许多显著的优势:
1)提高集群的内存利用率。当使用操作系统的缓存时,对一个数据块的重复读会导致所有副本都会被放到缓冲区当中,造成内存浪费;当使用集中式缓存时,用户可以指定n个副本中的m个被缓存,可以节约n-m的内存。
2)防止那些被频繁使用的数据从内存中清除。
3)提高数据读取效率:

  • DataNode缓存统一由NameNode来管理,上层计算框架的调度器查询数据块的缓存列表,并通过一定的调度策略将任务尽可能调度到缓存块所在节点上,以提高数据读性能。
  • 当数据块被DatNode缓存后,HDFS以使用一个高效的、支持zero-copy的新API加快读速度,这是因为缓存中数据块的校验码已经被计算过,当使用新API时,客户端开销基本是零。

五、HDFS访问方式

HDFS提供了多种访问方式,包括HDFS Shell、HDFS API、数据收集组件(比如flume、Sqoop等)以及上层计算框架等。

1.HDFS shell

HDFS提供了两类shell命令:用户命令和管理员命令。
1)用户命令
HDFS提供了文件操作命令dfs、文件一致性检查命令fsck、分布式文件复制命令distcp.

  • 文件操作命令:文件操作命令是与文件系统交互的命令

在HDFS创建目录/user/input

bin/hdfs dfs -mkdir -p /user/input

2)管理员命令
管理员命令主要是针对服务生命周期管理的,比如启动/关闭NameNode/DataNode等

sbin/hadoop-daemon.sh start namenode
sbin/hadoop-daemon.sh stop namenode

2.HDFS API

HDFS对外提供了丰富的编程API,允许用户使用Java、python等语言(Thrift)编写应用程序访问HDFS。

3.数据收集组件

Sqoop:Sqoop允许用户指定数据写入HDFS的目录、文件格式(支持Text和SequenceFile两种格式)、压缩方式等

4.计算引擎

1)上层计算框架可通过InputFormat和OutputFormat两个可编程组件访问HDFS上存放的文件,其中InputFormat能够解析输入文件,将之逻辑上划分成多个可并行处理的InputSplit,并进一步将每个InputSplit解析成一系列key/value对;OutputFormat可将数据以指定的格式写入输出文件。
Hadoop为常见的数据存储格式分别设计了InputFormat和OutputFormat实现,以方便MapReduce、Spark等上层计算框架使用,比如Text文件的实现是TextInputFormat和TextOutputFormat,SequenceFile的实现是SequenceFileInputFormat和SequenceFileOutputFormat。

2)另一种访问HDFS数据的方式是SQL、HIVE、Impala等查询引擎均允许用户直接使用SQL访问HDFS中存储的文件。

六、HDFS配置文件详解

hdfs-site.xml

<configuration>

<property>
        <name>dfs.replicationname>
        <value>3value>
        <description>分片数量description>
property>



<property>
        <name>dfs.nameservicesname>
        <value>yfclustervalue>
        <description>为namenode集群定义一个services namedescription>
property>


<property>
        <name>dfs.ha.namenodes.yfclustername>
        <value>nn1,nn2value>
        <description>nameservice包含哪些namenode,为各个namenode起名description>
property>

<property>
        <name>dfs.namenode.rpc-address.yfcluster.nn1name>
        <value>kafka1:8020value>
        <description> 名为nn1的namenode 的rpc地址和端口号,rpc用来和datanode通讯description>
property>

<property>
        <name>dfs.namenode.rpc-address.yfcluster.nn2name>
        <value>kafka2:8020value>
        <description> 名为nn2的namenode 的rpc地址和端口号,rpc用来和datanode通讯description>
property>

<property>
        <name>dfs.namenode.http-address.yfcluster.nn1name>
        <value>kafka1:50070value>
        <description> 名为nn1的namenode 的http地址和端口号,web客户端description>
property>

<property>
        <name>dfs.namenode.http-address.yfcluster.nn2name>
        <value>kafka2:50070value>
        <description> 名为nn2的namenode 的http地址和端口号,web客户端description>
property>


<property>
        <name>dfs.namenode.secondary.http-addressname>
        <value>kafka2:50090value>
        <description>命名空间和事务在本地文件系统永久存储的路径description>
property>


<property>
        <name>dfs.namenode.shared.edits.dirname>
        <value>qjournal://kafka1:8485;kafka2:8485;kafka3:8485/yfclustervalue>
        <description>namenode间用于共享编辑日志的journal节点列表description>
property>


<property>
        <name>dfs.journalnode.edits.dirname>
        <value>/moudle/hadoop3/hdfs/journaldatavalue>
        <description>journalnode上用于存放edits日志的目录description>
property>


<property>
        <name>dfs.namenode.name.dirname>
        <value>/moudle/hadoop3/hdfs/namevalue>
		<description>在本地文件系统所在的NameNode的存储空间和持续化处理日志description>
property>


<property>
        <name>dfs.datanode.data.dirname>
        <value>/moudle/hadoop3/hdfs/datavalue>
        <description>数据节点的块本地存放目录description>
property>



<property>
        <name>dfs.ha.fencing.methodsname>
        <value>sshfencevalue>
        <description>配置隔离机制description>
property>


<property>
        <name>dfs.ha.fencing.ssh.private-key-filesname>
        <value>/root/.ssh/id_rsavalue>
        <description>密钥认证文件description>
property>


<property>
        <name>dfs.ha.automatic-failover.enabledname>
        <value>truevalue>
        <description>是否开启自动故障转移。建议开启,truedescription>
property>


<property>
        <name>dfs.client.failover.proxy.provider.yfclustername>
        <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvidervalue>
        <description>客户端连接可用状态的NameNode所用的代理类description>
property>


<property>
		<name>dfs.webhdfs.enabledname>
		<value>truevalue>
property>

<property>
		
		<name>dfs.journalnode.http-addressname>
		<value>0.0.0.0:8480value>
property>

<property>
		
		<name>dfs.journalnode.rpc-addressname>
		<value>0.0.0.0:8485value>
property>


<property> 

<name>dfs.permissions.enabledname> 
<value>truevalue> 
property> 


<property> 
		
		<name>dfs.namenode.acls.enabledname> 
		<value>truevalue> 
property>


<property>
    <name>fs.permissions.umask-modename>
    <value>032value>
property>

configuration>

core-site.xml


<property>
        <name>fs.defaultFSname>
        <value>hdfs://yfclustervalue>
property>


<property>
        <name>hadoop.tmp.dirname>
        <value>/moudle/hadoop3/tmpvalue>
property>


<property>
        <name>ha.zookeeper.quorumname>
        <value>kafka2:2181,kafka3:2181value>
property>


<property>
        <name>hadoop.http.staticuser.username>
        <value>rootvalue>
property>


<property>
        <name>dfs.permissions.enabledname>
        <value>falsevalue>
property>
configuration>

你可能感兴趣的:(大数据平台搭建,分布式文件系统,HDFS)