【云驻共创】小白速看之HDFS分布式文件系统和ZooKeeper

网友投稿 709 2022-05-29

前言

本章主要讲解大数据分布式存储系统HDFS和解决分布式应用中经常遇到的一些数据管理问题的Zookeeper分布式服务框架。通过本章的学习,为后续组件学习打好基础。

大数据平台主要提供的是存储和计算能力。大数据的存储主要是由HDFS、HBase以及Hive等等组件来提供的,大数据平台的计算能力主要是由mapreduce、spark、Flink等等组件去提供的。其中大数据平台的计算场景的主要有批处理计算场景、流处理计算场景、实时响应查询的计算场景以及图计算场景。

zookeeper是大数据平台分布式一致性协调了服务组件,它为HDFS提供一种高可靠性的支撑服务。因此我们这一章把HDFS和zookeeper放在一起来进行讲解。

一、HDFS概述及应用场景

首先我们理解一下文件系统的含义。为了方便大家理解,我们把新华字典与文件系统进行了类比,其中新华字典中有目录、检字表,还有难检字的索引,对应的就是文件系统的文件名以及元数据(Metadata)。新华字典的字典正文就是对于文件系统的数据块,文件系统它主要是为了方便文件的查找以及管理,接下来我们对HDFS进行概述。

Hadoop分布式文件系统( HDFS)是一种旨在在商品硬件上运行的分布式文件系统。商品硬件就是我们一般所说的商用服务器。商用服务器相对于以前的小型机,它的价格更加低廉。

HDFS具有高度的容错能力,旨在部署在低成本硬件上。

HDFS提供对应用程序数据的高吞吐量访问,并且适用于具有大数据集的应用程序

HDFS放宽了一些POSIX要求,以实现对文件系统数据的流式访问。

HDFS最初是作为Apache Nutch Web搜索引擎项目的基础结构而构建的。

HDFS是Apache Hadoop Core项目的一部分。

HDFS和MapReduce是Hadoop最早的两个组件。

HDFS主要是用来存储网站数据,还有交通电子眼的数据,还有气象数据、传感器采集的数据。HDFS也不是万能的,有一些场景它并不适合,比如说需要实时响应的一些应用场景,HDFS就不太适合。HDFS并不适合存储大量的小文件,因为每一个文件的元数据大概是150kb,如果说一百万个小文件大概有300M。那么如果说一个小文件,它的元数据是非常巨大的,HDFS只采用单个节点来存储元数据,因此HDFS不适用于存储大量的小数据。HDFS也不适用于多用户写的场景以及随机写的场景,因为HDFS的数据是追加到文件的末尾,不支持在文件的任何一个地方进行写入。

二、HDFS相关概念

集群的结构,集群就是一些计算机我们通过网络连接起来就形成了一个集群。分布式文件系统的把文件分布式存储在了这样一个多节点的网络中,成千上万的计算机节点构成计算机集群。分布式文件系统所采用的计算机集群都是用普通的硬件所构成的,大大的降低了硬件上的开销。

HDFS的基本的系统架构我们从这个图中可以看到,它主要包括客户端、NameNode和DataNode。对于客户端,它主要包含了HDFS的一些接口,它用来访问HDFS上的文件。对于NameNode,它存储的是文件名以及元数据,还有就是文件与数据块的对应关系。对于DataNode,它是用来存储数据的节点。我们在HDFS的系统中可以有多个client、多个data node,但是对于提供服务,name node只能有一个。接下来我们介绍HDFS文件的基本存储单位block块,一个文件可以分成很多块,默认的一个块的大小是128M,我们以块为存储单位,大数据HDFS文件系统的块的大小远远大于普通的文件系统,可以起到最小化寻址开销的作用,提高了读取的吞吐量。

HDFS默认—个块128MB,一个文件被分成多个块,以块作为存储单位。块的大小远远大于普通文件系统,可以最小化寻址开销。

抽象的块概念可以带来以下几个明显的好处:

支持大规模文件存储

简化系统设计

适合数据备份

