0


分布式数据存储建设方法论——从HDFS架构优化与实践分析

作者:禅与计算机程序设计艺术

1.简介

随着互联网、云计算、大数据等新一代信息技术的出现和普及,数据量的激增、数据安全性的需求以及数据的分布式储存需求日益成为各大公司和组织面临的难题。传统的单体架构模式已经无法应付如此复杂的业务场景,因此,分布式数据存储系统(Distributed Data Store)在近年来逐渐受到越来越多的重视。HDFS(Hadoop Distributed File System)就是最著名的分布式数据存储系统之一,它被广泛应用于数据分析、搜索引擎、日志处理、高性能计算等领域。HDFS作为Apache基金会下的顶级开源项目,其架构经过精心设计,能够支撑高吞吐量的数据读写,适用于各种类型的企业用途。HDFS能够充分利用廉价的商用服务器硬件资源进行数据存储,并通过冗余机制和自我恢复能力,在服务器失效或网络拥塞时仍然可以确保数据的可靠性和一致性。HDFS通过精心设计的NameNode与DataNode两个主要组件,实现了分布式文件系统的功能和特性。下面将从HDFS的历史发展、基本概念、架构原理、性能优化、集群管理、故障排查等方面对HDFS进行全面详细地阐述。

2. HDFS 的发展历史

HDFS的前身分别为Apache Nutch项目的NutchFs、MapReduce项目的MapRFS,它们都是一种基于磁盘的分布式文件系统,具有简单的文件系统接口、快速数据访问、稳健的存储、适合批处理、海量数据集等特点。但是由于性能瓶颈,它们都没有完全兼容Unix/Linux操作系统的文件系统标准接口,难以满足移动设备上大规模文件的存储需求,因此在2006年,UC Berkeley Ph.D. students 、、发明了新的HDFS。HDFS在当时已经具备了上述的所有优点,并且经过多年的不断改进,已经成为目前大型网站、云服务提供商、大数据处理平台等领域使用的分布式文件系统。
  HDFS的发展历史还包括以下几个阶段:

1992-2002年:研究人员们从AT&T贝尔实验室开发的NutchFs系统,是一个基于磁盘的分布式文档检索系统。该系统支持基于Web文本的全文索引、数据分析、机器学习等任务。

2002-2003年:为了解决NutchFs系统的一些缺陷,提出了Google File System(GFS)的想法。GFS是在大规模集群环境下运行良好、高度可用的分布式文件系统,可扩展性强、成本低廉。

2003-2006年:GFS被Yahoo!实验室开发的MapRfs取代,支持分布式数据分析、分布式计算、文件系统接口的兼容。

2007-至今:HDFS历经多个版本的迭代升级,相信经过不断改进和完善之后,会继续为大数据处理提供更好的服务。
  以上是HDFS的主要发展历史。下面将介绍HDFS的基本概念和架构原理。

3. HDFS 的基本概念和架构原理

3.1 文件系统层次结构

3.1.1 文件系统层次结构概览

按照文件系统的层次结构,HDFS由两部分组成:分布式文件系统和一个高可用、容错的集群管理系统。HDFS是一个分布式文件系统,由两大组件构成:HDFS NameNode和HDFS DataNode。
  HDFS NameNode:负责整个文件系统的名字空间管理、存储空间分配、以及客户端请求的调度。NameNode运行在单个节点上,以主/备的方式对外提供服务。当NameNode宕机后,系统自动切换到备机,确保系统的高可用性。

HDFS DataNode:负责存储实际的数据块,在数据读写期间对数据进行校验和复制。DataNodes存储文件切片,这些文件切片在HDFS中称作Block。默认情况下,HDFS Block大小为64MB,通常情况下,Block大小可以在创建文件的时候指定。Block大小决定了HDFS的最大读写单位,也是用户最容易调整的参数。

HDFS的另一个重要特征就是支持多种数据模型。HDFS中的文件以字节流的形式存储,也支持更复杂的如Map-reduce程序的输出结果等。

根据分布式文件系统所遵循的"一个名称空间对应一个目录树"的原则,HDFS的命名空间非常类似于UNIX文件系统。HDFS中的每个文件或者目录都有一个路径名。这个路径名总是以“/”开头,例如“/users/gaozy/notes”。目录名末尾加“/”,表示这个目录是一个真正的目录,而不只是某个文件名。

除了用于目录树的结构之外,HDFS还有很多其他独特的特性,比如它的容错机制、它能够处理大文件、以及它对元数据进行了高度优化。

3.1.2 文件系统的命名空间与目录树

