性能

拓扑

师成师成· 更新于 2026-09-28· 阅读 17 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

Apache Ozone 使用拓扑信息(例如机架位置)来优化数据访问并提升弹性。一个完全具备机架感知能力的集群需要:

  1. 配置好的网络拓扑。
  2. 拓扑感知的数据节点选择,用于容器副本放置(写入路径)。
  3. 用于对写入流量进行负载均衡的管道选择策略。
  4. 优先从拓扑距离最近的数据节点读取(读取路径)。

对各容器类型的适用性

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 等工具验证拓扑感知是否生效。

参考资料

  1. Hadoop 文档:机架感知。
  2. Ozone 源码:容器放置策略。(可插拔放置策略的实现。)
  3. Ozone 源码:SCMContainerPlacementRandom.java。
  4. Ozone 源码:SCMContainerPlacementCapacity.java。
  5. Ozone 源码:SCMContainerPlacementRackScatter.java。

评论

登录后参与评论

正在加载评论…