采用块的概念可以带来以下几个方面的好处。第一个方面是支持大规模文件的存储。我们一个文件也分为了若干个数据块,那这些块又可以分散存储在若干个节点上,因此我们存储文件的大小不受限于单个节点的存储容量。第二个方面是它可以简化系统的设计。因为我们一个块的大小是固定的,很容易去计算出来一个节点到底可以存储了多少个块。其次我们可以很方便地计算出了文件的大小,适合数据的备份,因为我们的文件可以划分成若干个数据块,这些块可以分散的存储在多个节点上。并且可以进行冗余存储。采用冗余存储的方式,当发生了部分数据丢失了,我们很容易进行恢复。

接下来我们介绍HDFS的两个主要的组件,namenode和datanode。namenode负责了管理namespace,包含两个最重要的数据结构,fsimage和EditLog。fsimage维护了文件系统数以及文件数中的文件以及文件名的元数据。另外EditLog记录了所有针对于文件的修改、删除以及重命名一些操作。namenode记录了数据块与datanode的对应关系。datanode它主要负责了文件的存储和读取,并且datanode会根据namenode和客户端的调度对文件进行检索或者是存储。另外namenode将自己的数据块存储于Linux操作系统的文件系统中。

三、HDFS体系架构

hdfs包含名称节点、数据节点,在hdfs的分布式文件系统中,名称节点只有一个,数据节点可以有多个。除此之外还有客户端,客户端包含了hdfs的一些api,我们利用客户端可以去给名称节点发送文件名或者是数据块号查询他想去查询的数据块,名称节点中它记录了数据块存储在哪些数据节点之上,然后就通知相应的数据节点,让客户端从数据节点上读取数据,也就是读取这些数据。这就是个HDFS体系结构。

HDFS命名空间管理

接下来我们看看HDFS命名空间管理。HDFS的命名空间它包含目录、文件和块。HDFS使用的是传统的分析文件体系,我们以前的方式是直接用斜杠,我们就可以来访问到相应的文件。用户可以像使用普通文件系统一样可以很方便的对文件进行创建、删除以及重命名文件。HDFS采用name node维护文件系统的名称,对文件系统的名称空间、过期属性的任何更改都有namenode的记录。有两种的数据结构,一个fsimage,一个是EditLog,主要是用来记录客户端对原文件的修改。

接下来我们介绍HDFS通讯协议,HDFS通信协议主要都是基于tcp/ip协议的。客户端通过一个可配置的端口向名称节点主动发起TCP连接,并使用客户端协议与名称节点进行交互。名称节点和数据节点之间则使用数据节点协议进行交互,客户端与数据节点的交互是通过RPC ( Remote Procedure Call)来实现的。在设计上,名称节点不会主动发起RPc,而是响应来自客户端和数据节点的RPC请求。

【云驻共创】小白速看之HDFS分布式文件系统和ZooKeeper

现在我们看看客户端,客户端是用户操作HDFS最常用的方式,HDFS在部署时都提供了客户端;HDFS客户端是一个库,包含HDFS文件系统接口,这些接口隐藏了HDFS实现中的复杂性;严格来说,客户端并不算是HDFS的一部分;客户端可以支持打开、读取、写入等常见的操作,并且提供了类似Shell的命令行访问HDFS中的数据;HDFS也提供了Java APl,作为应用程序访问文件系统的客户端编程接口。因为HDFS它是用架构开发的,JAVA api是它的原生api,我们采用JAVA API去写的程序就会有很高的效率。

在HDFS 1.0中,它是采用了单名称节点的,HDFS只设置唯—一个名称节点,这样做虽然大大简化了系统设计,但也带来了一些明显的局限性,具体如下:

命名空间的限制:名称节点是保存在内存中的,因此,名称节点能够容纳的对象(文件、块)的个数会受到内存空间大小的限制。

性能的瓶颈:整个分布式文件系统的吞吐量,受限于单个名称节点的吞吐量。

隔离问题:由于集群中只有一个名称节点,只有一个命名空间,因此,无法对不同应用程序进行隔离。

