一、HDFS简介
主要介绍Hadoop生态里面的其中一个组件——HDFS,包括HDFS架构,数据是怎么在HDFS存储的,HDFS的特性,比如分布式存储、容错性,高可用,可靠性以及块概念等。另外还会涉及到HDFS的操作,比如如何从HDFS读写数据,还有HDFS的机架感知算法介绍。
1、HDFS 简介
HDFS(Hadoop Distribute File System)是大数据领域一种非常可靠的存储系统,它以分布式方式存储超大数据量文件,但它并不适合存储大量的小数据量文件。Hadoop HDFS是Hadoop和其他组件的数据存储层。HDFS是运行在由价格廉价的商用机器组成的集群上的,而价格低廉的机器发生故障的几率比较高,但是HDFS利用数据副本技术把数据存放在若干个机器上,保证数据的高可用性,使得数据不至于因为某几个机器发生故障发生丢失不可用的情况。HDFS以数据并发访问的方式达到高吞吐量的目的。下面开始详细介绍HDFS的各个关键点。
2、HDFS 节点
Hadoop是以主从结构的方式运行的,HDFS也是以同样的方式工作的,它也有有两种节点类型,分别是namenode节点和datanode节点。
namenode和datanode 也是HDFS的2个守护进程。
Namenode:该进程运行在master节点上。Namenode节点存储元数据,比如文件名,块数量,块副本数量,块的存储位置,以及块ID等。为了元数据的快速查询,这些都是存储在master节点的内存里面的,并在本地磁盘存储这些元数据的副本。
Datanode:该进程运行在Slave节点,这些节点是真正对数据进行处理和存储的节点。
2.1 HDFS NameNode
Namenode其实就是Master节点,它主要用来存储元数据,比如数据块的数量,副本和其他细节。这些元数据是存储在Master节点的内存里面的,因为要保证元数据的快速查询。另外还会在磁盘(FsImage文件和Editlog文件)保存一份元数据镜像文件。Namenode会规范客户端对文件的访问,它维护和管理Slave节点,并把读写任务分配给Slave节点。Namenode执行文件系统的名字空间操作,比如打开,关闭,重命名文件和目录。由于NameNode是整个HDFS集群的中心,所以最好把它部署在可靠的硬件机器上。
Namenode主要负责以下任务:
- 管理文件系统命名空间
- 规范客户端文件访问权限
- 执行文件系统相关的操作,如关闭,打开文件/目录,以及给文件/目录命名。
- 所有的datanode都会给Namenode发送心跳和块信息报告。心跳用来检测 Datanode是否处理正常状态。块信息报告是datanode上所有块信息的列表。
- Namenode还负责处理所有块的副本因子。
Namenode主要维护两个文件,一个是FSImage,一个是EditLog。
FsImage
FsImage是一个“镜像文件”。它保存了最新的元数据检查点,包含了整个HDFS文件系统的所有目录和文件的信息。对于文件来说包括了数据块描述信息、修改时间、访问时间等;对于目录来说包括修改时间、访问权限控制信息(目录所属用户,所在组)等。
EditLog
EditLog主要是在NameNode已经启动情况下对HDFS进行的各种更新操作进行记录,HDFS客户端执行所有的写操作都会被记录到editlog中。
2.2 HDFS DataNode
在HDFS集群,Datanode节点的数量可以扩展到1000。DataNode即Slave节点,它是实际存储业务数据的节点。Datanode负责数据存储,它是真正干活的节点,它会按照客户端的请求执行数据读写操作,比如响应客户端的数据读写请求,根据Namenode的指令创建和删除block。而且还会根据副本因子把block复制到其他节点。Datanode可以部署在价格低廉的商用机器上,没必要部署在昂贵的高可用机器上。
Datanode主要负责以下工作:
- 根据Namenode指令创建、删除和复制数据块。
- Datanode管理系统的数据存储。
- Datanode定期给Namenode发送心跳告知自身的健康状态,默认3秒发送一次心跳。
2.3 SecondaryNameNode
SecondaryNameNode是一个辅助的NameNode,不能代替NameNode。它的主要作用是用于合并FsImage和editlog文件。在没有SecondaryNameNode守护进程的情况下,从namenode启动开始至namenode关闭期间所有的HDFS更改操作都将记录到editlog文件,这样会造成巨大的editlog文件,所带来的直接危害就是下次启动namenode过程会非常漫长。
在启动SecondaryNameNode守护进程后,每当满足一定的触发条件(每3600s、文件数量增加100w等),SecondaryNameNode都会拷贝namenode的fsimage和editlog文件到自己的目录下,首先将fsimage加载到内存中,然后加载editlog文件到内存中合并fsimage和editlog文件为一个新的fsimage文件,然后将新的fsimage文件拷贝回namenode目录下。并且声明新的editlog文件用于记录DFS的更改。
2.4 Checkpint Node和Backup Node
Checkpoint Node会通过单独线程,定时从Active NameNode拉取edit log文件拷贝到本地,并且将这些edit log在自己内存中进行重演。如果checkpoint条件具备,将进行checkpoint操作,文件存入本地,并通过HTTP PUT的方式将fsimage文件传输给Active NameNode。
Backup Node除了具有Checkpoint Node的上述所有功能外,还会通过RPC方式(属于stream的方式,区别于单独定时拷贝)实时接收Active NameNode的edit操作。因此,同Checkpoint Node相比,Backup Node的内存映象在时间差上几乎与Active NameNode一致。
注意:Checkpoint Node和Backup Node在某种程度上几乎替代了Standby NameNode的功能,因此,在HA模式下,无法启动Checkpoint Node和Backup Node。必须使用非HA模式才可以启动并使用Checkpoint Node。
3、HDFS 的数据存储
把文件写入到HDFS的时候,HDFS会把文件分割成很多分片,也就是块(block)。默认情况下,HDFS块大小为128MB,块大小可以按需要修改。文件分割成块之后,HDFS会把他们以分布式方式存储在集群的不多节点上。这为MapReduce在集群并行化处理数据提供了很好的基础。
datanode根据副本因子把每个块的副本存放在集群的不用节点磁盘上,默认情况下副本因子为3,副本技术实现了数据的容错性、可靠性以及高可用特性。
4、HDFS 机架感知
Hadoop运行在由价格低廉的商用机器集群上,这些机器可能在不用的机架。为了数据容错,NameNode把块的副本放在多个机架上,NameNode尽量会在每个机架都存储至少一个块副本,这样如果其中一个机架发生故障,系统还是可用的。优化的副本位置使得HDFS和其他分布式文件系统拉开了差距。机架感知策略的目的是提升数据可用性、可靠性和网络带宽利用率。
在大型Hadoop集群,为了在读写文件的时候改善网络传输,Namenode会选择给同一个机架或者最近的机架上的Datanode发送读写请求。NameNode通过维护每个DataNode的机架id来获取机架信息。HDFS机架感知就是基于机架信息选择Datanode的过程。
在HDFS架构里面,Namenode需要确保所有的块副本不能存储在同一个机架上。它根据机架感知算法减少延迟时间和容错。我们知道默认副本因子是3,根据机架感知算法,第一个块副本将存储在本地机架,第二个副本存储在同一个机架的不同节点,第三个将存储在另一个机架上。
机架感知对以下几点的改善非常重要:
- 提升数据的高可用和可靠性。
- 改善集群性能。
- 改善网络带宽。
二、HDFS架构
Hadoop HDFS是一个主从(Master / Slave)架构,其中Master是Namenode节点,它主要用来存储元数据,Slave是Datanode节点,用来存储实际业务数据的节点。HDFS架构用一个Namenode和多个Datanode组成。
上面这个图清楚描述了HDFS的架构。一个用于存储元数据的Namenode和多个用于存储数据的Datanode。节点是在机架上的,而数据块的副本存储在不同机架上以达到容错的目的。在下面的会介绍HDFS是如何读写文件的,在读写文件的时候,客户端需要和Namenode交互。HDFS适合一次写入多次读取的场景,文件一旦被创建并写入数据后,就不能被编辑了。
Namenode负责存储元数据而Datanode负责存储实际的数据。执行任何任务,客户端都得和Namenode进行交互,因为Namenode是整个集群的中心。
Datanode是把数据存储在本地磁盘的,它会定期给Namenode发送心跳信息,以此来表明自己处在工作状态。另外,Datanode还会根据副本因子负责把block拷贝到其他Datanode。
1、Hadoop HDFS 特性
HDFS具有以下特点:
- 分布式存储
- 块
- 副本
- 高可用
- 数据可靠性
- 容错性
- 可扩展
- 高吞吐量
1、分布式存储
HDFS会把大数据文件分割成小block,并把这些block以分布式方式存储在集群。这样MapReduce才能并行的对这些数据进行计算处理。
2、HDFS 块概念
HDFS会把大文件分割成小的的数据块,它是Hadoop分布式文件系统最小的数据存储单位。数据块的存储位置由Namenode决定。默认的HDFS数据块大小是128MB,我们可以根据需要调整块大小。文件分割后所有的块大小都是一样的,除了最后一个块,默认情况下,它的大小可能小于等于128MB。
如果数据的大小比HDFS块大小还要小的话,那么块大小将等于数据的大小。比如,文件大小是129MB,那么HDFS将创建2个block,一个block的大小是默认值,即128MB,另外一个block就只有1MB,而不是128MB。
HDFS以块来存储数据的主要优势就是节省了磁盘寻道时间,另一个优势就是在mapper进程处理数据的时候,一次可以处理一个块的数据,这样一个mapper进程在同一时间可以处理大量的数据。
HDFS把文件分割成块,每个块会被存储在不同节点。默认情况下,每个块有3个副本,每个块的副本也是存储在不用节点的,这样可以达到数据容错的目的。这些块的存储位置是由Namenode决定的。
3、副本管理
块副本给HDFS提供了很好的数据容错特性。如果一个副本损坏了,我们可以从其他节点读取到该副本。HDFS里面块的副本数量叫做副本因子,默认情况下,副本因子是3,可以在配置文件hdfs-site.xml修改这个值。所以每个块会被复制3次,并存储在不用的datanode磁盘上。如果需要把128M的文件存储在HDFS上,那么需要384MB的存储空间(128MB * 3)。
Namenode定期接收来自Datanode的块信息报告来维护副本因子。如果块副本数量比副本因子大,Namenode会删除多余的块副本,相反,Namenode将会新增块副本。
HDFS创建块的副本是存储在集群的不用节点的。HDFS会在每个机架尽量存储至少一个副本。
机架是什么呢?即存放服务器的架子。Datanode是放在机架上的,机架上所有节点通过交换机连接,所以如果交换机发生故障了,那么整个机架就变成不可用的了。但数据可以从其他机架读取到。
4、高可用
为了达到数据高可用目的,数据块的副本是存储在集群的不同节点的。默认副本因子是3,也就是说数据会在3个不同节点存储,3个节点全挂的概率比较小,所以其中某个节点或者网络挂了都不影响数据可用性。
5、数据可靠性
HDFS会把根据副本因子把数据存储在不同节点,这对数据的可靠性非常有帮助的。由于HDFS的块复制技术,即使存储块的某些节点挂了,可以从其他节点获取的块数据。如果一个节点挂了,存储在该节点的块就被复制,节点挂了之后又恢复了,存储在该节点的块会被过度复制,我们需要根据情况增加或者删除块副本。这种情况下,只需要运行很少的命令,副本因子就能达到预期的值。这就是数据如何被可靠存储和提供容错以及高可用的原因。
6、容错
HDFS给Hadoop和其他组件提供具有容错特性的存储层。HDFS是运行在商用硬件上的,而商用硬件奔溃率较高。因此,为了使整个系统具备较高容错性,HDFS把数据复制并存储到集群的不同机器上,默认情况下,数据会存储在3个不同的位置。这样,即使其中的某2个机器宕机了,数据仍然是可用的,进而达到不丢失数据的目的,即数据容错性。
7、可扩展性
可扩展性即集群可以根据需要扩充和缩小。Hadoop HDFS可以用下面2种方式来达到扩展性目的。
- 给集群的节点增加更多的磁盘。
我们需要编辑配置文件,并为新添加的磁盘创建相应的条目。这种方式需要停机处理,即使停机时间很少。所以人们通常更倾向于使用第二种扩展方式,即水平扩展。 - 给集群增加更多的节点。
这种方式不需要停机,把机器加进来,做一下配置和数据平衡即可,这种方式被称为集群的水平扩展。
8、高吞吐量
HDFS提供高吞吐量访问数据。吞吐量是单位时间内完成的工作量,它描述了从系统访问数据的速度,通常用它来衡量一个系统的性能。当我们执行一个任务或者一个操作的时候,这个任务会被分割成小任务并被分发到不同系统,系统将会并行且独立的执行这些分配给他们的任务。这样,一个大任务将会在非常短的时间内被执行完成。HDFS就是利用这种方式来提供高吞吐量能力的。通过并行读取数据,我们大大减少了实际读取数据的时间。
2、HDFS 读写操作
在Hadoop,我们需要通过程序或者命令行(CLI)和文件系统交互。
Hadoop分布式文件系统和Linux文件系统有很多相似之处。比如创建目录,拷贝文件,修改权限等。HDFS也提供不同的文件访问权限,如对用户、用户组或者其他用户的可读、可写、可执行权限。
我们可以通过浏览器查看HDFS文件目录,只需在浏览器输入下面的网址即可,你可以从该网址获取集群信息,例如已用容量、可用容量、可用节点数量,不可用节点数量等。
http://master-IP:50070
1、HDFS 读操作
客户端从HDFS读取文件时,必须要先和Namenode交互,获取元数据,即数据块位置、数据块数量,副本和其他细节信息。Namenode是唯一存储数据节点元数据的地方。数据存储在哪个Slave节点由Namenode来决定。namenode拿到元数据之后再去相应的datanode读取数据。当客户端或者应用程序接收到文件的所有块之后,它会把这些合并成原始文件的形式。为了安全和身份认证,namenode会给客户端提供token,在客户端从datanode读取数据之前,客户端会把它提供给datanode做身份认证,认证成功之后,才开始读取文件。
客户端如果想从HDFS读取数据,那么它首先必须和namenode交互,所以客户端通过分布式文件系统API给namenode发起请求,namenode会判断客户端是否有数据访问权限,如果有权限,namenode才会把数据块位置信息发送给客户端。
除了块位置信息,namenode还会给client提供一个安全token,在客户端读取数据之前,需要用它来做身份认证。
当客户端到datanode读取数据的时候,datanode会检查客户端提供的token,如果token没问题,datanode才允许客户端读取特定的数据。这时,客户端将会通过FSDataInputStream开始从datanode读取数据。客户端就是以这种方式直接从datanode读取数据的。
如果在读取数据期间datanode突然挂了,那么客户端会重新给namenode发送请求,namenode将会给它提供其他可用数据块的位置信息。
2、HDFS 写操作
当客户端想把文件写入到HDFS的时候,也需要先和Namenode交互。Namenode会提供slave节点的地址信息,元数据信息(如块数量、块位置等数据块元数据),基于Namenode提供的信息,客户端把文件分割成若干个数据块。之后开始把数据块发送给第一个Datanode。
客户端一旦完成数据块的写入操作,slave节点就开始把它复制到另一个节点,这个节点会把块复制到第三个节点。因为默认的副本因子是3。副本创建完之后,slave节点会给客户端发送一个最终的确认信息。而身份认证和读操作是一样的。
客户端想要把数据写入HDFS,它必须先和namenode交互。客户端通过DistributedFileSystem API给namenode发送请求。namenode接收到请求后,会把可以用于写入数据的datanode的位置信息返回给客户端,接着客户端会跟这些datanode交互,并开始通过FSDataOutputStream写入数据。数据写入和复制完成之后,datanode会给客户端发送一个确认信息通知它数据已经完成写入。
客户端一旦完成第一个块的写入,那么第一个datanode将会把写入的块复制到其他节点,该节点接收到块之后,开始把它复制到第三个节点。第三个节点会把数据已写入的确认信息发送给第二个datanode,而第二个datanode则会把数据已写入的确认信息发送给第一个datanode,然后第一个datanode会发送最终的确认信息(副本因子默认为3的情况下)。
当datanode复制数据块时,客户端只发送一个数据副本,而不考虑复制因子。因此,在Hadoop HDFS写入文件成本并不高,因为在多个datanode上并行地写入多个块。
参考文章:HDFS 教程 | HDFS 教程