在了解了 NameNode、SecondaryNameNode 的工作机制、FsImage 与 Edits 数据备份、NameNode 安全机制与多目录后,对 NameNode 有了一些基础了解。在此基础之上,接下来了解一下 DataNode 的工作机制。
DataNode 工作机制
DataNode 中存储的每个数据块,以文件形式存储在磁盘上。包括 2 个文件:数据本身、元数据(包括数据块的长度、校验和、时间戳)
- DataNode 启动后,向 NameNode 注册
- NameNode 注册成功后,会同步在 NameNode 元数据中
- DataNode 每个一个
固定的周期
向 NameNode 再注册(默认1小时) - DataNode 与 NameNode 以
3 秒一次
的心跳机制判断是否断开。心跳返回结果带有 NameNode 给 DataNode 的命令 - NameNode 超过
10 分钟
没有收到心跳,则认为该节点不可用
DataNode 数据完整性
- 当 DataNode 读取 Block 时,它会计算 CheckSum(校验和)
- 如果计算后的 CheckSum 与 Block 创建时的值不一样,说明 Block 已经损坏
- Client 读取其他 DataNode 上的 Block
- DataNode 在其文件创建后,周期性的验证 CheckSum
掉线时限
DataNode 进程死亡或者网路故障,造成 DataNode 与 NameNode 无法通信,NameNode 不会立即把该节点判定为 死亡
,要经过一段时间后才会判定为死亡,这段时间称为 超时时长
。HDFS 默认的超时时长为 10min + 30s
超时时长计算公示: 2 * dfs.namenode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval
具体可参考 官方文档,默认值为: dfs.namenode.heartbeat.recheck-interval
5 分钟(300000)、dfs.heartbeat.interval
3秒(3s)
如果需要修改掉线时限,可以修改 hdfs-site.xml
文件。
服役新数据节点
现在已经有 3 台服务器构成了一个 hadoop 集群,如果现在需要在此基础上,再增加一个新的数据节点,就称为 新数据节点服役
。
环境准备
- 以 hadoop04 为主,克隆一台 hadoop05
- 修改 hadoop05 的 ip、主机名称
- 删除原来 HDFS 中的
data/
和log/
- 应用
/etc/profile
配置文件
服役新节点
- 启动原始集群 02、03、04
- 删除 05 的
data/
和log/
- 启动 05 的 DataNode(
sbin/hadoop-daemon.sh start datanode
) - 启动 05 的 NodeManager(
sbin/yarn-daemon.sh start nodemanager
) - 在 05 上上传文件进行测试
- 查看 WebUI 的 datanodes
退役旧数据节点
主机白名单
添加到白名单里的主机节点,都允许访问 NameNode,否则不允许访问。
配置步骤:
在 NameNode 的
%HADOOP_HOME%/etc/hadoop
目录下创建dfs.hosts
文件,添加白名单(此次不添加 05)
1
2
3
4 # dfs.hosts
hadoop02
hadoop03
hadoop04
在 NameNode 的
hdfs-site.xml
文件中增加 dfs.hosts 配置
1 | <!-- 配置白名单 --> |
分发到 03、04,并刷新 NameNode
1 | [root@hadoop02 hadoop]# xsync hdfs-site.xml |
更新 ResourceManager
1 | [root@hadoop03 ~]# yarn rmadmin -refreshNodes |
查看 WebUI
在执行上述操作的时候,02、03、04、05 都未关闭,也就是说,在执行上述操作之前,在 WebUI 的 DataNodes 中是可以看到 02、03、04、05 四台机器的。
在执行完上述操作后,再次查看 WebUI
如果数据不均衡,可以使用命令来实现集群的再平衡
1 | [root@hadoop02 hadoop-2.7.2]# sbin/start-balancer.sh |
此时再查看 README.TXT
文件的块信息,由 05 变更到 02 上了。
黑名单退役
在黑名单上的主机会被强制退出。
在测试实现这种情况之前,需要将现场恢复,即将 hdfs-site.xml 中添加的白名单配置先注释掉,并刷新 NameNode 和 ResourceManager,启动 05 上的 DataNode
在 NameNode 的 %HADOOP_HOME%/etc/hadoop
目录下,创建 dfs.hosts.exclude
文件,并添加 05
修改 NameNode 上的 hdfs-site.xml
文件,增加 dfs.hosts.exclude
配置
1 | <!-- 黑名单 --> |
刷新 NameNode、ResourceManager
1 | [root@hadoop02 hadoop]# hdfs dfsadmin -refreshNodes |
查看 WebUI,提示正在退役中(Decommission In Progress),此时正在退役的节点会将数据块复制到其他节点上,保证数据的完整性。
稍等一会后再刷新页面,提示 05 节点已退役完成:Decommissioned。
如果数据不平衡,可以和白名单一样,使用 balance 命令平衡数据。
需要注意的点:
- 等待退役节点状态为
Decommissioned
,此时所有的块都已经复制完成,停止该节点及节点资源管理器。注意:如果副本数是 3,服役的节点小于等于 3,是不能退役的!需要修改副本数后才能退役! - 不允许白名单和黑名单中存在同一个主机
DataNode 多目录
修改配置与 NameNode 多目录差不多,也是修改 hdfs-site.xml
,增加如下配置
1 | <property> |
分发到不同主机上后,重启 hadoop 集群即可。
注意:
DataNode 与 NameNode 不同,DataNode 每个目录中存放的数据不一样
。数据不是副本!
小文件存档
小文件存档的弊端
鉴于每个文件在 DataNode 中分块存储,每个块的元数据村存在 NameNode 中,因此 HDFS 存储小文件会非常低效。因为大量的小文件会耗尽 NameNode 中的大部分内存。
但是,需要注意的是,存储小文件所需要的磁盘容量和数据块的大小无关。
如:一个 1MB 的文件,设置为 128M 的块存储,实际使用的磁盘空间是 1MB,而不是 128MB。
解决办法之一
HDFS 存档文件或 HAR 文件,是一个更搞笑的文件存档工具,它将文件存在 HDFS 块,在减少 NameNode 内存使用的同时,允许对文件进行透明访问。
具体来说,HDFS 存档文件对内还是一个一个的独立文件,对外(NameNode)而言却是一个整体,减少了 NameNode 的内存。
测试
在 HDFS 中,存放几个测试文件:
文件压缩:
1 | # 参数解释 |
执行完成后,查看 WebUI
可以看到,文件成功输出了,但是我们看不到文件的内容是否和压缩前一致,解决办法:使用 hadoop fs -ls -R har:///output/output.har
命令查看
1 | [root@hadoop02 hadoop-2.7.2]# hadoop fs -ls -R har:///output/outout.har |
文档解压:
1 | [root@hadoop02 hadoop-2.7.2]# hadoop fs -cp har:///output/outout.har /har |
回收站
开启回收站功能,可以将删除的文件,在不超时的情况下,恢复原数据,起到防止误删、备份等作用。
回收站参数设置及工作机制
开启回收站功能参数
fs.trash.interval
:默认值为 0,表示禁用回收站
,其他值表示该文件的存活时间,单位分钟
fs.trash.checkpoint.interval
:默认值为 0,表示检查回收站的时间间隔
,如果为 0,则该值与fs.trash.interval
的时间间隔相同。单位分钟
- 要求:
fs.trash.checkpoint.interval
<=fs.trash.interval
修改 core-site.xml
文件
1 | <property> |
删除一条数据测试
1 | [root@hadoop03 hadoop-2.7.2]# hadoop fs -rm /README.txt |
在 WebUI 中查看回收站
错误原因:进入垃圾回收站的默认用户名为 dr.who
, 需要修改回收站用户名
修改 core-site.xml,并分发的 03、04 上,重启集群
1 | <property> |
再次查看 WebUI:
快照管理
快照,相当于对目录做了一次备份。此操作并 不会立即赋值所有文件 ,而是 指向同一个文件。当写入发生时,才会产生新文件。
常见命令
开启指定目录的快照功能:
hdfs dfsadmin -allowSnapshot <path>
1 | [root@hadoop02 hadoop-2.7.2]# hdfs dfsadmin -allowSnapshot /laiyy |
禁用指定目录的快照功能(默认):
hdfs dfsadmin -disallowSnapshot <path>
对指定目录创建快照:hdfs dfs -createSnapshot <path>
1 | [root@hadoop02 hadoop-2.7.2]# hdfs dfs -createSnapshot /laiyy |
此时在 WebUI 中是看不到快照文件的,因为这个快照文件是隐藏文件
,输入 /laiyy/.snapshot
即可查看
创建目录快照并指定名称:
hdfs dfs -createSnapshot <path> <name>
快照重命名:hdfs dfs -renameSnapshot <path> <oldName> <newName>
1 | [root@hadoop02 hadoop-2.7.2]# hdfs dfs -renameSnapshot /laiyy s20191203-135428.244 laiyy_snapshot |
查看 WebUI,可以看到快照名称已经修改了。
列出当前用户可以快照的目录:
hdfs lsSnapshottableDir
比较两个快照目录的不同:hdfs snapshotDiff <path> <from> <to>
1 | # path 哪个路径的快照 |
在已经创建快照之后,再往 /laiyy 下上传一个文件,比较结果
1 | [root@hadoop02 hadoop-2.7.2]# hdfs snapshotDiff /laiyy . .snapshot/laiyy_snapshot |
再创建一个新的快照,比较两个快照之间的区别
1 | [root@hadoop02 hadoop-2.7.2]# hdfs snapshotDiff /laiyy .snapshot/laiyy_snapshot .snapshot/laiyy_snapshot1 |
删除快照:
hdfs dfs -deleteSnapshot <path> <name>
1 | hdfs dfs -deleteSnapshot /laiyy laiyy_snapshot |
查看 WebUI