HDFS原理及使用

HDFS简介

HDFS(Hadoop Distributed File System),Hadoop的分布式文件系统,它是一种允许文件通过网络在多台主机上分享的文件系统,可以让多台机器上的多个用户分享文件和存储空间,其实分布式文件管理系统有很多,HDFS只是其中一种实现而已,还有GFS(谷歌的)、TFS(淘宝的)、S3(亚马逊的),不同的分布式文件系统的特点是不一样的,HDFS是一种适合大文件存储的分布式文件系统,不适合小文件存储,什么叫小文件,例如,几KB,几M的文件都可以认为是小文件。

在这里插入图片描述

用户在写入数据和读取数据的时候会通过一个文件系统,这个文件系统后面会有很多台服务器,所以我们的数据就可以存储在多台服务器上面。后期服务器增加或者减少,对我们用户而言,不用关注,这个统一由文件系统进行管理,我们只需要和文件系统进行交互就可以了。

在这里插入图片描述
1、用户请求查看数据时候会请求主节点,主节点上面会维护所有数据的存储信息;
2、主节点会把对应数据所在的节点信息返回给用户;
3、然后用户根据数据所在的节点信息去对应的节点去读取数据,这样压力就不会全部在主节点上面。

HDFS基础操作

针对HDFS,可以在shell命令行下进行操作,就类似于操作linux中的文件系统,但是具体命令的操作格式是有一些区别的。
在这里插入图片描述
注意:如果在PATH中配置了hadoop的bin目录,那么这里可以直接使用hdfs即可。

dfs:使用hadoop bin目录的hdfs命令,后面指定dfs,表示是操作分布式文件系统的,这些属于固定格式。

-xxx:这里的xxx是一个占位符,具体我们想对hdfs做什么操作,就可以在这里指定对应的命令。

schema:HDFS的schema是hdfs。

authority:是集群中namenode所在节点的ip和对应的端口号,把ip换成主机名也是一样的,path是我们要操作的文件路径信息。

path:其实后面这一长串内容就是core-site.xml配置文件中fs.defaultFS属性的值,这个代表的是HDFS的地址。

例如:hdfs dfs -ls hdfs://bigdata01:9000/

