image文件是什么,image文件是什么文件

  

  一、HDFS简介   

  

  上一篇文章提到,随着数据量的不断增加,不可能把所有的数据都存储在一台机器上,所以我们会把这些数据分布到不同的机器上进行存储,但是这就带来了一个问题:不方便管理和维护.   

  

  因此,我们希望有一个系统能够统一管理分布在不同操作服务器上的数据,这就是分布式文件系统.   

  

  HDFS是分布式文件系统的一种(目前使用最广泛的一种)。在使用HDFS的时候,很简单:虽然HDFS把文件存放在不同的机器里,但是我去用的时候,是把这些文件按照当做存放在一台机器里的方式使用的(但是后面有很多机器在运行):   

  

  举个例子:我调用一个RPC接口,我给他参数,他给我返回一个响应。其实我也不知道RPC接口做了什么(可能这个RPC接口已经转到其他RPC接口了)-http://www . Sina . com/。   

  

  需要说明的是:HDFS是一个屏蔽掉实现细节,对用户友好,文件系统。我们用它做什么?分布式文件系统.   

  

  现在,让我们学习一些关于HDFS的知识,这可以帮助我们更好地“使用”HDFS。   

  

  二、存数据呀学习从上面我们已经提到,HDFS是一个分布式文件系统,所以以它的数据是保存在多个系统上的.为例,如下图:一个1GB的文件将被分成几个小文件,每个服务器将存储其中的一部分。   

  

     

  

  那么肯定会有人问:要拆分多少个小文件?默认大小是128MB,每个128MB的文件在HDFS被称为切分。   

  

  显然这个128MB大小是可以匹配的。如果设置过小或过大,都不好。如果分段文件太小,一段数据可能会分布到多台机器上(寻址时间非常慢)。如果分段文件太大,数据传输时间会很慢。   

  

  PS:老版本默认64MB。   

  

  一个用户向HDFS客户端发送1GB的文件请求,HDFS客户端会根据配置(现在默认是128MB)对文件进行拆分,所以HDFS客户端会将其拆分成八个文件(也叫),然后每个服务器会存储这些拆分的文件(block)。现在让我们假设block.   

  

     

  

  这些存储每个服务器都存储两份的服务器在HDFS域中被称为真实数据。   

  

     

  

  现在的问题是,在根据配置对HDFS客户端进行分段之后,它如何知道将数据放入哪个服务器(DataNode)?这时候你就需要另一个角色,管理者(DataNode)。   

  

  NameNode实际上是一个NameNode(这种信息专业在http://www . Sina . com/)中称为“元数据”,它包括:文件路径名、每个块的ID和存储位置等。   

  

  因此,无论是读还是写,管理文件的各种信息,的客户都会先去NameNode获取相应的信息,然后再去DataNode。   

  

  如果是写操作,HDFS会在拆分文件后询问NameNode这些分段块应该写入哪个DataNode。如果是读操作,HDFS会在获取文件名时询问应该从哪个DataNode NameNode读取数据。   

  

  2.1 HDFS备份是一个分布式系统(一个大文件被分成几个小文件,存储在不同的机器上)。如果没有备份,只要其中一台机器挂机,“数据”就无法使用。   

  

  写到这里,如果你读过我写的MetaDataNameNode,的文章,你就会明白了。其实想法都是一样的。   

  

  卡夫卡要分区备份,埃尔   

asticSearch对分片进行备份,而到HDFS就是对Block进行备份。

  

尽可能将数据备份到不同的机器上,即便某台机器挂了,那就可以将备份数据拉出来用。

  

对Kafka和ElasticSearch不了解的同学,可以关注我的GitHub,搜索关键字即可查询(我觉得还算写得比较通俗易懂的)

  

注:这里的备份并不需要HDFS客户端去写,只要DataNode之间互相传递数据就好了。

  

  

2.2 NameNode的一些事从上面我们可以看到,NameNode是需要处理hdfs客户端请求的。(因为它是存储元数据的地方,无论读写都需要经过它)。

  

现在问题就来了,NameNode是怎么存放元数据的呢?

  

如果NameNode只是把元数据放到内存中,那如果NameNode这台机器重启了,那元数据就没了。如果NameNode将每次写入的数据都存储到硬盘中,那如果只针对磁盘查找和修改又会很慢(因为这个是纯IO的操作)说到这里,又想起了Kafka。Kafka也是将partition写到磁盘里边的,但人家是怎么写的?顺序IO

  

NameNode同样也是做了这个事:修改内存中的元数据,然后把修改的信息append(追加)到一个名为editlog的文件上。

  

由于append是顺序IO,所以效率也不会低。现在我们增删改查都是走内存,只不过增删改的时候往磁盘文件editlog里边追加一条。这样我们即便重启了NameNode,还是可以通过editlog文件将元数据恢复。

  

  

现在也有个问题:如果NameNode一直长期运行的话,那editlog文件应该会越来越大(因为所有的修改元数据信息都需要在这追加一条)。重启的时候需要依赖editlog文件来恢复数据,如果文件特别大,那启动的时候不就特别慢了吗?

  

的确是如此的,那HDFS是怎么做的呢?为了防止editlog过大,导致在重启的时候需要较长的时间恢复数据,所以NameNode会有一个内存快照,叫做fsimage

  

说到快照,有没有想起Redis的RDB!!

  

这样一来,重启的时候只需要加载内存快照fsimage+部分的editlog就可以了。

  

想法很美好,现实还需要解决一些事:我什么时候生成一个内存快照fsimage?我怎么知道加载哪一部分的editlog?

  

问题看起来好像复杂,其实我们就只需要一个定时任务

  

如果让我自己做的话,我可能会想:我们加一份配置,设置个时间就OK了

  

如果editlog大到什么程度或者隔了多长时间,我们就把editlog文件的数据跟内存快照fsiamge给合并起来。然后生成一个新的fsimage,把editlog给清空,覆盖旧的fsimage内存快照这样一来,NameNode每次重启的时候,拿到的都是最新的fsimage文件,editlog里边的都是没合并到fsimage的。根据这两个文件就可以恢复最新的元数据信息了。

  

HDFS也是类似上面这样干的,只不过它不是在NameNode起个定时的任务跑,而是用了一个新的角色:SecondNameNode。至于为什么?可能HDFS觉得合并所耗费的资源太大了,不同的工作交由不同的服务器来完成,也符合分布式的理念。

  

  

现在问题还是来了,此时的架构NameNode是单机的。SecondNameNode的作用只是给NameNode合并editlog和fsimage文件,如果NameNode挂了,那client就请求不到了,而所有的请求都需要走NameNode,这导致整个HDFS集群都不可用了。

  

于是我们需要保证NameNode是高可用的。一般现在我们会通过Zookeeper来实现。架构图如下:

  

  

主NameNode和从NameNode需要保持元数据的信息一致(因为如果主NameNode挂了,那从NameNode需要顶上,这时从NameNode需要有主NameNode的信息)。

  

所以,引入了Shared Edits来实现主从NameNode之间的同步,Shared Edits也叫做JournalNode。实际上就是主NameNode如果有更新元数据的信息,它的editlog会写到JournalNode,然后从NameNode会在JournalNode读取到变化信息,然后同步。从NameNode也实现了上面所说的SecondNameNode功能(合并editlog和fsimage)

  

  

稍微总结一下:

  

NameNode需要处理client请求,它是存储元数据的地方NameNode的元数据操作都在内存中,会把增删改以editlog持续化到硬盘中(因为是顺序io,所以不会太慢)由于editlog可能存在过大的问题,导致重新启动NameNode过慢(因为要依赖editlog来恢复数据),引出了fsimage内存快照。需要跑一个定时任务来合并fsimage和editlog,引出了SecondNameNode又因为NameNode是单机的,可能存在单机故障的问题。所以我们可以通过Zookeeper来维护主从NameNode,通过JournalNode(Share Edits)来实现主从NameNode元数据的一致性。最终实现NameNode的高可用。2.3 学点DataNode从上面我们就知道,我们的数据是存放在DataNode上的(还会备份)。

  

如果某个DataNode掉线了,那HDFS是怎么知道的呢?

  

DataNode启动的时候会去NameNode上注册,他俩会维持心跳,如果超过时间阈值没有收到DataNode的心跳,那HDFS就认为这个DataNode挂了。

  

还有一个问题就是:我们将Block存到DataNode上,那还是有可能这个DataNode的磁盘损坏了部分,而我们DataNode没有下线,但我们也不知道损坏了。

  

一个Block除了存放数据的本身,还会存放一份元数据(包括数据块的长度,块数据的校验和,以及时间戳)。DataNode还是会定期向NameNode上报所有当前所有Block的信息,通过元数据就可校验当前的Block是不是正常状态

  

最后其实在学习HDFS的时候,你会发现很多的思想跟之前学过的都类似。就比如提到的Kafka、Elasticsearch这些常用的分布式组件。

相关文章