深入理解 HDFS(二):Replica
对于我们上传的文件,HDFS 会复制多份,主要是为了降低数据丢失的风险,复制文件背后是复制 block,block 最终会存储在 datanode 中,那么在该过程中 namenode 参考了哪些因素选择的 datanode?内部处理流程又是如何?一起来分析。
1. 复制粒度
对于原始的 block 和复制的 block,统一叫做 replica,下面是和复制相关的一些细粒度参数:
dfs.blocksize: replica 的大小,默认 128m;
dfs.replication: 副本数量,默认 3,生成 replica 的过程是串行的,同一时刻只能有一个 writer;
dfs.replication.max:副本最大数量,默认 512,主要用于对 dfs.replication 的校验;
dfs.namenode.replication.min:副本最小数量,默认 1,主要用于 replica 生成后数量的校验。
2. 参考因素
从类别上可分为:客户端因素和服务端因素。
客户端因素:
CreateFlag.NO_LOCAL_WRITE:防止写入和客户端相同 IP 的 datanode,假设客户端和 datanode 在同一个主机上,客户端上传文件,默认策略下 datanode 都会存储 1 个副本,这样一来数据肯定不均衡,所以通过设置 NO_LOCAL_WRITE 可有效避免;
CreateFlag.NO_LOCAL_RACK:防止写入和客户端相同机架的 datanode,和 NO_LOCAL_WRITE 类似,只不过 datanode 换做成同机架下的所有 datanode 实例。
favoredNodes:如何服务端开启了 dfs.namenode.block-placement-policy.default.prefer-local-node 的设置,客户端上传文件时,通过 DistributedFileSystem.createFile -> HdfsDataOutputStreamBuilder.favoredNodes 进行设置,namenode 会根据上传的 favoredNodes 优先选择。
服务端因素:
dfs.block.replicator.classname:replication 分配策略,直接影响到 replication 分配到哪个 datanode 中,默认分配策略 BlockPlacementPolicyDefault,除此之外还有 BlockPlacementPolicyRackFaultTolerant 和 BlockPlacementPolicyWithNodeGroup 比较常用这里会重点讲解,其余的分配策略还有 AvailableSpaceBlockPlacementPolicy、AvailableSpaceRackFaultTolerantBlockPlacementPolicy 和 BlockPlacementPolicyWithUpgradeDomain,细节方面大家可查看下官方文档,后续我会酌情补充。
dfs.replication: 副本数量,默认 3,会决定选择 datanode 数量;
dfs.namenode.avoid.write.stale.datanode:不允许写入处于 stale 状态的 datanode,默认 false;
dfs.namenode.write.stale.datanode.ratio: 按照 stale 和 live 状态分别统计 datanode 数量,如果二者比值小于等于这个参数,即使设置了
dfs.namenode.avoid.write.stale.datanode = true
,也会选择处于 stale 状态下的 datanode。
3. Replica 分配策略
假设搭建了下面的集群,集群的副本数为 3:
3.1 BlockPlacementPolicyDefault:默认策略
3.1.1 未配置机架感知
所有 datanode 会默认分配到 /default-rack
虚拟机架中,屏蔽某些次要参数,该策略主要处理流程:
校验客户端所在节点是否有 datanode 实例:
如果有:选择该 datanode;
如果没有:从可用的 datanode 列表中随机选择 1 个。
对于每次选择的 datanode 都需要在可用列表中删除;
依次从可用列表中选择第 2 个、第 3 个。
3.1.2 机架感知
如果想开启 HDFS 机架感知,你需要做几件事:
编写脚本:主要目的是为了查询 datanode 所在机架。脚本只有 1 个输入参数主机 ip 或主机名,所以你需要根据主机 ip 或主机名输出匹配的机架信息,可参考下面的脚本进行配置:
在 core-site.xml 中配置
net.topology.script.file.name
的值为脚本的完整路径名;
重启集群后,输出集群拓补结构:
hdfs dfsadmin -printTopology
从结果可以看出 HDFS 已经开启了机架感知,那接着分析处理流程:
校验客户端所在节点是否有 datanode 实例:
如果有:选择该 datanode;
如果没有:从可用的 datanode 列表中随机选择 1 个。
从第 1 个 datanode 所在机架外的其他机架,随机选择 1 个 datanode 作为第 2 个;
在第 2 个 datanode 所在机架随机选择 1 个作为第 3 个。
3.2 BlockPlacementPolicyRackFaultTolerant:贪婪策略
该策略的主要目是尽可能的在不同的机架上选择 datanode,主要处理流程:
通过调用 getMaxNodesPerRack 计算平均每个机架可选择的最大 datanode 数量;
根据计算的 maxNodesPerRack 调用 chooseTargetInOrder 一次性选择和副本数相同数量的 datanode;
为了保证选择的 datanode 和副本数相等,内部又做了很多保证机制。
如果决定使用贪婪策略,你需要编写脚本,开启机架感知功能,同时在 hdfs-site.xml 中需要设置属性:
3.3 BlockPlacementPolicyWithNodeGroup:分组策略
1 个 42U 19 英寸的机柜,除了预留散热和交,换机位置,可以轻松部署 16 台 1U 服务器。在同一个机架内,如果你想更细粒度的对 datanode 进行分组选择,可以试试分组策略。
分组策略内部处理流程:
校验客户端所在节点是否有 datanode 实例:
如果有:选择该 datanode;
如果没有:从可用的 datanode 列表中随机选择 1 个。
从第 1 个 datanode 所在机架外的其他机架,随机选择 1 个 datanode 作为第 2 个;
在第 2 个 datanode 所在机架不同的 node-group 中选择 1 个 作为第 3 个。
使用分组策略你需要进行如下操作:
开启机架感知:
在 core-site.xml 中设置:
在 hdfs-site.xml 中设置:
4. 快速搭建 HDFS
4.1 主机列表
4.2 跳转主机环境准备
我通常会选择 namenode 作为跳转主机,下面使用 root 用户操作:
4.3 安装 JDK
在跳转机上使用 root 用户操作。
4.4 安装 HDFS
在跳转机上使用 5CC99CC1 用户操作。
4.5 启动 HDFS
在跳转机上使用 5CC99CC1 用户操作。
4.6 模拟上传测试
使用 root 用户安装 fio
脚本功能:生成指定大小文件上传到 HDFS,之后查看该文件的 block 分配情况。
有问题欢迎大家留言,我们一起讨论。
版权声明: 本文为 InfoQ 作者【冰心的小屋】的原创文章。
原文链接:【http://xie.infoq.cn/article/3e50ba89537572ec0730df606】。文章转载请联系作者。
评论