# 查看hdfs的帮助文档
# 这里面的[]表示是可选项,<>表示是必填项
[root@bigdata01 hadoop-3.2.0]# hdfs dfs
Usage: hadoop fs [generic options]
        [-appendToFile <localsrc> ... <dst>]
        [-cat [-ignoreCrc] <src> ...]
        [-checksum <src> ...]
        [-chgrp [-R] GROUP PATH...]
        [-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
        [-chown [-R] [OWNER][:[GROUP]] PATH...]
        [-copyFromLocal [-f] [-p] [-l] [-d] [-t <thread count>] <localsrc> ... <dst>]
        [-copyToLocal [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
        [-count [-q] [-h] [-v] [-t [<storage type>]] [-u] [-x] [-e] <path> ...]
        [-cp [-f] [-p | -p[topax]] [-d] <src> ... <dst>]
        [-createSnapshot <snapshotDir> [<snapshotName>]]
        [-deleteSnapshot <snapshotDir> <snapshotName>]
        [-df [-h] [<path> ...]]
        [-du [-s] [-h] [-v] [-x] <path> ...]
        [-expunge]
        [-find <path> ... <expression> ...]
        [-get [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
        [-getfacl [-R] <path>]
        [-getfattr [-R] {-n name | -d} [-e en] <path>]
        [-getmerge [-nl] [-skip-empty-file] <src> <localdst>]
        [-head <file>]
        [-help [cmd ...]]
        [-ls [-C] [-d] [-h] [-q] [-R] [-t] [-S] [-r] [-u] [-e] [<path> ...]]
        [-mkdir [-p] <path> ...]
        [-moveFromLocal <localsrc> ... <dst>]
        [-moveToLocal <src> <localdst>]
        [-mv <src> ... <dst>]
        [-put [-f] [-p] [-l] [-d] <localsrc> ... <dst>]
        [-renameSnapshot <snapshotDir> <oldName> <newName>]
        [-rm [-f] [-r|-R] [-skipTrash] [-safely] <src> ...]
        [-rmdir [--ignore-fail-on-non-empty] <dir> ...]
        [-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec> <path>]]
        [-setfattr {-n name [-v value] | -x name} <path>]
        [-setrep [-R] [-w] <rep> <path> ...]
        [-stat [format] <path> ...]
        [-tail [-f] <file>]
        [-test -[defsz] <path>]
        [-text [-ignoreCrc] <src> ...]
        [-touch [-a] [-m] [-t TIMESTAMP ] [-c] <path> ...]
        [-touchz <path> ...]
        [-truncate [-w] <length> <path> ...]
        [-usage [cmd ...]]

Generic options supported are:
-conf <configuration file>        specify an application configuration file
-D <property=value>               define a value for a given property
-fs <file:///|hdfs://namenode:port> specify default filesystem URL to use, overrides 'fs.defaultFS' property from configurations.
-jt <local|resourcemanager:port>  specify a ResourceManager
-files <file1,...>                specify a comma-separated list of files to be copied to the map reduce cluster
-libjars <jar1,...>               specify a comma-separated list of jar files to be included in the classpath
-archives <archive1,...>          specify a comma-separated list of archives to be unarchived on the compute machines

The general command line syntax is:
command [genericOptions] [commandOptions]

# 查询指定路径信息
# 查看hdfs根目录
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -ls hdfs://bigdata01:9000/
[root@bigdata01 hadoop-3.2.0]#

其实后面hdfs的url这一串内容在使用时默认是可以省略的,因为hdfs在执行的时候会根据HDOOP_HOME自动识别配置文件中的fs.defaultFS属性.

# 查询指定路径信息
# 查看hdfs根目录
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -ls /
[root@bigdata01 hadoop-3.2.0]#

# 递归显示所有目录的信息
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -ls -R /
-rw-r--r--   2 root supergroup       1361 2020-04-08 15:34 /README.txt
drwxr-xr-x   - root supergroup          0 2020-04-08 15:44 /abc
drwxr-xr-x   - root supergroup          0 2020-04-08 15:44 /abc/xyz
drwxr-xr-x   - root supergroup          0 2020-04-08 15:43 /test

# 从本地上传文件
# 上传README.txt
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -put README.txt  /
# 再查看hdfs根目录
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -ls /
Found 1 items
-rw-r--r--   2 root supergroup       1361 2020-04-08 15:34 /README.txt
# 查看HDFS文件内容
# 查看README.txt
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -cat /README.txt
For the latest information about Hadoop, please visit our website at:

   http://hadoop.apache.org/

and our wiki, at:

   http://wiki.apache.org/hadoop/
...........

# 下载文件到本地
# 下载README.txt到本地
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -get /README.txt README.txt.bak
[root@bigdata01 hadoop-3.2.0]# ll
total 188
drwxr-xr-x. 2 1001 1002    203 Jan  8  2023 bin
drwxr-xr-x. 3 1001 1002     20 Jan  8  2019 etc
drwxr-xr-x. 2 1001 1002    106 Jan  8  2019 include
drwxr-xr-x. 3 1001 1002     20 Jan  8  2019 lib
drwxr-xr-x. 4 1001 1002   4096 Jan  8  2019 libexec
-rw-rw-r--. 1 1001 1002 150569 Oct 19  2018 LICENSE.txt
-rw-rw-r--. 1 1001 1002  22125 Oct 19  2018 NOTICE.txt
-rw-rw-r--. 1 1001 1002   1361 Oct 19  2018 README.txt
-rw-r--r--. 1 root root   1361 Apr  8 15:41 README.txt.bak
drwxr-xr-x. 3 1001 1002   4096 Apr  7 22:08 sbin
drwxr-xr-x. 4 1001 1002     31 Jan  8  2019 share
# 创建一个文件夹test
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -mkdir /test
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -ls /
Found 2 items
-rw-r--r--   2 root supergroup       1361 2020-04-08 15:34 /README.txt
drwxr-xr-x   - root supergroup          0 2020-04-08 15:43 /test

# 递归创建多级目录
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -mkdir -p /abc/xyz
You have new mail in /var/spool/mail/root
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -ls /
Found 3 items
-rw-r--r--   2 root supergroup       1361 2020-04-08 15:34 /README.txt
drwxr-xr-x   - root supergroup          0 2020-04-08 15:44 /abc
drwxr-xr-x   - root supergroup          0 2020-04-08 15:43 /test

# 删除文件
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm /README.txt
Deleted /README.txt

# 删除文件夹
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm /test
rm: `/test': Is a directory
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm -r /test
Deleted /test

# 如果是多级目录,可以递归删除
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm -r /abc
Deleted /abc

统计HDFS中文件的个数和每个文件的大小

# 先向HDFS中上传几个文件
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -put LICENSE.txt /
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -put NOTICE.txt /
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -put README.txt /

# 1、统计根目录下文件的个数
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -ls / |grep /| wc -l    
3

# 2、统计根目录下每个文件的大小,最终把文件名称和大小打印出来
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -ls / |grep / |  awk '{print $8,$5}'
/LICENSE.txt 150569
/NOTICE.txt 22125
/README.txt 1361

NameNode

HDFS支持主从结构,主节点称为 NameNode ,是因为主节点上运行的有NameNode进程,NameNode支持多个。
从节点称为 DataNode ,是因为从节点上面运行的有DataNode进程,DataNode支持多个,
HDFS中还包含一个 SecondaryNameNode 进程,辅助节点。

HDFS的体系结构,这里面的TCP、RPC、HTTP表示是不同的网络通信方式。

NameNode是整个文件系统的管理节点,主要维护着整个文件系统的文件目录树,文件/目录的信息 和 每个文件对应的数据块列表,并且还负责接收用户的操作请求。文件信息都在namenode上面存储着的。

  • 目录树:表示目录之间的层级关系,就是我们在hdfs上执行ls命令可以看到的那个目录结构信息。
  • 文件/目录的信息:表示文件/目录的的一些基本信息,所有者 属组 修改时间 文件大小等信息。
  • 每个文件对应的数据块列表:如果一个文件太大,那么在集群中存储的时候会对文件进行切割,这个时候就类似于会给文件分成一块一块的,存储到不同机器上面。所以HDFS还要记录一下一个文件到底被分了多少块,每一块都在什么地方存储着。
  • 接收用户的操作请求:其实我们在命令行使用hdfs操作的时候,是需要先和namenode通信才能开始去操作数据的。
# 上传200M左右的文件
[root@bigdata01 hadoop-3.2.0]# cd /data/soft/
[root@bigdata01 soft]# hdfs dfs -put hadoop-3.2.0.tar.gz  /

到集群的web ui(默认端口9870)界面查看,能看到分成了多个Block块,一个文件对应有多少个Block块信息 是在namenode里面保存着的。
在这里插入图片描述

NameNode主要包括以下文件:

  • fsimange: 元数据镜像文件,存储某一时刻NameNode内存中的元数据信息,就类似是定时做了一个快照操作。【这里的元数据信息是指文件目录树、文件/目录的信息、每个文件对应的数据块列表】。
  • edits: 操作日志文件【事务文件】,这里面会实时记录用户的所有操作。
  • seen_txid: 是存放transactionId的文件,format之后是0,它代表的是namenode里面的edits_*文件的尾数,namenode重启的时候,会按照seen_txid的数字,顺序从头跑edits_0000001~到seen_txid的数字。如果根据对应的seen_txid无法加载到对应的文件,NameNode进程将不会完成启动以保护数据一致性。
  • version:保存了集群的版本信息。

这些文件所在的路径是由hdfs-default.xml的dfs.namenode.name.dir属性控制的。

hdfs-default.xml文件在hadoop-3.2.0\share\hadoop\hdfs\hadoop-hdfs-3.2.0.jar中,这个文件中包含了HDFS相关的所有默认参数

在配置集群的时候会修改一个hdfs-site.xml文件,hdfs-site.xml文件属于hdfs-default.xml的一个扩展,它可以覆盖掉hdfs-default.xml中同名的参数

# 查看dfs.namenode.name.dir文件
<property>
  <name>dfs.namenode.name.dir</name>
  <value>file://${hadoop.tmp.dir}/dfs/name</value>
  <description>Determines where on the local filesystem the DFS name node
      should store the name table(fsimage).  If this is a comma-delimited list
      of directories then the name table is replicated in all of the
      directories, for redundancy. </description>
</property>

dfs.namenode.name.dir这个属性的值是由hadoop.tmp.dir属性控制的,hadoop.tmp.dir属性的默认值在core-default.xmlcore-site.xml是core-default.xml的扩展,core-site.xml中的hadoop.tmp.dir属性会覆盖掉core-default.xml中的值查看core-site.xml中hadoop.tmp.dir是:/data/hadoop_repo。
所以最终dfs.namenode.name.dir属性的值就是:/data/hadoop_repo/dfs/name。

进入到/data/hadoop_repo/dfs/name目录下,有current 目录,表示当前的意思;in_use.lock 文件名后缀值lock 表示是锁的意思,文件名是in_use 表示这个文件现在正在使用,不允许你再启动namenode。

当我们启动namonde的时候 会判断这个目录下是否有in_use.lock 这个相当于一把锁,如果没有的话,才可以启动成功,启动成功之后就会加一把锁, 停止的时候会把这个锁去掉。

[root@bigdata01 name]# cd /data/hadoop_repo/dfs/name
[root@bigdata01 name]# ll
total 8
drwxr-xr-x. 2 root root 4096 Apr  8 21:31 current
-rw-r--r--. 1 root root   14 Apr  8 20:30 in_use.lock
[root@bigdata01 name]# cd current
[root@bigdata01 current]# ll
total 4152
-rw-r--r--. 1 root root      42 Apr  7 22:17 edits_0000000000000000001-0000000000000000002
-rw-r--r--. 1 root root 1048576 Apr  7 22:17 edits_0000000000000000003-0000000000000000003
-rw-r--r--. 1 root root      42 Apr  7 22:22 edits_0000000000000000004-0000000000000000005
-rw-r--r--. 1 root root 1048576 Apr  7 22:22 edits_0000000000000000006-0000000000000000006
-rw-r--r--. 1 root root      42 Apr  8 14:53 edits_0000000000000000007-0000000000000000008
-rw-r--r--. 1 root root    1644 Apr  8 15:53 edits_0000000000000000009-0000000000000000031
-rw-r--r--. 1 root root    1523 Apr  8 16:53 edits_0000000000000000032-0000000000000000051
-rw-r--r--. 1 root root      42 Apr  8 17:53 edits_0000000000000000052-0000000000000000053
-rw-r--r--. 1 root root 1048576 Apr  8 17:53 edits_0000000000000000054-0000000000000000054
-rw-r--r--. 1 root root      42 Apr  8 20:31 edits_0000000000000000055-0000000000000000056
-rw-r--r--. 1 root root     523 Apr  8 21:31 edits_0000000000000000057-0000000000000000065
-rw-r--r--. 1 root root 1048576 Apr  8 21:31 edits_inprogress_0000000000000000066
-rw-r--r--. 1 root root     652 Apr  8 20:31 fsimage_0000000000000000056
-rw-r--r--. 1 root root      62 Apr  8 20:31 fsimage_0000000000000000056.md5
-rw-r--r--. 1 root root     661 Apr  8 21:31 fsimage_0000000000000000065
-rw-r--r--. 1 root root      62 Apr  8 21:31 fsimage_0000000000000000065.md5
-rw-r--r--. 1 root root       3 Apr  8 21:31 seen_txid
-rw-r--r--. 1 root root     219 Apr  8 20:30 VERSION

current里面有edits文件 和fsimage文件

fsimage文件有两个文件名相同的,有一个后缀是md5,md5是一种加密算法,这个其实主要是为了做md5校验的,为了保证文件传输的过程中不出问题,相同内容的md5是一样的;如果根据md5对fsimage的内容进行加密,获取一个值和fsimage.md5中的内容进行比较,如果一样,说明接收到的文件就是完整的。
可以把fsimage 拆开 fs 是文件系统 filesystemimage是镜像说明是文件系统镜像,把文件的当前信息记录下来

# 查看fsimage_0000000000000000056镜像文件,转换成xml
# -i 输入文件 -o 输出文件
[root@bigdata01 current]# hdfs oiv -p XML -i fsimage_0000000000000000056 -o fsimage56.xml
2020-04-08 22:23:32,851 INFO offlineImageViewer.FSImageHandler: Loading 4 strings
2020-04-08 22:23:32,916 INFO namenode.FSDirectory: GLOBAL serial map: bits=29 maxEntries=536870911
2020-04-08 22:23:32,916 INFO namenode.FSDirectory: USER serial map: bits=24 maxEntries=16777215
2020-04-08 22:23:32,916 INFO namenode.FSDirectory: GROUP serial map: bits=24 maxEntries=16777215
2020-04-08 22:23:32,916 INFO namenode.FSDirectory: XATTR serial map: bits=24 maxEntries=16777215

# 查看转换成xml的镜像文件fsimage56.xml
<?xml version="1.0"?>
<fsimage>
   <version>
       <layoutVersion>-65</layoutVersion>
       <onDiskVersion>1</onDiskVersion>
    <oivRevision>e97acb3bd8f3befd27418996fa5d4b50bf2e17bf</oivRevision>
   </version>
   <NameSection>
       <namespaceId>498554338</namespaceId>
       <genstampV1>1000</genstampV1>
       <genstampV2>1005</genstampV2>
       <genstampV1Limit>0</genstampV1Limit>
       <lastAllocatedBlockId>1073741829</lastAllocatedBlockId>
       <txid>56</txid>
   </NameSection>
   <ErasureCodingSection>
       <erasureCodingPolicy>
           <policyId>5</policyId>
           <policyName>RS-10-4-1024k</policyName>
           <cellSize>1048576</cellSize>
           <policyState>DISABLED</policyState>
           <ecSchema>
               <codecName>rs</codecName>
               <dataUnits>10</dataUnits>
               <parityUnits>4</parityUnits>
           </ecSchema>
       </erasureCodingPolicy>
       <erasureCodingPolicy>
           <policyId>2</policyId>
           <policyName>RS-3-2-1024k</policyName>
           <cellSize>1048576</cellSize>
           <policyState>DISABLED</policyState>
           <ecSchema>
               <codecName>rs</codecName>
               <dataUnits>3</dataUnits>
               <parityUnits>2</parityUnits>
           </ecSchema>
       </erasureCodingPolicy>
       <erasureCodingPolicy>
           <policyId>1</policyId>
           <policyName>RS-6-3-1024k</policyName>
           <cellSize>1048576</cellSize>
           <policyState>ENABLED</policyState>
           <ecSchema>
               <codecName>rs</codecName>
               <dataUnits>6</dataUnits>
               <parityUnits>3</parityUnits>
           </ecSchema>
       </erasureCodingPolicy>
       <erasureCodingPolicy>
           <policyId>3</policyId>
           <policyName>RS-LEGACY-6-3-1024k</policyName>
           <cellSize>1048576</cellSize>
           <policyState>DISABLED</policyState>
           <ecSchema>
               <codecName>rs-legacy</codecName>
               <dataUnits>6</dataUnits>
               <parityUnits>3</parityUnits>
           </ecSchema>
       </erasureCodingPolicy>
       <erasureCodingPolicy>
           <policyId>4</policyId>
           <policyName>XOR-2-1-1024k</policyName>
           <cellSize>1048576</cellSize>
           <policyState>DISABLED</policyState>
           <ecSchema>
               <codecName>xor</codecName>
               <dataUnits>2</dataUnits>
               <parityUnits>1</parityUnits>
           </ecSchema>
       </erasureCodingPolicy>
   </ErasureCodingSection>
   <INodeSection>
       <lastInodeId>16395</lastInodeId>
       <numInodes>4</numInodes>
       <inode>
           <id>16385</id>
           <type>DIRECTORY</type>
           <name></name>
           <mtime>1586332531935</mtime>
           <permission>root:supergroup:0755</permission>
           <nsquota>9223372036854775807</nsquota>
           <dsquota>-1</dsquota>
       </inode>
       <inode>
           <id>16393</id>
           <type>FILE</type>
           <name>LICENSE.txt</name>
           <replication>2</replication>
           <mtime>1586332513657</mtime>
           <atime>1586332513485</atime>
           <preferredBlockSize>134217728</preferredBlockSize>
           <permission>root:supergroup:0644</permission>
           <blocks>
               <block>
                   <id>1073741827</id>
                   <genstamp>1003</genstamp>
                   <numBytes>150569</numBytes>
               </block>
           </blocks>
           <storagePolicyId>0</storagePolicyId>
       </inode>
       <inode>
           <id>16394</id>
           <type>FILE</type>
           <name>NOTICE.txt</name>
           <replication>2</replication>
           <mtime>1586332522962</mtime>
           <atime>1586332522814</atime>
           <preferredBlockSize>134217728</preferredBlockSize>
           <permission>root:supergroup:0644</permission>
           <blocks>
               <block>
                   <id>1073741828</id>
                   <genstamp>1004</genstamp>
                   <numBytes>22125</numBytes>
               </block>
           </blocks>
           <storagePolicyId>0</storagePolicyId>
       </inode>
       <inode>
           <id>16395</id>
           <type>FILE</type>
           <name>README.txt</name>
           <replication>2</replication>
           <mtime>1586332531932</mtime>
           <atime>1586332531689</atime>
           <preferredBlockSize>134217728</preferredBlockSize>
           <permission>root:supergroup:0644</permission>
           <blocks>
               <block>
                   <id>1073741829</id>
                   <genstamp>1005</genstamp>
                   <numBytes>1361</numBytes>
               </block>
           </blocks>
           <storagePolicyId>0</storagePolicyId>
       </inode>
   </INodeSection>
   <INodeReferenceSection></INodeReferenceSection>
   <SnapshotSection>
       <snapshotCounter>0</snapshotCounter>
       <numSnapshots>0</numSnapshots>
   </SnapshotSection>
   <INodeDirectorySection>
       <directory>
           <parent>16385</parent>
           <child>16393</child>
           <child>16394</child>
           <child>16395</child>
       </directory>
   </INodeDirectorySection>
   <FileUnderConstructionSection></FileUnderConstructionSection>
   <SecretManagerSection>
       <currentId>0</currentId>
       <tokenSequenceNumber>0</tokenSequenceNumber>
       <numDelegationKeys>0</numDelegationKeys>
       <numTokens>0</numTokens>
   </SecretManagerSection>
   <CacheManagerSection>
       <nextDirectiveId>1</nextDirectiveId>
       <numDirectives>0</numDirectives>
       <numPools>0</numPools>
   </CacheManagerSection>
</fsimage>

fsimage56.xml里面最外层是一个fsimage标签,看里面的inode标签,这个inode表示是hdfs中的每一个目录或者文件信息。

<inode>
   <id>16393</id>
   <type>FILE</type>
   <name>LICENSE.txt</name>
   <replication>2</replication>
   <mtime>1586332513657</mtime>
   <atime>1586332513485</atime>
   <preferredBlockSize>134217728</preferredBlockSize>
   <permission>root:supergroup:0644</permission>
   <blocks>
       <block>
           <id>1073741827</id>
           <genstamp>1003</genstamp>
           <numBytes>150569</numBytes>
       </block>
   </blocks>
   <storagePolicyId>0</storagePolicyId>
</inode>
  • id:唯一编号
  • type:文件类型
  • name:文件名称
  • replication:文件的副本数量
  • mtime:修改时间
  • atime:访问时间
  • preferredBlockSize:推荐每一个数据块的大小
  • permission:权限信息
  • blocks:包含多少数据块【文件被切成数据块】
  • block:
    • 内部的id表示是块id,
    • genstamp是一个唯一编号,
    • numBytes表示当前数据块的实际大小,
  • storagePolicyId表示是数据的存储策略

fsimage这个文件中其实就维护了整个文件系统的文件目录树,文件/目录的元信息和每个文件对应的数据块列表,所以说fsimage中存放了hdfs最核心的数据。

edits文件为事务文件。

当上传大文件时,一个大文件会分为多个block,那么edits文件中就会记录这些block的上传状态,只有当全部block都上传成功,这时edits中才会记录这个文件上传成功,那么执行hdfs dfs -ls 就能查到这个文件,所以当我们在hdfs中执行ls命令的时候,其实会查询fsimage和edits中的内容。

首先固化的一些文件内容是存储在fsimage文件中,当前正在上传的文件信息是存储在edits文件中。

# 将edits_0000000000000000057-0000000000000000065转换成edits.xml
[root@bigdata01 current]# hdfs oev -i  edits_0000000000000000057-0000000000000000065  -o edits.xml

分析生成的edits.xml文件里面有很多record。每一个record代表不同的操作。
例如 OP_ADD,OP_CLOSE 等等,具体挑一个实例进行分析。

  • OP_ADD:执行上传操作
  • OP_ALLOCATE_BLOCK_ID:申请block块id
  • OP_SET_GENSTAMP_V2:设置GENSTAMP,block里的一个唯一编号
  • OP_ADD_BLOCK:添加block块
  • OP_CLOSE:关闭上传操作
# 查看edits.xml
<RECORD>
    <OPCODE>OP_ADD</OPCODE>
    <DATA>
      <TXID>58</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>16396</INODEID>
      <PATH>/user.txt</PATH>
      <REPLICATION>3</REPLICATION>
      <MTIME>1586349095694</MTIME>
      <ATIME>1586349095694</ATIME>
      <BLOCKSIZE>134217728</BLOCKSIZE>
      <CLIENT_NAME>DFSClient_NONMAPREDUCE_-1768454371_1</CLIENT_NAME>
      <CLIENT_MACHINE>192.168.182.1</CLIENT_MACHINE>
      <OVERWRITE>true</OVERWRITE>
      <PERMISSION_STATUS>
        <USERNAME>yehua</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>420</MODE>
      </PERMISSION_STATUS>
      <ERASURE_CODING_POLICY_ID>0</ERASURE_CODING_POLICY_ID>
      <RPC_CLIENTID>1722b83a-2dc7-4c46-baa9-9fa956b755cd</RPC_CLIENTID>
      <RPC_CALLID>0</RPC_CALLID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
    <DATA>
      <TXID>59</TXID>
      <BLOCK_ID>1073741830</BLOCK_ID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
    <DATA>
      <TXID>60</TXID>
      <GENSTAMPV2>1006</GENSTAMPV2>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ADD_BLOCK</OPCODE>
    <DATA>
      <TXID>61</TXID>
      <PATH>/user.txt</PATH>
      <BLOCK>
        <BLOCK_ID>1073741830</BLOCK_ID>
        <NUM_BYTES>0</NUM_BYTES>
        <GENSTAMP>1006</GENSTAMP>
      </BLOCK>
      <RPC_CLIENTID/>
      <RPC_CALLID>-2</RPC_CALLID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_CLOSE</OPCODE>
    <DATA>
      <TXID>62</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>0</INODEID>
      <PATH>/user.txt</PATH>
      <REPLICATION>3</REPLICATION>
      <MTIME>1586349096480</MTIME>
      <ATIME>1586349095694</ATIME>
      <BLOCKSIZE>134217728</BLOCKSIZE>
      <CLIENT_NAME/>
      <CLIENT_MACHINE/>
      <OVERWRITE>false</OVERWRITE>
      <BLOCK>
        <BLOCK_ID>1073741830</BLOCK_ID>
        <NUM_BYTES>17</NUM_BYTES>
        <GENSTAMP>1006</GENSTAMP>
      </BLOCK>
      <PERMISSION_STATUS>
        <USERNAME>yehua</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>420</MODE>
      </PERMISSION_STATUS>
    </DATA>
  </RECORD>

edits里面的每一个record都有一个事务id,txid。
事务id是连续的,其实一个put操作会在edits文件中产生很多的record,对应的就是很多步骤,这些步骤对我们是屏蔽的。

注意:所有对hdfs的增删改操作都会在edits文件中留下信息,edits文件会定期合并到fsimage文件中。这个其实是框架去做的,在合并的时候会对edits中的内容进行转换,生成新的内容,其实edits中保存的内容太细化,单单一个上传操作就分为了好几步,其实上传成功后,只需要保存文件具体存储的block信息,所以在合并的时候其实是对edits中的内容进行精简。

secondarynamenode进程负责定期的把edits中的内容合并到fsimage中。这是一个单独的进程,在实际工作中部署的时候,也需要部署到一个单独的节点上面。

注意:在NameNode的HA架构中没有SecondaryNameNode进程,文件合并操作会由standby NameNode负责实现。所以在Hadoop集群中,SecondaryNameNode进程并不是必须的。

current目录中还有一个seen_txid文件,HDFS在format格式化后就是0。
current目录中seen_txid代表的是namenode里面的edits_?文件的尾数,namenode重启的时候,会按照seen_txid的数字,顺序从头跑edits_0000001~到seen_txid的数字。如果根据对应的seen_txid无法加载到对应的文件,NameNode进程将不会完成启动以保护数据一致性。

[root@bigdata01 current]# cat seen_txid 
66

current目录下面还有一个VERSION文件,保存了集群的版本信息
当重新对hdfs格式化之后,版本变化,VERSION文件里面的信息会变化。

[root@bigdata01 current]# cat VERSION 
#Wed Apr 08 20:30:00 CST 2020
namespaceID=498554338
clusterID=CID-cc0792dd-a861-4a3f-9151-b0695e4c7e70
cTime=1586268855170
storageType=NAME_NODE
blockpoolID=BP-1517789416-192.168.182.100-1586268855170
layoutVersion=-65

SecondaryNameNode介绍

SecondaryNameNode主要负责定期的把edits文件中的内容合并到fsimage中。这个合并操作称为checkpoint,在合并的时候会对edits中的内容进行转换,生成新的内容保存到fsimage文件中。

注意:在NameNode的HA架构中没有SecondaryNameNode进程,文件合并操作会由standby NameNode负责实现。所以在Hadoop集群中,SecondaryNameNode进程并不是必须的。

DataNode介绍

DataNode是提供真实文件数据的存储服务。
datanode:

  • block
  • replication。

block,HDFS会按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个Block,HDFS默认Block大小是 128MB。

blokc块是HDFS读写数据的基本单位,不管你的文件是文本文件 还是视频 或者音频文件,针对hdfs而言 都是字节。

block信息可以在fsimage文件中看到,也可以在hdfs webui上面看到block的id信息,并且也会显示这个数据在哪个节点上面。
在这里插入图片描述
datanode中数据的具体存储位置是由dfs.datanode.data.dir来控制的,查询hdfs-default.xml,
发现dfs.datanode.data.dir这个属性的值是由hadoop.tmp.dir属性控制的,hadoop.tmp.dir属性的默认值在core-default.xmlcore-site.xml是core-default.xml的扩展,core-site.xml中的hadoop.tmp.dir属性会覆盖掉core-default.xml中的值查看core-site.xml中hadoop.tmp.dir是:/data/hadoop_repo。
所以最终dfs.datanode.data.dir属性的值就是:/data/hadoop_repo/dfs/data。

# 通过查询hdfs-default.xml
<property>
  <name>dfs.datanode.data.dir</name>
  <value>file://${hadoop.tmp.dir}/dfs/data</value>
  <description>Determines where on the local filesystem an DFS data node
  should store its blocks.  If this is a comma-delimited
  list of directories, then data will be stored in all named
  directories, typically on different devices. The directories should be tagged
  with corresponding storage types ([SSD]/[DISK]/[ARCHIVE]/[RAM_DISK]) for HDFS
  storage policies. The default storage type will be DISK if the directory does
  not have a storage type tagged explicitly. Directories that do not exist will
  be created if local filesystem permission allows.
  </description>
</property>

# 查看从节点bigdata02中/data/hadoop_repo/dfs/data/ 
[root@bigdata02 ~]# cd /data/hadoop_repo/dfs/data/
[root@bigdata02 data]# ll
total 4
drwxr-xr-x. 3 root root 72 Apr  7 22:21 current
-rw-r--r--. 1 root root 14 Apr  8 20:30 in_use.lock

# 查看datanode中current
[root@bigdata02 data]# cd current/
[root@bigdata02 current]# ll
total 4
drwx------. 4 root root  54 Apr  8 20:30 BP-1517789416-192.168.182.100-1586268855170
-rw-r--r--. 1 root root 229 Apr  8 20:30 VERSION

# 查看datanode中current/BP-1517789416-192.168.182.100-1586268855170/
[root@bigdata02 current]# cd BP-1517789416-192.168.182.100-1586268855170/
[root@bigdata02 BP-1517789416-192.168.182.100-1586268855170]# ll
total 4
drwxr-xr-x. 4 root root  64 Apr  8 20:25 current
-rw-r--r--. 1 root root 166 Apr  7 22:21 scanner.cursor
drwxr-xr-x. 2 root root   6 Apr  8 20:30 tmp

# 查看datanode中current/BP-1517789416-192.168.182.100-1586268855170/current/
[root@bigdata02 BP-1517789416-192.168.182.100-1586268855170]# cd current/
[root@bigdata02 current]# ll
total 8
-rw-r--r--. 1 root root  20 Apr  8 20:25 dfsUsed
drwxr-xr-x. 3 root root  21 Apr  8 15:34 finalized
drwxr-xr-x. 2 root root   6 Apr  8 22:13 rbw
-rw-r--r--. 1 root root 146 Apr  8 20:30 VERSION

# 查看datanode中current/BP-1517789416-192.168.182.100-1586268855170/current/finalized/
[root@bigdata02 current]# cd finalized/
[root@bigdata02 finalized]# ll
total 0
drwxr-xr-x. 3 root root 21 Apr  8 15:34 subdir0
# 查看datanode中current/BP-1517789416-192.168.182.100-1586268855170/current/finalized/subdir0/
[root@bigdata02 finalized]# cd subdir0/
[root@bigdata02 subdir0]# ll
total 4
drwxr-xr-x. 2 root root 4096 Apr  8 22:13 subdir0
# 查看datanode中current/BP-1517789416-192.168.182.100-1586268855170/current/finalized/subdir0/subdir0/
[root@bigdata02 subdir0]# cd subdir0/
[root@bigdata02 subdir0]# ll
total 340220
-rw-r--r--. 1 root root     22125 Apr  8 15:55 blk_1073741828
-rw-r--r--. 1 root root       183 Apr  8 15:55 blk_1073741828_1004.meta
-rw-r--r--. 1 root root      1361 Apr  8 15:55 blk_1073741829
-rw-r--r--. 1 root root        19 Apr  8 15:55 blk_1073741829_1005.meta
-rw-r--r--. 1 root root        17 Apr  8 20:31 blk_1073741830
-rw-r--r--. 1 root root        11 Apr  8 20:31 blk_1073741830_1006.meta
-rw-r--r--. 1 root root 134217728 Apr  8 22:13 blk_1073741831
-rw-r--r--. 1 root root   1048583 Apr  8 22:13 blk_1073741831_1007.meta
-rw-r--r--. 1 root root 134217728 Apr  8 22:13 blk_1073741832
-rw-r--r--. 1 root root   1048583 Apr  8 22:13 blk_1073741832_1008.meta
-rw-r--r--. 1 root root  77190019 Apr  8 22:13 blk_1073741833
-rw-r--r--. 1 root root    603055 Apr  8 22:13 blk_1073741833_1009.meta

查看datanode中current/BP-1517789416-192.168.182.100-1586268855170/current/finalized/subdir0/subdir0/里面有很多的block块。

注意: block块里.meta文件也是做校验用的。

根据前面看到的blockid信息到这对应的找到文件,可以直接查看,发现文件内容就是之前上传上去的内容。

[root@bigdata02 subdir0]# cat blk_1073741830
jack
tom
jessic
[root@bigdata02 subdir0]# 

注意:这个block中的内容可能只是文件的一部分,如果文件较大,就会分为多个block存储,默认hadoop3中一个block的大小为128M。根据字节进行截取,截取到128M就是一个block。如果文件大小没有默认的block块大,那最终就只有一个block。
HDFS中,如果一个文件小于一个数据块的大小,那么并不会占用整个数据块的存储空间。

在这里插入图片描述
注意:这个block块是hdfs产生的,如果直接把文件上传到这个block文件所在的目录,这时hdfs是不识别的,没有用的。

副本

副本表示数据有多少个备份,现在的集群有两个从节点,所以最多可以有2个备份,这个是在hdfs-site.xml中进行配置的dfs.replication,默认这个参数的配置是3。表示会有3个副本。副本只有一个作用就是保证数据安全。

NameNode总结

注意:block块存放在哪些datanode上,只有datanode自己知道,
当集群启动的时候,datanode会扫描自己节点上面的所有block块信息,然后把节点和这个节点上的所有block块信息告诉给namenode。这个关系是每次重启集群都会动态加载的【这个其实就是集群为什么数据越多,启动越慢的原因】。

fsimage(edits)文件中保存的有文件和block块之间的信息,是block块和节点之间的关系,这两块关联在一起之后,就可以根据文件找到对应的block块,再根据block块找到对应的datanode节点,这样就真正找到了数据。所以其实namenode中不仅维护了文件和block块的信息,还维护了block块和所在的datanode节点的信息。

可以理解为namenode维护了两份关系:

  • 第一份关系:file 与block list的关系(文件和block块的关系),对应的关系信息存储在fsimage和edits文件中,当NameNode启动的时候会把文件中的元数据信息加载到内存中。
  • 第二份关系:datanode与block的关系(block块和datanode节点的关系),对应的关系主要在集群启动的时候保存在内存中,当DataNode启动时会把当前节点上的Block信息和datanode节点信息上报给NameNode。

注意:NameNode启动的时候会把文件中的元数据信息加载到内存中,然后每一个文件的元数据信息会占用150字节的内存空间,这个是恒定的,和文件大小没有关系,HDFS不适合存储小文件,其实主要原因就在这里,不管是大文件还是小文件,一个文件的元数据信息在NameNode中都会占用150字节,NameNode节点的内存是有限的,所以它的存储能力也是有限的,如果存储一堆都是几KB的小文件,最后发现NameNode的内存占满了,确实存储了很多文件,但是文件的总体大小却很小,这样就失去了HDFS存在的价值。

最后,在datanode的数据目录下面的current目录中也有一个VERSION文件,datanode的VERSION文件和namenode的VERSION文件是有一些相似之处的,具体对比一下两个文件的内容:

# namenode的VERSION文件
[root@bigdata01 current]# cat VERSION 
#Wed Apr 08 20:30:00 CST 2020
namespaceID=498554338
clusterID=CID-cc0792dd-a861-4a3f-9151-b0695e4c7e70
cTime=1586268855170
storageType=NAME_NODE
blockpoolID=BP-1517789416-192.168.182.100-1586268855170
layoutVersion=-65

# datanode的VERSION文件
[root@bigdata02 current]# cat VERSION 
#Wed Apr 08 20:30:04 CST 2020
storageID=DS-0e86cd27-4961-4526-bacb-3b692a90b1b0
clusterID=CID-cc0792dd-a861-4a3f-9151-b0695e4c7e70
cTime=0
datanodeUuid=0b09f3d7-442d-4e28-b3cc-2edb0991bae3
storageType=DATA_NODE
layoutVersion=-57

格式化
namenode不要随便格式化,因为格式化了以后VERSION里面的clusterID会变,但是datanode的VERSION中的clusterID并没有变,所以就对应不上了。
如果确实要重新格式化的话需要把/data/hadoop_repo数据目录下的内容都清空,全部都重新生成是可以的。

HDFS的回收站

HDFS会为每一个用户创建一个回收站目录:/user/用户名/.Trash/,每一个被用户在Shell命令行删除的文件/目录,会进入到对应的回收站目录中,在回收站中的数据都有一个生存周期,也就是当回收站中的文件/目录在一段时间之内没有被用户恢复的话,HDFS就会自动的把这个文件/目录彻底删除,用户就永远也找不回这个文件/目录了。

默认情况下hdfs的回收站是没有开启的,需要通过一个配置来开启,在core-site.xml中添加如下配置,value的单位是分钟,1440分钟表示是一天的生存周期。

<property>
    <name>fs.trash.interval</name>
    <value>1440</value>
</property>

验证

# 在修改配置信息之前先验证一下删除操作,显示的是直接删除掉了。
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm -r /NOTICE.txt
Deleted /NOTICE.txt

# 修改回收站配置,先在bigdata01上操作,然后再同步到其它两个节点,先停止集群。
[root@bigdata01 hadoop-3.2.0]# sbin/stop-all.sh 
[root@bigdata01 hadoop-3.2.0]# vi etc/hadoop/core-site.xml 
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://bigdata01:9000</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/data/hadoop_repo</value>
   </property>
    <property>
        <name>fs.trash.interval</name>
        <value>1440</value>
    </property>
</configuration>
[root@bigdata01 hadoop-3.2.0]# scp -rq etc/hadoop/core-site.xml bigdata02:/data/soft/hadoop-3.2.0/etc/hadoop/
[root@bigdata01 hadoop-3.2.0]# scp -rq etc/hadoop/core-site.xml bigdata03:/data/soft/hadoop-3.2.0/etc/hadoop/

# 启动集群,再执行删除操作
[root@bigdata01 hadoop-3.2.0]# sbin/start-all.sh
[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm -r /README.txt
2020-04-09 11:43:47,664 INFO fs.TrashPolicyDefault: Moved: 'hdfs://bigdata01:9000/README.txt' to trash at: hdfs://bigdata01:9000/user/root/.Trash/Current/README.txt

# 此时看到提示信息说把删除的文件移到到了指定目录中,其实就是移动到了当前用户的回收站目录。

回收站的文件也是可以下载到本地的。其实在这回收站只是一个具备了特殊含义的HDFS目录。

注意:如果删除的文件过大,超过回收站大小的话会提示删除失败,
需要指定参数 -skipTrash ,指定这个参数表示删除的文件不会进回收站。

[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm -r -skipTrash /user.txt
Deleted /user.txt

HDFS的安全模式

在平时操作HDFS的时候,有时候可能会遇到这个问题,特别是刚启动集群的时候去上传或者删除文件,会发现报错,提示NameNode处于safe mode。这个属于HDFS的安全模式,因为在集群每次重新启动的时候,HDFS都会检查集群中文件信息是否完整,例如副本是否缺少之类的信息,所以这个时间段内是不允许对集群有修改操作的,如果遇到了这个情况,可以稍微等一会,等HDFS自检完毕,就会自动退出安全模式。

[root@bigdata01 hadoop-3.2.0]# hdfs dfs -rm -r /hadoop-3.2.0.tar.gz
2020-04-09 12:00:36,646 WARN fs.TrashPolicyDefault: Can't create trash directory: hdfs://bigdata01:9000/user/root/.Trash/Current
org.apache.hadoop.hdfs.server.namenode.SafeModeException: Cannot create directory /user/root/.Trash/Current. Name node is in safe mode.

此时访问HDFS的web ui界面,可以看到下面信息,on表示处于安全模式,off表示安全模式已结束。
在这里插入图片描述
通过hdfs命令也可以查看当前的状态

[root@bigdata01 hadoop-3.2.0]# hdfs dfsadmin -safemode get
Safe mode is ON

如果想快速离开安全模式,可以通过命令强制离开,正常情况下建议等HDFS自检完毕,自动退出。

[root@bigdata01 hadoop-3.2.0]# hdfs dfsadmin -safemode leave
Safe mode is OFF

HDFS的高可用和高扩展

在HDFS的设计中,NameNode也是可以支持多个的,一个主的,多个备用的,当主的挂掉了,备用的可以顶上去,这样就可以解决NameNode节点宕机导致的单点故障问题了,也就实现了HDFS的高可用。

一个主NameNode,多个备用的NameNode的方案只能解决NameNode的单点故障问题,无法解决单个NameNode内存不够用的问题。
官方提供了Federation机制(联邦),它可以解决单节点内存不够用的情况,就是HDFS的高扩展。

HDFS的高可用(HA)

HDFS的高可用,HA(High Available)。
在这里插入图片描述
HDFS的HA,指的是在一个集群中存在多个NameNode,分别运行在独立的物理节点上。在任何时间点,只有一个NameNode是处于Active状态,其它的是处于Standby状态。 Active NameNode(简写为Active NN)负责所有的客户端的操作,而Standby NameNode(简写为Standby NN)用来同步Active NameNode的状态信息,以提供快速的故障恢复能力。

为了保证Active NN与Standby NN节点状态同步,即元数据保持一致。除了DataNode需要向这些NameNode发送block位置信息外,还构建了一组独立的守护进程”JournalNodes”(简写为JN),用来同步Edits信息。当Active NN执行任何有关命名空间的修改,它需要持久化到一半以上的JNs上。而Standby NN负责观察JNs的变化,读取从Active NN发送过来的Edits信息,并更新自己内部的命名空间。一旦Active NN遇到错误,Standby NN需要保证从JNs中读出了全部的Edits,然后切换成Active状态,如果有多个Standby NN,还会涉及到选主的操作,选择一个切换为Active 状态。

需要保证Active NN与Standby NN节点状态同步,即元数据保持一致。

这里的元数据包含两块,一个是静态的,一个是动态的。

静态的是fsimage和edits,其实fsimage是由edits文件合并生成的,所以只需要保证edits文件内容的一致性。这个就是需要保证多个NameNode中edits文件内容的事务性同步。这块的工作是由JournalNodes集群进行同步的。

动态数据是指block和DataNode节点的信息,当DataNode启动的时候,上报数据信息的时候需要向每个NameNode都上报一份。
这样就可以保证多个NameNode的元数据信息都一样了,当一个NameNode down掉以后,立刻从Standby NN中选择一个进行接管,没有影响,因为每个NameNode 的元数据时刻都是同步的。

注意:使用HA的时候,不能启动SecondaryNameNode,会出错。
之前是SecondaryNameNode负责合并edits到fsimage文件 那么现在这个工作被standby NN负责了。

NameNode 切换可以自动切换,也可以手工切换,如果想要实现自动切换,需要使用到zookeeper集群。

使用zookeeper集群自动切换的原理:
当多个NameNode 启动的时候会向zookeeper中注册一个临时节点,当NameNode挂掉的时候,这个临时节点也就消失了,这属于zookeeper的特性,这个时候,zookeeper就会有一个watcher监视器监视到,就知道这个节点down掉了,然后会选择一个节点转为Active,把down掉的节点转为Standby。

HDFS的高扩展(Federation)

HDFS Federation可以解决单一命名空间存在的问题,使用多个NameNode,每个NameNode负责一个命令空间。
这种设计可提供以下特性:

  1. HDFS集群扩展性。多个NameNode分管一部分目录,使得一个集群可以扩展到更多节点,不再因内存的限制制约文件存储数目。
  2. 性能更高效。多个NameNode管理不同的数据,且同时对外提供服务,将为用户提供更高的读写吞吐率。
  3. 良好的隔离性。用户可根据需要将不同业务数据交由不同NameNode管理,这样不同业务之间影响很小。

如果真用到了Federation,一般也会和HA结合起来使用。
在这里插入图片描述
这里面用到了4个NameNode和6个DataNode:

  • NN-1、NN-2、NN-3、NN-4
  • DN-1、DN-2、DN-3、DN-4、DN-5、DN-6

其中NN-1、和NN-3配置了HA,提供了一个命令空间,/share,其实可理解为一个顶级目录,NN-2和NN-4配置了HA,提供了一个命名空间/user。

在存储数据时,就可以根据数据的业务类型来区分是存储到share目录下还是user目录下,此时HDFS的存储能力就是/share和/user两个命名空间的总和了。

  • 15
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

偷偷学习被我发现

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值