集群的可用性:一旦这个唯一的名称节点发生故障,会导致整个集群变得不可用。

四、关键特性介绍

首先我们来看HDFS的高可用性。高可用性它的缩写是HA(Highly Available)。高可用性是Hadoop2.0发展出来了一个新特性,因为对于Hadoop1.0来说,它只有一个名称节点,如果这个名称节点一旦崩溃了,整个集群将处于不可用。我们说HDFS1.0即使一个名称节点不可用之后,我们可以采用手工的方式,把集群先停下,然后把相应的备份文件,比如说fsimage和EditLog拷贝到namenode上,我们重新启动,但是它会停用一段时间。在2.0中,我们对这个问题进行了改进。设计了两个名称节点,一个称为了active NameNode,一个称为stand NameNode。一般我们称active NameNode它是主节点,stand NameNode称为二备份节点。通常情况下在集群运行的某个时刻,只有一个主节点提供服务。这个备用节点它是用来备份元数据信息的。我们为了去保证在集群中始终有一个提供服务的主名称节点。因此我们需要采用Zookeeper监控名称节点的心跳。当发现这个主名称节点崩溃的时候呢,就会来起用这个备用名称节点。备用名称这里它需要去存储相应的原数据信息。

那么这个元数据信息是怎么去存储的呢?涉及到两个层次,第一个层次是需要对Editlog,对元数据的一些更新操作信息,它需要去存储,它采用的是共享存储机制。同时在内存中维护了数据块与文件之间的对应关系,它记录了哪些数据块在哪些在datanode里面。因此我们在集群运行的期间,datanode需要不断地通过心跳把自身的数据块、数据信息发送给两个namenode,两个namenode都需要实时的去维护,文件跟数据块以及数据块在哪个data node之间的一个对应关系。

NameNode 基于内存存储文件元数据、目录结构、文件 block 的映射等信息,为了保障其可靠性,需要对其进行持久化。日志文件的方式 和 内存 Dump 都有其相应的优势与劣势,因此 HDFS 也使用了混合的方式。HDFS 同样也同时使用了这两种方式,其 日志记录 方式被称为 EditsLog,其内存 Dump 方式被称为 FsImage。因为 EditsLog 和 FsImage 也存在 日志记录 和 内存 Dump 的固有的缺点,因此两种方式都使用,来弥补对方的缺点。

由于滚动更新 FsImage 文件,也是比较耗时耗力的原因,HDFS 给 NameNode 提供了一个秘书,即 Secondary NameNode。Secondary NameNode 并非是第二个 NameNode,因为它不存储元数据,它的作用是完成 FsImage 和 EditsLog 的合并。通常 Secondary NameNode 和 NameNode 不在同一主机。Secondary NameNode 通过 http get 方式获取 NameNode 主机上的 FsImage 和 EditsLog,合并后通过 http post 方式提交给 NameNode,从而生成新的 FsImage 文件。

当 Secondary NameNode 将 EditsLog 拉取以后,NameNode 会将将新的日志记录到新的 EditsLog 中。

HDFS 联邦架构主要用于构建数据湖中的大型Hadoop集群,该集群具有以下特点:

1、文件数量非常多:数据湖中文件数达到数亿甚至更多。

2、单一集群规模大:数据湖的Hadoop集群规模达到数百台甚至更多。

3、各业务场景需要隔离:数据湖多种业务场景共同部署在一个物理集群,各业务之间要求互不影响。

联邦架构与单组Namenode架构相比,主要是Namespace被拆分成了多个独立的部分,分别由独立的Namenode进行管理。为了水平扩展Namenode,HDFS联邦架构使用了多个独立的Namenode/Namespace。这些Namenode之间是联合的,也就是说,他们之间相互独立且不需要互相协调,各自分工,管理自己的区域。分布式的Datanode被用作通用的数据块存储设备。每个Datanode要向集群中所有的Namenode注册,且周期性地向所有Namenode发送心跳和块报告,并执行来自所有Namenode的命令。

