5.HDFS角色分析
5.1 NameNode
5.1.1 NameNode分析
- 文件和目录的元数据:(运行时,元数据放内存中——为了读取(操作)更快)
- 文件和block副本个数
- 修改和访问时间
- 访问权限
- block大小以及组成文件的block信息列表
- 以两种方式在NameNode本地进行持久化:命名空间镜像文件(fsimage)(持久化数据在此)和编辑日志(edits log)(上一次持久化到下一次持久化之间的数据保存在此 )
- fsimage文件不记录每个block所在的DataNode信息,这些信息在每次系统启动的时候从DataNode重建。之后DataNode会周期性的通过心跳包向NameNode报告block信息。DataNode向NameNode注册的时候NameNode请求DataNode发送block列表信息
1、文件名称和路径
2、文件的大小
3、文件的所属关系
4、文件的block块大小 128MB
5、文件的副本个数 3 MR 10个副本
6、文件的修改时间
7、文件的访问时间
8、文件的权限
9、文件的block列表
- 存储结构
一个运行的NameNode如下的目录结构,该目录结构在第一次格式化的时候创建
如果属性dfs.namenode.name.dir指定了多个路径,则每个路径中的内容是一样的,尤其是当其中一个是挂载的NFS的时候,这种机制为管理提供了一些弹性。(简单来说dfs.namenode.name.dir就是防止宕机之后数据无法恢复问题)
备份数据in_use.lock文件用于NameNode锁定存储目录。这样就防止其他同时运行的NameNode实例使用相同的存储目录。
[root@node1 name]# pwd
/var/itbaizhan/hadoop/full/dfs/name
[root@node1 name]# ll
总用量 8
drwxr-xr-x 2 root root 4096 10月 9 15:49 current
-rw-r--r-- 1 root root 10 10月 9 11:48 in_use.lock
[root@node1 name]# cat in_use.lock
7939@node1
[root@node1 name]# jps
7939 NameNode
22536 Jps
edits表示edits log日志文件
fsimage表示文件系统元数据镜像文件
NameNode在checkpoint之前首先要切换新的edits log文件,在切换时更新seen_txid的值。上次合并fsimage和editslog之后的第一个操作编号。
[root@node1 current]# ll
总用量 3124
-rw-r--r-- 1 root root 42 10月 9 15:49 edits_0000000000000000050-0000000000000000051
-rw-r--r-- 1 root root 1048576 10月 9 15:49 edits_inprogress_0000000000000000052
-rw-r--r-- 1 root root 722 10月 9 14:49 fsimage_0000000000000000049
-rw-r--r-- 1 root root 62 10月 9 14:49 fsimage_0000000000000000049.md5
-rw-r--r-- 1 root root 722 10月 9 15:49 fsimage_0000000000000000051
-rw-r--r-- 1 root root 62 10月 9 15:49 fsimage_0000000000000000051.md5
-rw-r--r-- 1 root root 3 10月 9 15:49 seen_txid
-rw-r--r-- 1 root root 219 10月 9 10:42 VERSION
[root@node1 current]# cat seen_txid
52
- VERSION文件
[root@node1 current]# cat VERSION
#Sat Oct 09 10:42:49 CST 2021
namespaceID=1536048782
clusterID=CID-7ecb999c-ef5a-4396-bdc7-c9a741a797c4
cTime=1633747369798
storageType=NAME_NODE
blockpoolID=BP-1438277808-192.168.20.101-1633747369798
layoutVersion=-64
namespaceID是该文件系统的唯一标志符,当NameNode第一次格式化的时候生成。
clusterID是HDFS集群使用的一个唯一标志符,在HDFS联邦的情况下,就看出它的作用了,因为联邦情况下,集群有多个命名空间,不同的命名空间由不同的NameNode管理。
cTime标记着当前NameNode创建的时间。对于刚格式化的存储,该值永远是0,但是当文件系统更新的时候,这个值就会更新为一个时间戳。
storageType表示当前目录存储NameNode内容。
blockpoolID是block池的唯一标志符,一个NameNode管理一个命名空间,该命名空间中的所有文件存储的block都在block池中。
layoutVersion是一个负数,定义了HDFS持久化数据结构的版本。这个版本数字跟hadoop发行的版本无关。当layout改变的时候,该数字减1(比如从–63到-64)。当对HDFS进行了升级,就会发生改变。
5.1.2 NameNode_FsImage和Edits log文件分析
查看oiv和oev命令
[root@node1 ~]# hdfs|grep o.v
oev apply the offline edits viewer to an edits file
oiv apply the offline fsimage viewer to an fsimage
- oiv查看Fsimage文件
(1)查看oiv命令
[root@node1 ~]# hdfs oiv --help
Usage: bin/hdfs oiv [OPTIONS] -i INPUTFILE -o OUTPUTFILE
Offline Image Viewer
View a Hadoop fsimage INPUTFILE using the specified PROCESSOR,
saving the results in OUTPUTFILE.
-i,--inputFile <arg> FSImage or XML file to process.
Optional command line arguments:
-o,--outputFile <arg> Name of output file. If the specified
file exists, it will be overwritten.
(output to stdout by default)
If the input file was an XML file, we
will also create an <outputFile>.md5 file.
-p,--processor <arg> Select which type of processor to apply
against image file. (XML|FileDistribution|
ReverseXML|Web|Delimited)
The default is Web.
(2)基本语法
hdfs oiv -p 文件类型 -i 镜像文件 -o 转换后文件输出的全路径名
(3)案例实操
[root@node1 current]# pwd
/var/itbaizhan/hadoop/full/dfs/name/current
[root@node1 current]# ll|grep fsimage
-rw-r--r-- 1 root root 722 10月 9 13:49 fsimage_0000000000000000047
-rw-r--r-- 1 root root 62 10月 9 13:49 fsimage_0000000000000000047.md5
-rw-r--r-- 1 root root 722 10月 9 14:49 fsimage_0000000000000000049
-rw-r--r-- 1 root root 62 10月 9 14:49 fsimage_0000000000000000049.md5
[root@node1 current]# hdfs oiv -p XML -i fsimage_0000000000000000049 -o /opt/hadoop-3.1.3/fsimage49.xml
2021-10-09 15:20:24,428 INFO offlineImageViewer.FSImageHandler: Loading 3 strings
[root@node1 current]# vim /opt/hadoop-3.1.3/fsimage49.xml
#格式化该xml文件:Ctrl+v-> !xmllint -format - -> 删除生成的<xml ..> ->保存并退出
[root@node1 current]# cat /opt/hadoop-3.1.3/fsimage49.xml
部分显示结果如下:
<?xml version="1.0"?>
<fsimage>
<INodeSection>
<lastInodeId>16392</lastInodeId>
<numInodes>5</numInodes>
<inode>
<id>16385</id>
<type>DIRECTORY</type>
<name/>
<mtime>1633749749273</mtime>
<permission>root:supergroup:0755</permission>
<nsquota>9223372036854775807</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16386</id>
<type>DIRECTORY</type>
<name>user</name>
<mtime>1633748876034</mtime>
<permission>root:supergroup:0755</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16387</id>
<type>DIRECTORY</type>
<name>root</name>
<mtime>1633749176246</mtime>
<permission>root:supergroup:0755</permission>
<nsquota>-1</nsquota>
<dsquota>-1</dsquota>
</inode>
<inode>
<id>16388</id>
<type>FILE</type>
<name>hadoop-3.1.3.tar.gz</name>
<replication>2</replication>
<mtime>1633749066652</mtime>
<atime>1633749010986</atime>
<preferredBlockSize>134217728</preferredBlockSize>
<permission>root:supergroup:0644</permission>
<blocks>
<block>
<id>1073741825</id>
<genstamp>1001</genstamp>
<numBytes>134217728</numBytes>
</block>
<block>
<id>1073741826</id>
<genstamp>1002</genstamp>
<numBytes>134217728</numBytes>
</block>
<block>
<id>1073741827</id>
<genstamp>1003</genstamp>
<numBytes>69640404</numBytes>
</block>
</blocks>
<storagePolicyId>0</storagePolicyId>
</inode>
<inode>
<id>16389</id>
<type>FILE</type>
<name>test.txt</name>
<replication>2</replication>
<mtime>1633749176236</mtime>
<atime>1633749175593</atime>
<preferredBlockSize>134217728</preferredBlockSize>
<permission>root:supergroup:0644</permission>
<blocks>
<block>
<id>1073741828</id>
<genstamp>1004</genstamp>
<numBytes>38</numBytes>
</block>
</blocks>
<storagePolicyId>0</storagePolicyId>
</inode>
</INodeSection>
......
</fsimage>
**思考:**观察发现Fsimage中没有记录块所对应DataNode,为什么?
在集群启动后,要求DataNode上报数据块信息,并间隔一段时间后再次上报。
- oev查看Edits log文件
(1)查看oiv命令
[root@node1 current]# hdfs oev --help
Usage: bin/hdfs oev [OPTIONS] -i INPUT_FILE -o OUTPUT_FILE
Offline edits viewer
Parse a Hadoop edits log file INPUT_FILE and save results
in OUTPUT_FILE.
Required command line arguments:
-i,--inputFile <arg> edits file to process, xml (case
insensitive) extension means XML format,
any other filename means binary format.
XML/Binary format input file is not allowed
to be processed by the same type processor.
-o,--outputFile <arg> Name of output file. If the specified
file exists, it will be overwritten,
format of the file is determined
by -p option
Optional command line arguments:
-p,--processor <arg> Select which type of processor to apply
against image file, currently supported
processors are: binary (native binary format
that Hadoop uses), xml (default, XML
format), stats (prints statistics about
edits file)
显示结果如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EDITS>
<EDITS_VERSION>-64</EDITS_VERSION>
<RECORD>
<OPCODE>OP_START_LOG_SEGMENT</OPCODE>
<DATA>
<TXID>1</TXID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_MKDIR</OPCODE>
<DATA>
<TXID>2</TXID>
<LENGTH>0</LENGTH>
<INODEID>16386</INODEID>
<PATH>/user</PATH>
<TIMESTAMP>1633748876031</TIMESTAMP>
<PERMISSION_STATUS>
<USERNAME>root</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>493</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_MKDIR</OPCODE>
<DATA>
<TXID>3</TXID>
<LENGTH>0</LENGTH>
<INODEID>16387</INODEID>
<PATH>/user/root</PATH>
<TIMESTAMP>1633748876034</TIMESTAMP>
<PERMISSION_STATUS>
<USERNAME>root</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>493</MODE>
</PERMISSION_STATUS>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD</OPCODE>
<DATA>
<TXID>4</TXID>
<LENGTH>0</LENGTH>
<INODEID>16388</INODEID>
<PATH>/user/root/hadoop-3.1.3.tar.gz._COPYING_</PATH>
<REPLICATION>2</REPLICATION>
<MTIME>1633749010986</MTIME>
<ATIME>1633749010986</ATIME>
<BLOCKSIZE>134217728</BLOCKSIZE>
<CLIENT_NAME>DFSClient_NONMAPREDUCE_1752542758_1</CLIENT_NAME>
<CLIENT_MACHINE>192.168.20.101</CLIENT_MACHINE>
<OVERWRITE>true</OVERWRITE>
<PERMISSION_STATUS>
<USERNAME>root</USERNAME>
<GROUPNAME>supergroup</GROUPNAME>
<MODE>420</MODE>
</PERMISSION_STATUS>
<ERASURE_CODING_POLICY_ID>0</ERASURE_CODING_POLICY_ID>
<RPC_CLIENTID>d021df05-6937-4fc7-9474-ffcbf27f0f14</RPC_CLIENTID>
<RPC_CALLID>3</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
<DATA>
<TXID>5</TXID>
<BLOCK_ID>1073741825</BLOCK_ID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
<DATA>
<TXID>6</TXID>
<GENSTAMPV2>1001</GENSTAMPV2>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_ADD_BLOCK</OPCODE>
<DATA>
<TXID>7</TXID>
<PATH>/user/root/hadoop-3.1.3.tar.gz._COPYING_</PATH>
<BLOCK>
<BLOCK_ID>1073741825</BLOCK_ID>
<NUM_BYTES>0</NUM_BYTES>
<GENSTAMP>1001</GENSTAMP>
</BLOCK>
<RPC_CLIENTID/>
<RPC_CALLID>-2</RPC_CALLID>
</DATA>
</RECORD>
<RECORD>
<OPCODE>OP_END_LOG_SEGMENT</OPCODE>
<DATA>
<TXID>8</TXID>
</DATA>
</RECORD>
</EDITS>
当文件系统客户端进行了写操作(例如创建或移动了文件),这个事务首先在edits log中记录下来。NameNode在内存中有文件系统的元数据,当edits log记录结束后,就更新内存中的元数据。内存中的元数据用于响应客户端的读请求。
edits log在磁盘上表现为一定数量的文件。每个文件称为片段(Segment),前缀“edits”,后缀是其中包含的事务ID(transaction IDs)。每个写操作事务都仅仅打开一个文件(比如edits_inprogress_00000000000010),写完后冲刷缓冲区并同步到磁盘,然后返回客户端success状态码。如果NameNode的元数据需要写到多个目录中,则对于每个写事务需要所有的写操作都完成,并冲刷缓冲区同步到磁盘才返回success状态码。这样就可以保证在发生宕机的时候没有事务数据丢失。
用户的操作是一个事务,每个操作NN都要先将操作记录到edits log中,如果给NN指定了多个目录,则在多个目录中都存在edits log文件,用户的操作要在多个目录中都写完成,才让NN同步数据到内存中。当NN在内存中也同步了数据,就返回客户端success。
每个fsimage文件都是系统元数据的一个完整的持久化检查点(checkpoint)(后缀表示镜像中的最后一个事务)。写操作不更新这个数据,因为镜像文件通常为GB数量级,写到磁盘很慢。如果NameNode宕机,可以将最新fsimage加载到内存,同时执行edits log对应于该fsimage之后的操作,就可以重建元数据的状态。而这正是每次启动NameNode的时候NameNode要做的工作。
5.2 SecondaryNameNode
存在的意义
edits log会随着对文件系统的操作而无限制地增长,这对正在运行的NameNode而言没有任何影响,如果NameNode重启,则需要很长的时间执行edits log的记录以更新fsimage(元数据镜像文件)。在此期间,整个系统不可用。定期进行Fsimage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低。因此,引入一个新的节点SecondaryNamenode,专门用于FsImage和Edits log的合并。
SecondaryNameNode要和NameNode拥有相同的内存。对大的集群,SecondaryNameNode运行于一台专用的物理主机。
存储结构
[root@node1 name]# pwd
/var/itbaizhan/hadoop/full/dfs/name
|-current
| |-edits_0000000000000000001-0000000000000000008
| |-edits_0000000000000000009-0000000000000000038
| |-edits_0000000000000000039-0000000000000000040
| |-edits_0000000000000000041-0000000000000000041
| |-edits_0000000000000000042-0000000000000000043
| |-edits_0000000000000000044-0000000000000000045
| |-edits_0000000000000000046-0000000000000000047
| |-edits_0000000000000000048-0000000000000000049
| |-edits_0000000000000000050-0000000000000000051
| |-edits_0000000000000000052-0000000000000000053
| |-edits_0000000000000000054-0000000000000000054
| |-edits_0000000000000000055-0000000000000000056
| |-fsimage_0000000000000000054
| |-fsimage_0000000000000000054.md5
| |-fsimage_0000000000000000056
| |-fsimage_0000000000000000056.md5
| |-edits_inprogress_0000000000000000057
| |-seen_txid #57
| |-VERSION
|-in_use.lock
[root@node2 namesecondary]# pwd
/var/itbaizhan/hadoop/full/dfs/namesecondary
|-current
| |-edits_0000000000000000001-0000000000000000008
| |-edits_0000000000000000009-0000000000000000038
| |-edits_0000000000000000039-0000000000000000040
| |-edits_0000000000000000041-0000000000000000041
| |-edits_0000000000000000042-0000000000000000043
| |-edits_0000000000000000044-0000000000000000045
| |-edits_0000000000000000046-0000000000000000047
| |-edits_0000000000000000048-0000000000000000049
| |-edits_0000000000000000050-0000000000000000051
| |-edits_0000000000000000052-0000000000000000053
| |-edits_0000000000000000055-0000000000000000056
| |-fsimage_0000000000000000054
| |-fsimage_0000000000000000054.md5
| |-fsimage_0000000000000000056
| |-fsimage_0000000000000000056.md5
| |-VERSION
|-in_use.lock
-
SecondaryNameNode中checkpoint目录布局(dfs.namenode.checkpoint.dir)和NameNode中的基本一样。
-
如果NameNode完全坏掉,可以快速地从SecondaryNameNode恢复。有可能丢数据
-
如果SecondaryNameNode直接接手NameNode的工作,需要在启动NameNode进程的时候添加-importCheckpoint选项。该选项会让NameNode从由dfs.namenode.checkpoint.dir属性定义的路径中加载最新的checkpoint数据,但是为了防止元数据的覆盖,要求dfs.namenode.name.dir定义的目录中没有内容。
工作流程
edits_inprogress_00000000001_0000000019 seen_txid=20 -
secondarynamenode请求namenode生成新的edits log文件(edits_inprogress_…)并向其中写日志。NameNode会在所有的存储目录中更新seen_txid文件
-
SecondaryNameNode通过HTTP GET的方式从NameNode下载fsimage和edits文件到本地。
-
SecondaryNameNode将fsimage加载到自己的内存,并根据edits log更新内存中的fsimage信息,然后将更新完毕之后的fsimage写到磁盘上。
-
SecondaryNameNode通过HTTP PUT将新的fsimage文件发送到NameNode,NameNode将该文件保存为.ckpt的临时文件备用。
-
NameNode重命名该临时文件并准备使用。此时NameNode拥有一个新的fsimage文件和一个新的很小的edits log文件(可能不是空的,因为在SecondaryNameNode合并期间可能对元数据进行了读写操作)。管理员也可以将NameNode置于safemode,通过hdfs dfsadmin -saveNamespace命令来进行edits log和fsimage的合并。
检查点创建时机:对于创建检查点(checkpoint)的过程,有三个参数进行配置:
<!-- 默认情况下,SecondaryNameNode每个小时进行一次checkpoint合并 -->
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>3600s</value>
</property>
<!-- 一分钟检查一次操作次数,当操作次数达到1百万时,SecondaryNameNode执行一次 -->
<property>
<name>dfs.namenode.checkpoint.txns</name>
<value>1000000</value>
<description>操作动作次数</description>
</property>
<property>
<name>dfs.namenode.checkpoint.check.period</name>
<value>60s</value>
<description> 1分钟检查一次操作次数</description>
</property >
合并条件总结: 1、每小时一次,2、不足一小时,则只要edits log中记录的事务数达到了1000000,则合并。
hdfs-default.xml,如果想修改这几个参数的话,直接在hdfs-site.xml中进行配置即可。
5.3 NameNode故障处理(扩展)
NameNode故障后,可以采用如下两种方法恢复数据。
-
将SecondaryNameNode中数据拷贝到NameNode存储数据的目录;
kill -9 NameNode进程id(可以通过jps查看nodename进程的id)
删除NameNode存储的数据
[root@node1 hadoop-3.1.3]# rm -rf /var/itbaizhan/hadoop/full/dfs/name/*
拷贝SecondaryNameNode中数据到原NameNode存储数据目录
[root@node1 dfs]# scp -r root@node2:/var/itbaizhan/hadoop/full/dfs/namesecondary/* ./name/
重新启动NameNode
[root@node1 hadoop-3.1.3]# hdfs --daemon start namenode
- 使用-importCheckpoint选项启动NameNode守护进程,从而将SecondaryNameNode中数据拷贝到NameNode目录中。
修改hdfs-site.xml中的
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>120</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/var/itbaizhan/hadoop/full/dfs/name</value>
</property>
kill -9 NameNode进程id
删除NameNode存储的数据(/var/itbaizhan/hadoop/full/dfs/name)
[root@node1 ~]# rm -rf /var/itbaizhan/hadoop/full/dfs/name/*
如果SecondaryNameNode不和NameNode在一个主机节点上,需要将SecondaryNameNode存储数据的目录拷贝到NameNode存储数据的平级目录,并删除in_use.lock文件
[root@node1 dfs]# scp -r root@node2:/var/itbaizhan/hadoop/full/dfs/namesecondary ./
[root@node1 namesecondary]# rm -rf in_use.lock
[root@node1 dfs]# pwd
/var/itbaizhan/hadoop/full/dfs
[root@node1 dfs]# ls
data name namesecondary
导入检查点数据(等待一会ctrl+c结束掉)
[`root@node1 dfs]# hdfs namenode -importCheckpoint
启动NameNode
[root@node1 dfs]# hdfs --daemon start namenode
5.4 NameNode多目录配置(了解)
- NameNode的本地目录可以配置成多个,且每个目录存放内容相同,增加了可靠性
- 具体配置如下:
(1)停止集群,在四台节点的hdfs-site.xml文件中添加如下内容
<property>
<name>dfs.namenode.name.dir</name>
<value>file://${hadoop.tmp.dir}/dfs/name1,file://${hadoop.tmp.dir}/dfs/name2</value>
</property>
(2)删除四台节点的/var/itbaizhan/hadoop/full和/opt/hadoop-3.1.3/logs中所有数据。
[root@node1 ~]# rm -rf /var/itbaizhan/hadoop/full/ /opt/hadoop-3.1.3/logs/
[root@node2 ~]# rm -rf /var/itbaizhan/hadoop/full/ /opt/hadoop-3.1.3/logs/
[root@node3 ~]# rm -rf /var/itbaizhan/hadoop/full/ /opt/hadoop-3.1.3/logs/
[root@node4 ~]# rm -rf /var/itbaizhan/hadoop/full/ /opt/hadoop-3.1.3/logs/
(3)格式化集群并启动。
[root@node1 ~]# hdfs namenode –format
[root@node1 ~]# start-dfs.sh
(4)查看结果
[root@node1 ~]# cd /var/itbaizhan/hadoop/full/dfs
[root@node1 dfs]# ll
总用量 12
drwxrwxr-x. 3 root root 4096 10月 10 16:34 name1
drwxrwxr-x. 3 root root 4096 10月 10 16:34 name2
5.5 DataNode分析
5.5.1 工作机制
- 一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。
- DataNode启动后向NameNode注册,通过后,周期性(1小时)的向NameNode上报所有的块信息。
- 心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用。
- 集群运行中可以安全加入和退出一些机器。
5.5.2 存储结构
DataNode不需要显式地格式化;关键文件和目录结构如下
- HDFS块数据存储于blk_前缀的文件中,包含了被存储文件原始字节数据的一部分。
- 每个block文件都有一个.meta后缀的元数据文件关联。该文件包含了一个版本和类型信息的头部,后接该block中每个部分的校验和。
- 每个block属于一个block池,每个block池有自己的存储目录,该目录名称就是该池子的ID(跟NameNode的VERSION文件中记录的block池ID一样)。
当一个目录中的block达到64个(通过dfs.datanode.numblocks配置)的时候,DataNode会创建一个新
的子目录来存放新的block和它们的元数据。这样即使当系统中有大量的block的时候,目录树也不会太深。同时也保证了在每个目录中文件的数量是可管理的,避免了多数操作系统都会碰到的单个目录中的文件个数限制(几十几百上千个)。
如果dfs.datanode.data.dir指定了位于在不同的硬盘驱动器上的多个不同的目录,则会通过轮询的方式向目录中写block数据。需要注意的是block的副本不会在同一个DataNode上复制,而是在不同的DataNode节点之间复制。
5.5.3 存储数据模型(重点)
- 文件线性切割成块(Block)(按字节切割)
[root@node1 ~]# for i in `seq 100000`; do echo "hello gtjin $i" >> hello.txt; done
[root@node1 ~]# cat hello.txt
hello gtjin1
.....
hello gtjin100
......
-
Block分散存储在集群节点中
-
单一文件Block大小一致,文件与文件可以不一致
hdfs dfs -D dfs.blocksize=1048576 -D dfs.replication=2 -put hello.txt /
- Block可以设置副本数,副本分散在不同节点中
a) 副本数不要超过DataNode节点数量
b) 承担计算
c) 容错
- 文件上传可以设置Block大小和副本数
- 已上传的文件Block副本数可以调整,大小不变
- 支持一次写入多次读取;对同一个文件,一个时刻只有一个写入者
- 可以append追加数据
5.5.4 优势(了解)
- 一个文件的大小可以大于网络中任意一个节点的磁盘容量
- 使用抽象块而非整个文件作为存储单元,大大简化存储子系统的设计
- 块非常适合用于数据备份进而提供数据容错能力和提高可用性
5.6 权限(了解)
5.7 虚拟机时间不同步问题
4台虚拟机都需要操作
[root@node0 ~]# vim /etc/ntp.conf
# 添加代码
server ntp1.aliyun.com
server ntp2.aliyun.com
server ntp3.aliyun.com
systemctl restart ntpd