HDFS的命名空间是一个树状结构,即它以树形结构显示所有文件和目录。不同于UNIX文件系统的基于磁盘的目录结构,HDFS的目录结构是由文件和目录记录在内存中的哈希表来实现的。这种结构使得HDFS支持任意数量的目录,无需物理限制。而且,HDFS的文件系统不仅可以作为客户端访问的接口,同时也可以作为内部子系统之间的通信接口。

HDFS将文件系统划分为多个块大小相同的Block。文件的长度和块大小是通过第一次写入文件时设置的。文件的名字同样也一样,第一次创建文件时指定。文件在HDFS中以Block为基本单元。HDFS为每个Block都维护一个校验和和副本,副本数量默认为3。当某个DataNode损坏时,HDFS将尝试自动识别损坏块并将其复制到另一个DataNode。HDFS通过一个中心元数据服务器来管理所有的Block和文件。
  HDFS的目录结构通过对文件名和目录名采用哈希表来实现。这样做可以使得查询和检索变得非常快,因为一个简单的哈希表查找的时间复杂度是O(1)。另外,HDFS的目录结构也是不可变的,也就是说不能增加或者删除文件或者目录,只能修改文件名。

另外,HDFS支持多种权限控制策略,可以将文件或目录授权给不同的用户、组、角色等。HDFS支持用户自定义属性,可以向文件添加自定义的元数据信息,如标签、描述等。HDFS的访问控制列表(ACL)可以控制对文件和目录的读、写、执行等权限。

3.2 HDFS 的架构原理

3.2.1 数据流动过程

当客户端向HDFS提交文件上传操作时,首先要先向NameNode发送一个报告文件上传信息的命令。NameNode收到命令后,会检查目标文件是否存在,如果不存在则创建一个新的文件并返回给客户端。然后,NameNode再把这个文件分割成多个HDFS块,分配到相应的DataNode上。

当客户端读取某个文件时,它会首先向NameNode发送一个读取请求。NameNode将根据文件的长度、数据分布情况,选择合适的数据节点读取文件,然后将其发送给客户端。客户端接收到数据后,可以立即开始进行数据解析和处理。

HDFS的所有操作都是由HDFS客户端进程触发的,客户端通过调用Java API或者其他编程接口来完成文件上传、下载、查看和修改等操作。客户端可以直接通过调用API向NameNode上传文件,并通过DataNode下载文件。同时,客户端还可以对远程数据进行map reduce操作。
  HDFS采用流水线式的设计方式,一次处理多个数据块,减少网络I/O消耗。HDFS可以很好地利用网络带宽资源,有效地节省了数据传输的开销。HDFS支持多副本机制,防止因机器故障导致的数据丢失。HDFS在客户端读写数据的过程中,还支持文件的压缩和数据校验机制,保证数据的完整性。
  HDFS支持在线扩容和缩容,方便用户按需扩展集群资源。除此之外,HDFS还提供了命令行工具hdfs命令,方便管理员管理HDFS集群。

3.2.2 副本机制

HDFS的副本机制解决了数据冗余的问题。对于每个数据块,HDFS都会保存3份副本,其中一份放在本地磁盘上,剩余两份存放在不同的数据结点上。在一般情况下,HDFS会选取一个接近本地磁盘的数据结点作为主副本,其他副本则同步更新。当主副本所在的数据结点发生故障时,HDFS会自动选取另一个副本作为新的主副本,确保数据完整性。HDFS在底层使用的是HDFS协议,它提供了高可靠性、数据完整性和容错性。

3.2.3 容错机制

HDFS通过将文件分割成固定大小的Block,以及对每个Block进行校验和、副本更新等操作,来保证数据的完整性和容错性。HDFS的数据备份、数据校验和数据迁移等操作都是自动化的,并可以通过NameNode管理界面查看进度和状态。对于集群出现故障、磁盘损坏等异常情况,HDFS均能够及时检测到并自动修复,保证数据安全、可用性和可靠性。

3.2.4 数据块大小

HDFS在设计时,就考虑到Block大小应该尽可能小,以减少网络IO,并充分利用局部性原理。因此,HDFS将Block的大小设置为64M,这也是Hadoop的默认值。除此之外,HDFS还允许用户在文件创建时设置Block大小。但一般来说,建议不要设置过大的值,以避免过大的磁盘占用。

3.2.5 编码方式

HDFS支持两种编码方式:静态的文本编码和动态的压缩编码。静态编码使用UTF-8编码将原始数据编码成字节流。动态编码使用Google Snappy进行压缩。

3.2.6 数据校验

