【HDFS实战】HADOOP 机架感知能力-HDFS
HADOOP (HDFS) 机架感知能力
文章目录
- HADOOP (HDFS) 机架感知能力
- 为什么需要机架感知能力?
- 怎么开启机架感知能力?
- 配置后启动NameNode
- 输出生效的机架信息
- 网络拓扑
- NetworkTopology
- 官网原文
- Rack Awareness
为什么需要机架感知能力?
HDFS集群的服务器会分布在不同的机架,通过交换机进行网络通信。
同一个机架内的数据节点通信的网络速度高于跨机架的数据节点的通信速度,网络通信的数据受上层交换机的带宽影响。
HDFS块放置策略,默认策略:org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyDefault#chooseTargetInOrder
- 块是3副本(3份数据)
- 副本1:客户端不在集群中时,随机放置在集群的一个数据节点(A)中;客户端在集群中时,会放在客户端所在数据的节点中。
- 副本2:安排在与副本1所在机架内的其他的数据节点(B)上。datanodeA与datanodeB在同一个rack。
- 副本3:与副本1,副本2不同机架的数据节点(C)上。datanodeC在其他rack上
HDFS就近读写操作:当本地数据损坏,会先从同机架的相邻数据节点中获取数据,此时的读写速度高于跨机架的。
机架的故障率低于服务器的故障率
当整个机架出现问题,会从其他机架的数据节点中读取数据,保证数据的可用性。
怎么开启机架感知能力?
默认情况下,机架感知能力关闭。集群中的所有服务器都在同一个机架/default-rack
下。此时会忽略服务器的实际物理机架距离,在整个集群中随机读写块,可能会导致大量跨机架的网络通信,致使机架间的流量激增,会造成性能瓶颈。
配置后启动NameNode
core-site.xml
<property><name>net.topology.node.switch.mapping.impl</name><value>org.apache.hadoop.net.TableMapping</value></property><property><name>net.topology.table.file.name</name><value>${env.HADOOP_HOME}/etc/hadoop/rack_topology.data</value></property>
-
net.topology.node.switch.mapping.impl
: 指定使用拓扑映射的Java类 -
net.topology.table.file.name
: 机架信息的文件路径 -
rack_topology.data
:服务器机架映射关系文件内容格式:一个映射关系一行,行的第一个元素是集群服务器IP(DataNode),行的第二个元素是机架名称
192.168.1.1 /rack-1 192.168.1.2 /rack-1 192.168.1.3 /rack-1 192.168.2.1 /rack-2 192.168.2.2 /rack-2 192.168.2.3 /rack-2 192.168.3.1 /rack-3 192.168.3.2 /rack-3 192.168.3.3 /rack-3
输出生效的机架信息
hdfs dfsadmin -printTopology
网络拓扑
代码部分采用hadoop 3.4.1
NetworkTopology
org.apache.hadoop.net.NetworkTopology
该类表示具有树状分层网络拓扑结构的计算机集群。例如,一个集群可能由多个数据中心组成,每个数据中心内都装满计算机机架。在网络拓扑中,叶子节点代表数据节点(DatanodeDescriptor
),非叶子节点(内部节点InnerNode
)则代表交换机/路由器,用于管理进出数据中心或机架的流量。根结点(ROOT)命名为/
。
物理网络拓扑
R1
代表路由器,S1
,S2
,S3
代表交换机。
逻辑机架映射拓扑
计算结点间的距离
返回两个节点之间的距离。假设从某个节点到其父节点的距离为1。两个节点之间的距离通过求和它们到最近共同祖先的距离来计算。
getDistance(Node node1, Node node2)
- 节点相同距离为0
- 若有个节点为NULL,则距离为
Integer.MAX_VALUE
- 若节点之间的层级不同,则每差一层,那么距离+1
- 若节点之间的双亲节点不同,则一直返祖,直到共同双亲节点,每返祖一次,那么距离+2
- 若节点的双亲节点相同,则距离+2
举例
getDistance(D1,D1)=0
getDistance(D1,D2)=2
getDistance(D1,D4)=4
getDistance(D1,D7)=6
寻找最佳DataNode
默认情况下会随机选中集群中的一个节点,然后判断是否是合适的节点。
boolean isGoodDatanode(DatanodeDescriptor node,int maxTargetPerRack, boolean considerLoad,List<DatanodeStorageInfo> results,boolean avoidStaleNodes) {// check if the node is in state 'In Service'// 检查节点管理状态是否正常if (!node.isInService()) {logNodeIsNotChosen(node, NodeNotChosenReason.NOT_IN_SERVICE);return false;}// check if the target is a stale node// 检查节点是否属于汇报过期节点if (avoidStaleNodes) {if (node.isStale(this.staleInterval)) {logNodeIsNotChosen(node, NodeNotChosenReason.NODE_STALE);return false;}}// check the communication traffic of the target machine // 检查节点的负载是否过高if(considerLoad){if(excludeNodeByLoad(node)){return false;}}// check if the target rack has chosen too many nodes// 检查目标机架是否被选择了过多的数据节点String rackname = node.getNetworkLocation();int counter=1;for(DatanodeStorageInfo resultStorage : results) {if (rackname.equals(resultStorage.getDatanodeDescriptor().getNetworkLocation())) {counter++;}}if (counter > maxTargetPerRack) {logNodeIsNotChosen(node, NodeNotChosenReason.TOO_MANY_NODES_ON_RACK);return false;}// check if the target is a slow node// 检查目标是否为慢节点if (dataNodePeerStatsEnabled && excludeSlowNodesEnabled) {Set<String> slowNodesUuidSet = DatanodeManager.getSlowNodesUuidSet();if (slowNodesUuidSet.contains(node.getDatanodeUuid())) {logNodeIsNotChosen(node, NodeNotChosenReason.NODE_SLOW);return false;}}return true;}
官网原文
Rack Awareness
Hadoop components are rack-aware. For example, HDFS block placement will use rack awareness for fault tolerance by placing one block replica on a different rack. This provides data availability in the event of a network switch failure or partition within the cluster.
Hadoop master daemons obtain the rack id of the cluster workers by invoking either an external script or java class as specified by configuration files. Using either the java class or external script for topology, output must adhere to the java org.apache.hadoop.net.DNSToSwitchMapping interface. The interface expects a one-to-one correspondence to be maintained and the topology information in the format of ‘/myrack/myhost’, where ‘/’ is the topology delimiter, ‘myrack’ is the rack identifier, and ‘myhost’ is the individual host. Assuming a single /24 subnet per rack, one could use the format of ‘/192.168.100.0/192.168.100.5’ as a unique rack-host topology mapping.
To use the java class for topology mapping, the class name is specified by the net.topology.node.switch.mapping.impl parameter in the configuration file. An example, NetworkTopology.java, is included with the hadoop distribution and can be customized by the Hadoop administrator. Using a Java class instead of an external script has a performance benefit in that Hadoop doesn’t need to fork an external process when a new worker node registers itself.
If implementing an external script, it will be specified with the net.topology.script.file.name parameter in the configuration files. Unlike the java class, the external topology script is not included with the Hadoop distribution and is provided by the administrator. Hadoop will send multiple IP addresses to ARGV when forking the topology script. The number of IP addresses sent to the topology script is controlled with net.topology.script.number.args and defaults to 100. If net.topology.script.number.args was changed to 1, a topology script would get forked for each IP submitted by DataNodes and/or NodeManagers.
If net.topology.script.file.name or net.topology.node.switch.mapping.impl is not set, the rack id ‘/default-rack’ is returned for any passed IP address. While this behavior appears desirable, it can cause issues with HDFS block replication as default behavior is to write one replicated block off rack and is unable to do so as there is only a single rack named ‘/default-rack’.
Hadoop组件具备机架感知能力。例如,HDFS块放置会利用机架感知机制实现容错,通过将一个块副本放置在不同机架上实现。这确保了在集群内发生网络交换机故障或分区时,数据仍可保持可用性。
Hadoop master 进程通过调用配置文件指定的外部脚本或Java类获取集群workers 的机架ID。无论采用Java类还是外部脚本实现拓扑功能,输出结果必须遵循Java org.apache.hadoop.net.DNSToSwitchMapping 接口规范。该接口要求保持一对一映射关系,拓扑信息格式为‘/myrack/myhost’,其中‘/’为拓扑分隔符,‘myrack’表示机架标识符,‘myhost’表示具体主机。假设每机架仅含一个/24子网,可采用“/192.168.100.0/192.168.100.5”格式实现唯一的机架-主机拓扑映射。
要使用拓扑映射的Java类,需在配置文件中通过net.topology.node.switch.mapping.impl参数指定类名。示例文件 NetworkTopology.java 随 Hadoop 发行版提供,可由 Hadoop 管理员进行定制。相较于外部脚本,使用 Java 类具有性能优势:当新工作节点注册时,Hadoop 无需分叉外部进程。
若需实现外部脚本,需在配置文件中通过net.topology.script.file.name参数进行指定。与Java类不同,外部拓扑脚本不包含在Hadoop发行版中,需由管理员自行提供。Hadoop在分叉拓扑脚本时会向ARGV参数传递多个IP地址。发送至拓扑脚本的IP地址数量由net.topology.script.number.args控制,默认值为100。若将该参数改为1,则每个由DataNode和/或NodeManager提交的IP地址都会触发独立的拓扑脚本进程。
如果未设置 net.topology.script.file.name 或 net.topology.node.switch.mapping.impl,则对任何传入的 IP 地址返回机架 ID ‘/default-rack’。虽然这种行为看似合理,但会导致HDFS块复制出现问题——默认行为是将一个复制块写入机架之外,而由于仅存在名为‘/default-rack’的单一机架,该操作将无法实现。