拓扑
Apache Ozone 使用拓扑信息(例如机架位置)来优化数据访问并提升弹性。一个完全具备机架感知能力的集群需要:
- 配置好的网络拓扑。
- 拓扑感知的数据节点选择,用于容器副本放置(写入路径)。
- 用于对写入流量进行负载均衡的管道选择策略。
- 优先从拓扑距离最近的数据节点读取(读取路径)。
对各容器类型的适用性
Ozone 的拓扑感知策略会因操作不同而有所区别:
- 写入路径(打开状态的容器): 客户端写入数据时,会在管道创建阶段利用拓扑感知,以确保组成该管道的一组数据节点位于不同机架上。这为初始写入提供了容错能力。
- 再复制路径(已关闭的容器): 当需要为某个已关闭的容器创建副本时(由于节点故障、退役或负载均衡),会采用拓扑感知策略为新副本选择最佳数据节点。
有关打开状态与关闭状态容器的更多信息,请参阅关于容器的页面。
配置拓扑层级
Ozone 通过 Hadoop 的机架感知机制来确定数据节点的网络位置(例如机架),该机制在 ozone-site.xml 中通过 net.topology.node.switch.mapping.impl 进行配置。此配置项指定一个 org.apache.hadoop.net.CachedDNSToSwitchMapping 实现。[1]
note
Ozone Manager(OM)与 Storage Container Manager(SCM)都会使用网络拓扑信息。保持集群中所有 OM 和 SCM 实例的拓扑分配一致至关重要。
主要有两种配置方式:
1. 静态列表:TableMapping
这是用于静态映射的非默认实现。它借助一个预定义文件将 IP/主机名映射到机架。如果未指定映射文件,或者某个数据节点在文件中找不到,则会被分配到 /default-rack。
配置: 将
net.topology.node.switch.mapping.impl设置为org.apache.hadoop.net.TableMapping,并将net.topology.table.file.name设置为映射文件的路径。[1]<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>/etc/ozone/topology.map</value> </property>文件格式: 每行两列的文本文件(IP/主机名,机架路径)。[1] 示例
topology.map:192.168.1.100 /rack1 datanode101.example.com /rack1 192.168.1.102 /rack2 datanode103.example.com /rack2
2. 动态列表:ScriptBasedMapping(默认)
这是默认实现。它使用外部脚本来解析 IP 的机架位置。
配置: 将
net.topology.node.switch.mapping.impl设置为org.apache.hadoop.net.ScriptBasedMapping,将net.topology.script.file.name设置为脚本的路径。[1]<property> <name>net.topology.node.switch.mapping.impl</name> <value>org.apache.hadoop.net.ScriptBasedMapping</value> </property> <property> <name>net.topology.script.file.name</name> <value>/etc/ozone/determine_rack.sh</value> </property>脚本: 由管理员提供的可执行脚本。Ozone 会将 IP(最多
net.topology.script.number.args个,默认为 100 个)作为参数传入;脚本输出机架路径(每行一个)。示例determine_rack.sh:#!/bin/bash # This is a simplified example. A real script might query a CMDB or use other logic. while [ $# -gt 0 ] ; do nodeAddress=$1 if [[ "$nodeAddress" == "192.168.1.100" || "$nodeAddress" == "datanode101.example.com" ]]; then echo "/rack1" elif [[ "$nodeAddress" == "192.168.1.102" || "$nodeAddress" == "datanode103.example.com" ]]; then echo "/rack2" else echo "/default-rack" fi shift done
确保脚本具有可执行权限(chmod +x /etc/ozone/determine_rack.sh)。
注意: 在生产环境中,请在脚本中实现健壮的错误处理和输入校验。这应包括处理网络超时、无效输入、CMDB 查询失败以及适当地记录错误日志。上面的示例仅为便于说明而做了简化处理。
拓扑映射最佳实践:
- 准确性: 映射必须准确且保持最新。
- 静态映射: 对于小型、稳定的集群更简单;需要手动更新。
- 动态映映: 适用于大型/动态集群,更加灵活。脚本的性能、正确性和可靠性至关重要;请确保脚本是幂等的,并能高效地处理批量查询。
放置与选择策略
Ozone 使用三种不同类型的策略来管理数据的写入方式和写入位置。
1. Pipeline 创建策略
该策略选择一组 Datanode 来组成新的 Pipeline。其目的是通过将 Pipeline 的节点分散到不同的机架上,确保新 Pipeline 具有内部容错能力,同时在各 Datanode 之间平衡 Pipeline 的数量。这是打开容器在写入路径上实现拓扑感知的主要机制。
该策略通过 ozone-site.xml 中的 ozone.scm.pipeline.placement.impl 属性进行配置。
PipelinePlacementPolicy(默认)- 功能: 这是 Pipeline 创建的默认且唯一受支持的策略。它基于负载均衡(每个节点的 Pipeline 数量)和网络拓扑来选择 Datanode。它会过滤掉参与其他 Pipeline 过多的节点,然后选择节点以确保机架多样性。推荐大多数生产环境使用此策略。
- 使用场景: 在具备机架感知能力的集群中进行通用的 Pipeline 创建。
2. Pipeline 选择(负载均衡)策略
在创建了一组健康、开放且具备机架感知能力的 Pipeline 之后,该策略用于从中选择一个 Pipeline 来处理客户端的写入请求。其目的是负载均衡,而非拓扑感知,因为拓扑问题已在 Pipeline 创建阶段处理完毕。
对于 Ratis 容器,该策略通过 ozone-site.xml 中的 hdds.scm.pipeline.choose.policy.impl 属性进行配置;对于 EC 容器,则通过 hdds.scm.ec.pipeline.choose.policy.impl 属性进行配置。以下所有策略均同时受 Ratis 和 EC 容器支持。
RandomPipelineChoosePolicy(默认): 从可用列表中随机选择一个 Pipeline。该策略简单,在分发负载时不考虑其他指标。CapacityPipelineChoosePolicy: 随机选取两个 Pipeline,并选择利用率较低的一个,倾向于选择具有更多可用容量的 Pipeline。RoundRobinPipelineChoosePolicy: 以轮询方式选择 Pipeline。主要用于调试和测试。HealthyPipelineChoosePolicy: 随机选择 Pipeline,但只返回健康的 Pipeline。
注意:配置这些值时,请包含完整的类名前缀,例如 org.apache.hadoop.hdds.scm.pipeline.choose.algorithms.CapacityPipelineChoosePolicy
3. 已关闭容器的副本放置策略
Ratis 容器
Ratis 容器通过在 ozone-site.xml 中的 ozone.scm.container.placement.impl 属性进行配置。可用策略如下:
SCMContainerPlacementRackAware(默认)- 功能: 将流水线的 Datanode 分布到不同机架上以实现容错(例如,对于 3 节点流水线,会尽量分布在至少两个机架上)。与 HDFS 的放置策略类似。[1]
- 使用场景: 需要机架级容错能力的生产集群。
- 局限性: 面向单层机架拓扑(例如
/rack/node)设计。不建议用于多层层次结构(例如/dc/row/rack/node),因为可能无法正确解析更深层级。[1]
SCMContainerPlacementRandom- 功能: 随机选择健康且可用的 Datanode,忽略机架拓扑。[3]
- 使用场景: 不要求机架容错的小型开发/测试集群。
SCMContainerPlacementCapacity- 功能: 根据可用容量选择 Datanode(优先选择磁盘利用率较低的节点),以均衡整个集群的磁盘使用情况。[4]
- 使用场景: 异构存储集群,或以磁盘均衡利用为关键需求的场景。
注意:配置这些值时,请包含完整的类名前缀,例如 org.apache.hadoop.hdds.scm.container.placement.algorithms.SCMContainerPlacementCapacity
EC 容器
对于纠删码(EC)容器,SCM 采用专门的放置策略,通过将数据块和校验块分布到多个机架上,来确保数据的弹性和可用性。该策略通过 ozone-site.xml 中的 ozone.scm.container.placement.ec.impl.key 属性进行配置。
SCMContainerPlacementRackScatter(默认)- 功能: 这是 EC 容器的默认策略。它会尝试将 EC 容器的每个块(包括数据块和校验块)放置在不同的机架上。例如,对于一个 RS-6-3-1024k 容器(6 个数据块 + 3 个校验块),该策略会尝试将这 9 个块分布到 9 个不同的机架上。这种"分散"方式可最大化容错能力,因为单个机架的故障不会影响该容器中超过一个块。[5]
- 使用场景: 对于使用纠删码以防范机架级故障的生产集群,强烈推荐使用该策略。
- 配置:
<property>
<name>ozone.scm.container.placement.ec.impl.key</name>
<value>org.apache.hadoop.hdds.scm.container.placement.algorithms.SCMContainerPlacementRackScatter</value>
</property>- 行为: 如果可用机架的数量少于 EC 组中的块数,该策略将在同一机架上放置多个块,同时尽量保持分布尽可能均匀。
- 局限性: 与
SCMContainerPlacementRackAware类似,该策略针对单层机架拓扑(例如/rack/node)设计,不建议用于多层层次结构。
优化读取路径
此功能自 Ozone 1.4.0 起默认启用(HDDS-8300),它会引导客户端从拓扑上距离最近的 Datanode 读取副本数据,从而降低延迟并减少跨机架流量。建议在拓扑配置准确的情况下保持启用该功能。
如需禁用此功能,请在 ozone-site.xml 中将 ozone.network.topology.aware.read 设置为 false:
<property>
<name>ozone.network.topology.aware.read</name>
<value>false</value>
</property>最佳实践小结
- 准确的拓扑: 维护一份准确、最新的拓扑映射(静态或动态脚本);这是一切的基础。
- 流水线创建: 在生产环境中,为
ozone.scm.pipeline.placement.impl使用默认的PipelinePlacementPolicy,以同时保证机架容错与流水线负载均衡。 - 流水线选择:
hdds.scm.pipeline.choose.policy.impl的默认RandomPipelineChoosePolicy适用于一般的负载均衡场景。 - 多副本(RATIS)容器: 在生产环境中,请使用
SCMContainerPlacementRackAware(注意其仅支持单层拓扑的限制)或SCMContainerPlacementCapacity(可均衡磁盘使用率),而不是SCMContainerPlacementRandom。 - 纠删码(EC)容器: 为实现生产环境的机架容错,请使用
SCMContainerPlacementRackScatter。 - 读操作: 在拓扑准确的前提下,启用
ozone.network.topology.aware.read。 - 监控与验证: 定期监控数据放置与均衡情况;可使用 Recon 等工具验证拓扑感知是否生效。
参考资料
评论
登录后参与评论
KnowForge