HDFS通过计算每份数据块的校验和来保证数据完整性。HDFS会对每个Block上的数据进行MD5计算得到校验和,并将校验和记录在NameNode和DataNode上。客户端从DataNode接收到Block数据后,会验证该数据的校验和,确保数据没有损坏。
  HDFS支持三种策略来处理损坏的Block:

1.拒绝服务(DoS)攻击:该策略在NameNode检测到损坏的Block时,会将其标记为失效,防止其被热备份。

2.自动垃圾回收:该策略会周期性地扫描整个HDFS集群,找出失效的Block并将其删除。

3.手动回收:管理员可以手工将失效的Block删除。

3.3 HDFS 的性能优化

3.3.1 参数调优

HDFS有很多参数可以进行优化。比如,Block大小、副本数目、名字服务缓存时间、以及对特定工作负载的调优等。

3.3.2 JVM配置

为了提升HDFS的性能,需要对JVM进行配置。在启动时,HDFS会加载配置文件$HADOOP_HOME/etc/hadoop/core-site.xml中的配置项。配置项包括:Java堆大小、线程池大小、RPC超时设置等。

3.3.3 流控机制

HDFS采用流控机制来控制客户端的请求速率。当客户端的请求速率超过一定阈值时,HDFS会对其进行限流处理,防止其超出预期地消耗网络带宽、CPU资源。

3.3.4 压缩与数据校验

HDFS支持在写入数据时进行压缩和数据校验,并在读取数据时进行数据校验。这样可以有效地减少网络传输的数据量。

3.3.5 EC编码

EC(Erasure Coding)编码是一种数据冗余机制。它通过奇偶校验等方式来实现数据的冗余,并通过校验失败后的重新编码恢复数据。HDFS支持两种EC编码的方式:一种是纯粹的EC编码,另一种是混合的EC编码。纯粹的EC编码使用了一部分数据块来进行数据冗余,另一部分数据块则留给普通的HDFS块。而混合的EC编码则结合了普通HDFS块和纯粹EC块的冗余。

3.3.6 缓存机制

HDFS支持Block级别的缓存机制,可以提升HDFS的整体性能。它可以缓存热门的数据块,减少对远程DataNode的访问次数。

3.3.7 客户端优化

为了提升客户端的响应速度,HDFS提供了一系列的客户端优化措施。如减少打开文件的个数、降低客户端等待时间、增加读取线程数等。

3.3.8 查询优化

HDFS支持基于范围的查询、分布式并发查询、索引等。客户端可以使用Range,Prefix和Index等参数来进行查询。

3.4 HDFS 集群管理

3.4.1 硬件选择

在部署HDFS之前,首先需要选择硬件配置。HDFS的硬件要求比较苛刻,要求不少于两个DataNode,否则就会出现单点故障。

3.4.2 操作系统准备

HDFS依赖于Linux操作系统,所以在部署HDFS之前,需要安装Linux操作系统。操作系统应该选择具有较高IOPS的高性能服务器,且内存容量要足够大。

3.4.3 安装Hadoop

下载最新版的Hadoop安装包并解压。

wget http://archive.apache.org/dist/hadoop/common/stable/hadoop-3.2.1.tar.gz
tar-zxvf hadoop-3.2.1.tar.gz

3.4.4 配置集群

配置$HADOOP_HOME/etc/hadoop/core-site.xml文件。该文件中的配置项如下:

hdfs.nameservices:指定HDFS集群的名称,在同一个集群内可以起多个不同的名称。

hdfs.namenode.rpc-address:指定HDFS的NameNode的地址,可以是主机名或者IP地址。该地址必须是集群中某个DataNode的地址。

hdfs.client.failover.proxy.provider:指定故障转移代理,用于客户端连接到NameNode时的负载均衡。该配置项可以是:(1).配置权威域名解析器;(2).配置Hadoop自带的故障转移代理Provider;(3).配置Apache Knox的Knox代理;(4).自定义的故障转移代理Provider。

hdfs.replication:指定HDFS文件的副本数目,默认为3。

配置$HADOOP_HOME/etc/hadoop/hdfs-site.xml文件。该文件中的配置项如下:

dfs.blocksize:指定HDFS块的大小。默认值为64MB。

dfs.replication:指定HDFS文件的副本数目。默认值为3。

dfs.datanode.data.dir:指定DataNode存储数据文件的目录。默认值为/var/lib/hadoop-hdfs/data。该配置项可以配置多个目录,用逗号隔开。

配置$HADOOP_HOME/etc/hadoop/yarn-site.xml文件。该文件用于配置YARN相关的属性,如ResourceManager的地址、队列、白名单等。