数据副本机制在haddoop1.0的时候就一直存在,数据副本是分布式系统解决数据丢失异常的唯一手段。另一类副本是服务副本,数个节点提供相同的服务,这种服务一般并不依赖节点的本地存储,其所需数据一般来自其他存储节点。

假如说我们的客户端提交了要存储一个数据块,那么这个数据块它是怎么存放的啊?如果说客户端在某个机架上的某个机器的服务器上,这时候它就会在所相应的这个服务器节点上去存储一个数据块block。如果说我们这个客户端不在这个机架上,在集群的外部,那我们就会在某个资源最丰富(存储资源)机架寻找一个节点,把相应的数据块存到这个节点上。然后它的第二个块是怎么样去存储的?他会来找其他的一个机架的很多个服务器,就会相应的在上面去找一个数据节点,然后把数据块传出来这个数据节点上。对于第三个副本我们一般情况下就会找到跟第一个副本所在的同一个机架,然后把第三个副本放到另外一个block上。如果说还有多的副本,因为我们这个副本是可以去设置的,我们通常情况下对伪分布式的模式只有一个副本。对于这种真实的集群环境下,我们可以设两个、三个、四个,当然也不是越多越好。根据实际情况,我们一般默认是三个副本,如果说有多余三个副本,他就会来去随机的去可以算出一个值,然后让你存随机存储到某一个节点上。

HDFS数据完整性保障

HDFS主要目的是保证存储数据完整性,对于各组件的失效,做了可靠性处理。重建失效数据盘的副本数据

DataNode向NameNode周期上报失败时,NameNode发起副本重建动作以恢复丢失副本。集群数据均衡

HDFS架构设计了数据均衡机制,此机制保证数据在各个DataNode上分布是平均的。

元数据可靠性保证

采用日志机制操作元数据,同时元数据存放在主备NameNode上。

快照机制实现了文件系统常见的快照机制,保证数据误操作时,能及时恢复。

安全模式

HDFS提供独有安全模式机制,在数据节点故障,硬盘故障时,能防止故障扩散。

HDFS架构其他关键设计要点说明

空间回收机制:

支持回收站机制,以及副本数的动态设置机制。

数据组织:

数据存储以数据块为单位,存储在操作系统的HDFS文件系统上。

访问方式:

提供JAVA API,HTTP方式,SHELL方式访问HDFS数据。

例如:hdfs dfs -cat /emp/words/

HDFS3.0 HDFS新特性总结

支持HDFS中的纠删码Erasure Encoding

基于HDFS路由器的联合

支持多个NameNode

DataNode内部添加了负载均衡Disk Balancer

在HDFS中,把连续的数据分成很多的小部分称为条带化单元,对于原始数据单元的每个条带单元,都会计算并存储一定数量的奇偶检验单元,计算的过程称为编码,可以通过基于剩余数据和奇偶校验单元的解码计算来恢复任何条带化单元上的错误。

五、HDFS的数据读写流程

HDFS数据读写流程:

首先我们看hdfs文件系统是怎么样去写入数据的。首先HDFS客户端,提出创建文件这个请求,我们通常要用到HDFS它提供的一个叫Distributed FileSystem类,我们可以认为呢\是接口,然后把这个创建文件这样一个请求发送给namenode接收到这个请求之后是吧解释这个请求之后,然后就反馈给客户端,客户端这时候紧接着就写入数据,写入数据它依据的是FSData OutputStream这个接口。它前面通过namenode获取到在哪些datanode上可以去写入数据块。写入的时候,首先找到第一个DataNode写入第一个副本,这个数据副本只需要写入到大概百分之四十左右的时候,那么他就回来把这个写入操作,相应的传递给另外一个DateNode,这个类似于流水线操作,然后传给这个DataNode。对DataNode同样写到百分之四十左右的时候,就把写入第三个副本的信息发送给了另外一个datanode同样进行写。那么当写完之后,就回来反馈,反馈这个已经正确的数据包。再反馈回去给客户端,客户端这时候就会关闭文件来写操作,最后这个写操作完成。

