我们知道主节点主要存储的元数据包括:

  1. 所有从节点的元数据信息,包括从节点的数量、每个节点的 IP 地址以及使用情况等信息

  2. 所有分布式文件的元数据信息,包括文件名、大小等基础信息,还有文件对应的数据块的元数据信息


对于存储的从节点的元数据信息很好理解。就是当从节点启动的时候,会将自己的 IP 地址、自己的磁盘总大小以及使用情况告诉主节点。


对于文件的元数据的存储和管理相对来说复杂点,这篇文章我们就要说明白主节点中存储的文件元数据。


文件元数据数据结构


首先我们需要搞明白的是文件元数据是以什么样的数据结构组织起来的。


分布式文件的元数据主要包括两个信息:

  1. 文件名

  2. 文件对应的基本信息:文件大小、文件对应哪些数据块


每个数据块的元数据又包括:

  1. 数据块的唯一 id

  2. 数据块的基本信息:数据块大小、数据块的备份数、每个数据块存储在哪台 slave 服务器中


所以在主节点中肯定需要两个数据结构来存储两个部分的信息:

  1. 文件名及其对应的文件基本信息

  2. 数据块唯一 id 及其对应的数据块的基本信息


我们来举一个具体的例子,我们现在将下面的两个文件存储在集群中:

  • /douma/tmp/test/text.txt  这个文件被划分成 3 个数据块,分别是 b1、b2、b3

  • /douma/data/product/word.txt 这个文件被划分成 2 个数据块 ,分别是 b4、b5


那么在主节点中的元数据的存储形式应该如下图所示:

大数据技术思想入门(四):分布式文件的元数据是怎么存储的_第1张图片


从上图中可以看出,文件名实际上被组织成了一棵树,这棵树我们一般称为文件目录树,其实这个和 Linux 中的文件目录树是一个意思的,在目录树中分为两种类型的节点:

  1. NodeDirectory (表示文件目录),它一般会有若干个孩子节点

  2. NodeFile (表示文件),它具有几个属性,那就是这个文件的基本信息(文件大小等)和文件对应的数据块信息


如果要查询文件对应的数据块信息的话,就可以根据这个文件对应的数据块 id 去数据块元数据中查找了。


总结,在主节点中关于文件元数据的管理主要就是两种数据的存储:

  1. 文件目录树,以及文件数据块的索引,即每个文件对应的数据块列表

  2. 数据块与 slave 服务器的关系,即某一个数据块存在哪些 slave 节点上


文件元数据存储在主节点内存


搞明白了文件元数据的存储结构,接下来我们来看下这个文件元数据到底存储在主节点的内存好点,还是存储在主节点的磁盘中好点呢?要搞明白这个问题,我们需要弄明白文件元数据本身的特点及其被访问的特点。


文件元数据本身的特点很简单,那就是数据量不大。


而文件元数据被访问的特点:

  1. 访问很频繁,不仅客户端会访问文件元数据,slave 节点也是会访问文件元数据的

  2. 会被实时的更新,因为文件会实时的创建、删除等,所以文件元数据也是需要实时被更新的


鉴于以上的特点,那么文件元数据最好就是存储在主节点的内存中,因为查询内存中的数据是很快的,而且内存中的数据的更新也是实时的。


所以在主节点的内存中会存在两个 Map :

  1. Map<文件名, 文件基本信息> 这个用于存储文件名及其对应的文件的基本信息

  2. Map<数据块唯一 id, 数据块基本信息> 这个用于存储数据块唯一 id 及其对应的数据块的基本信息


保证元数据不丢失


上面我们说到,文件元数据是存储在主节点的内存中的,内存的查询和更新速度是非常快,但是数据存储在内存有个缺点,那就是一旦主节点挂了,那么存储在主节点内存中的所有文件元数据都会丢失了,根本就找不到了,这个问题就非常的严重了。


我们可以通过将主节点内存中的文件元数据保存一份到磁盘中,也就是说对于文件元数据,内存中存储一份,磁盘中保持一份,这样既能保证文件元数据的访问性能,又能保证这些元数据不会丢失。


怎么做到将内存中的元数据保存到磁盘中呢?为了减轻主节点的压力,我们可以引入另一个辅助服务器,这个辅助服务器可以将主节点的内存中元数据拉取过来,然后将这些数据组织成可以存储到磁盘中的数据结构,最后将转换后的数据结构保存到主节点的磁盘中。


以上只是一个解决元数据丢失这个问题的思路,至于细节我们后续会再详细讲解。


系统学习大数据技术:大数据高薪就业课