配置$HADOOP_HOME/etc/hadoop/mapred-site.xml文件。该文件用于配置MapReduce相关的属性,如JobHistoryServer的地址等。

配置$HADOOP_HOME/etc/hadoop/httpfs-site.xml文件。该文件用于配置HttpFS相关的属性,如HttpFS的监听端口等。

3.4.5 启动集群

启动HDFS集群有两种方式:分离式和联邦式。分离式指的是NameNode和DataNode分开部署。联邦式指的是NameNode和多个DataNode共同部署。

启动HDFS集群分为NameNode和DataNode的启动。首先启动NameNode。然后,将NameNode注册到JMX监控端口。

在各个DataNode上启动HDFS守护进程。每个DataNode会向NameNode注册自己。一旦DataNode注册成功,NameNode就可以识别到DataNode并分配其存储空间。

HDFS启动成功后,就可以通过Web浏览器访问HDFS文件系统,并上传或下载文件。

HDFS启动失败的原因有很多,如NameNode启动失败、DataNode启动失败、磁盘空间不足、网络连接故障、配置错误等。如果启动失败,可以先检查

     H 
    
   
     A 
    
   
     D 
    
   
     O 
    
   
     O 
    
    
    
      P 
     
    
      L 
     
    
   
     O 
    
    
    
      G 
     
    
      D 
     
    
   
     I 
    
   
     R 
    
   
     / 
    
   
     h 
    
   
     a 
    
   
     d 
    
   
     o 
    
   
     o 
    
   
     p 
    
   
     − 
    
   
     h 
    
   
     d 
    
   
     f 
    
   
     s 
    
   
     − 
    
   
     n 
    
   
     a 
    
   
     m 
    
   
     e 
    
   
     n 
    
   
     o 
    
   
     d 
    
   
     e 
    
   
     − 
    
   
  
    HADOOP_LOG_DIR/hadoop-hdfs-namenode- 
   
  
HADOOPL​OGD​IR/hadoop−hdfs−namenode−USER.*.out文件看是否有报错信息,然后检查配置项。

3.4.6 关闭集群

关闭HDFS集群也很简单。首先关闭所有DataNode上的HDFS守护进程。然后关闭NameNode进程。关闭HDFS集群后,相应的文件和目录不会在DataNode上保留,因此不会产生额外的费用。

当然,关闭集群后,HDFS的文件系统将无法访问,需要等待一段时间才能恢复访问。

3.5 HDFS 故障排查

3.5.1 HDFS 日志文件

HDFS有四个日志文件:

  •   H 
     
    
      A 
     
    
      D 
     
    
      O 
     
    
      O 
     
     
     
       P 
      
     
       L 
      
     
    
      O 
     
     
     
       G 
      
     
       D 
      
     
    
      I 
     
    
      R 
     
    
      / 
     
    
      h 
     
    
      a 
     
    
      d 
     
    
      o 
     
    
      o 
     
    
      p 
     
    
      − 
     
    
      h 
     
    
      d 
     
    
      f 
     
    
      s 
     
    
      − 
     
    
      n 
     
    
      a 
     
    
      m 
     
    
      e 
     
    
      n 
     
    
      o 
     
    
      d 
     
    
      e 
     
    
      − 
     
    
    
     HADOOP_LOG_DIR/hadoop-hdfs-namenode- 
    

    HADOOPL​OGD​IR/hadoop−hdfs−namenode−USER.*.out:NameNode的日志文件,包含NameNode的信息、警告和错误日志。

  •   H 
     
    
      A 
     
    
      D 
     
    
      O 
     
    
      O 
     
     
     
       P 
      
     
       L 
      
     
    
      O 
     
     
     
       G 
      
     
       D 
      
     
    
      I 
     
    
      R 
     
    
      / 
     
    
      h 
     
    
      a 
     
    
      d 
     
    
      o 
     
    
      o 
     
    
      p 
     
    
      − 
     
    
      h 
     
    
      d 
     
    
      f 
     
    
      s 
     
    
      − 
     
    
      n 
     
    
      a 
     
    
      m 
     
    
      e 
     
    
      n 
     
    
      o 
     
    
      d 
     
    
      e 
     
    
      − 
     
    
    
     HADOOP_LOG_DIR/hadoop-hdfs-namenode- 
    

    HADOOPL​OGD​IR/hadoop−hdfs−namenode−USER.log:NameNode日志滚动记录。该文件是每天产生一个,记录当天的日志信息。当日志文件达到一定大小后,会自动生成新的日志文件。

  •   H 
     
    
      A 
     
    
      D 
     
    
      O 
     
    
      O 
     
     
     
       P 
      
     
       L 
      
     
    
      O 
     
     
     
       G 
      
     
       D 
      
     
    
      I 
     
    
      R 
     
    
      / 
     
    
      h 
     
    
      a 
     
    
      d 
     
    
      o 
     
    
      o 
     
    
      p 
     
    
      − 
     
    
      h 
     
    
      d 
     
    
      f 
     
    
      s 
     
    
      − 
     
    
      d 
     
    
      a 
     
    
      t 
     
    
      a 
     
    
      n 
     
    
      o 
     
    
      d 
     
    
      e 
     
    
      − 
     
    
    
     HADOOP_LOG_DIR/hadoop-hdfs-datanode- 
    

    HADOOPL​OGD​IR/hadoop−hdfs−datanode−USER.*.out:DataNode的日志文件,包含DataNode的信息、警告和错误日志。

  •   H 
     
    
      A 
     
    
      D 
     
    
      O 
     
    
      O 
     
     
     
       P 
      
     
       L 
      
     
    
      O 
     
     
     
       G 
      
     
       D 
      
     
    
      I 
     
    
      R 
     
    
      / 
     
    
      h 
     
    
      a 
     
    
      d 
     
    
      o 
     
    
      o 
     
    
      p 
     
    
      − 
     
    
      h 
     
    
      d 
     
    
      f 
     
    
      s 
     
    
      − 
     
    
      d 
     
    
      a 
     
    
      t 
     
    
      a 
     
    
      n 
     
    
      o 
     
    
      d 
     
    
      e 
     
    
      − 
     
    
    
     HADOOP_LOG_DIR/hadoop-hdfs-datanode- 
    

    HADOOPL​OGD​IR/hadoop−hdfs−datanode−USER.log:DataNode日志滚动记录。该文件是每天产生一个,记录当天的日志信息。当日志文件达到一定大小后,会自动生成新的日志文件。