首先我们发送一个打开文件的请求,接下来我们要从上去获取打开文件Distributed FileSystem的元数据信息,就是说需要在DataNode上去获取它所需要的这个block。好,再就是读取请求是通过FSData IuputStream进行封装,紧接着就会找到相应的来DataNode去读取它所需要的block,block最后关闭枢纽,关闭了文件系统。

六、ZooKeeper概述与体系架构

Zookeeper称为动物园管理员,ZooKeeper 分布式服务框架主要是用来解决分布式应用中经常遇到的一些数据管理问题提供分布式、高可用性的协调服务能力。安全模式下ZooKeeper依赖于Kerberos和LdapServer进行安全认证,非安全模式则不依赖于Kerberos与LdapServer。ZooKeeper作为底层组件广泛被上层组件使用并依赖,如Kafka,HDFS,HBase,Storm等。

Zookeeper维护一个类似文件系统的树状数据结构,这种特性使得 Zookeeper 不能用于存放大量的数据,每个节点的存放数据上限为1M。每个子目录项如 NameService 都被称作为 znode(目录节点)。

Zookeeper服务架构 --模型

ZooKeeper集群由一组Server节点组成,这一组Server节点中只存在一个Leader的节点,其他节点都为Follower。

启动时选举出leader。

ZooKeeper使用自定义的原子消息协议,保证了整个系统中的节点数据的一致性。Leader节点在接收到数据变更请求后,先写磁盘再写内存。

Zookeeper服务架构 --容灾能力

ZooKeeper能够完成选举即能够正常对外提供服务。ZooKeeper选举时,当某一个实例获得了半数以上的票数时,则变为leader。

对于n个实例的服务,n可能为奇数或偶数。

n为奇数时,假定n= 2x +1,则成为leader的节占少种得x+1票,容灾能力为x。

n为偶数时,假定n= 2x +2,则成为leader的节点需要获得x+2票(大于一半),容灾能力为x。

ZooKeeper关键特性

最终一致性:无论哪个server,对外展示的均是同一个视图。

实时性:保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。

可靠性:一条消息被一个server接收,它将被所有server接受。

等待无关性:慢的或者失效的client不会干预快速的client的请求,使得每个client都能有效的等待。

原子性:更新只能成功或者失败,没有中间状态。

顺序一致性:客户端所发送的更新会按照它们被发送的顺序进行应用。

ZooKeeper读特性

由ZooKeeper的一致性可知,客户端无论连接哪个server,获取的均是同一个视图。所以,读操作可以在客户端与任意节点间完成。

ZooKeeper客户端常用命令使用

调用ZooKeeper客户端,执行命令:zkCli.sh -server 172.16.0.1:24002

创建节点: create /node

列出节点子节点:ls /node

创建节点数据: set /node data

获取节点数据: get /node

删除节点:delete /node

删除节点及所有子节点: deleteall /node

总结

分布式文件系统是大数据时代解决大规模数据存储问题的有效解决方案,HDFS开源实现了GFS,可以利用由廉价硬件构成的计算机集群实现海量数据的分布式存储。

HDFS具有兼容廉价的硬件设备、流数据读写、大数据集、简单的文件模型、强大的跨平台兼容性等特点。但是,也要注意到,HDFS也有自身的局限性,比如不适合低延迟数据访问、无法高效存储大量小文件和不支持多用户写入及任意修改文件等。

块是HDFS核心的概念,一个大的文件会被拆分成很多个块。HDFS采用抽象的块概念,具有支持大规模文件存储、简化系统设计、适合数据备份等优点。

ZooKeeper分布式服务框架主要是用来解决分布式应用中经常遇到的一些数据管理问题,提供分布式、高可用性的协调服务能力。

本文整理自华为云社区【内容共创系列】活动。

查看活动详情:https://bbs.huaweicloud.com/blogs/314887

相关任务详情:HDFS分布式文件系统和ZooKeeper

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:漫画解读:轻松看懂机器学习十大常用算法
下一篇:proc中的重要信息
相关文章