HDFS日志有三类:服务日志、垃圾收集日志和操作日志。

  • 服务日志:用于记录NameNode和DataNode相关的关键事件,如启动、停止、故障转移、读写操作、块生成、复制等。

  • 垃圾收集日志:用于记录HDFS垃圾收集相关的信息,如回收的垃圾数量、回收的时间等。

  • 操作日志:用于记录客户端对HDFS进行的所有操作,包括读写、复制等。

可以使用命令tail命令查看日志文件末尾的内容。

3.5.2 Hadoop 命令行工具

Hadoop提供了几个命令行工具:hdfs,fs,yarn,mapred,httpfs等。

  • hdfs:用于管理HDFS文件系统的命令行工具。

  • fs:hdfs的替代品,可以使用更简单易懂的命令行语法。

  • yarn:用于管理Yarn集群的命令行工具。

  • mapred:用于管理MapReduce应用程序的命令行工具。

  • httpfs:用于访问HDFS文件系统的HTTP接口。

可以使用命令help查看命令帮助信息。

3.5.3 查看集群信息

命令hdfs getconf -confKey confValue:获取指定配置项的值。

命令hdfs dfsadmin -report:查看HDFS集群的状态信息。

命令hdfs df -h:查看HDFS中各个DataNode的存储空间使用情况。

命令hdfs getjmx:查看NameNode和DataNode的JMX监控信息。

命令hdfs zkfc -list-corrupt-files:查看HDFS文件系统的坏BLOCK。

命令hdfs haadmin -getServiceState nameserviceId:获取NameNode的当前状态。

3.5.4 使用webHDFS

Hadoop的WebHDFS(Hadoop Web Distributed File System)是一个基于HTTP协议的RESTful文件系统接口。它支持文件的创建、删除、重命名、查看、追加、修改、复制、Trash、支持block size,支持权限控制、提供Web页面接口。

WebHDFS可以通过浏览器访问,URL地址类似于:http://namenodehost:port/webhdfs/v1/

?op=LISTSTATUS。其中,

表示文件路径。可以通过命令hdfs dfs –ls webhdfs://hostname:port/ 

 查看HDFS中的文件。 

WebHDFS客户端有Java库、C++库、Python库、命令行工具、PowerShell脚本等。它们可以用于文件上传、下载、删除、重命名、列举等操作。


本文转载自: https://blog.csdn.net/universsky2015/article/details/132002515
版权归原作者 禅与计算机程序设计艺术 所有, 如有侵权,请联系我们删除。

“分布式数据存储建设方法论——从HDFS架构优化与实践分析”的评论:

还没有评论