HDFS 磁盘平衡器

概述

Diskbalancer 是一款命令行工具,可将数据均匀地分布在数据节点的所有磁盘上。此工具不同于 Balancer,后者负责整个集群的数据平衡。由于多种原因,节点上的磁盘之间的数据分布可能不均匀。这可能是由于大量的写入和删除或由于磁盘更换造成的。此工具针对给定的数据节点运行,并将块从一个磁盘移动到另一个磁盘。

架构

磁盘平衡器通过创建计划并继续在数据节点上执行该计划来运行。计划是一组语句,描述了在两个磁盘之间应该移动多少数据。计划由多个移动步骤组成。移动步骤具有源磁盘、目标磁盘和要移动的字节数。计划可以针对操作数据节点执行。磁盘平衡器不应干扰其他进程,因为它会限制每秒复制的数据量。请注意,磁盘平衡器在集群上默认启用。

命令

以下部分讨论磁盘平衡器支持哪些命令以及如何使用这些命令。

计划

可以通过运行以下命令针对给定数据节点运行计划命令

hdfs diskbalancer -plan node1.mycluster.com

该命令接受通用选项

计划命令还具有一组参数,允许用户控制计划的输出和执行。

COMMAND_OPTION 说明
-out 允许用户控制计划文件的输出位置。
-bandwidth 由于数据节点处于操作状态并且可能正在运行其他作业,因此磁盘平衡器会限制每秒移动的数据量。此参数允许用户设置要使用的最大带宽。如果未指定,则不需要设置此参数,因为 diskBalancer 将使用默认带宽。
-thresholdPercentage 由于我们针对数据节点的快照进行操作,因此移动操作具有容差百分比以声明成功。如果用户指定 10%,并且移动操作的大小为 20GB,如果我们可以移动 18GB,则该操作将被视为成功。这是为了适应数据节点的实时变化。如果未指定,则不需要此参数,并且使用默认值。
-maxerror 最大错误允许用户指定在中止移动步骤之前必须失败多少个块复制操作。同样,这不是必需的参数,如果未指定,则使用系统默认值。
-v 详细模式,指定此参数会强制计划命令在 stdout 上打印计划的摘要。
-fs - 指定要使用的名称节点。如果未指定,则使用配置中的默认值。

计划命令写入两个输出文件。它们是 <nodename>.before.json,它捕获运行磁盘平衡器之前集群的状态,以及 <nodename>.plan.json

执行

执行命令采用计划命令,针对生成该计划的数据节点执行该命令。

hdfs diskbalancer -execute /system/diskbalancer/nodename.plan.json

此操作通过从计划文件中读取数据节点的地址来执行计划。当 DiskBalancer 执行该计划时,它是一个可能需要很长时间的异步进程的开始。因此,查询命令有助于获取执行命令的当前状态。

COMMAND_OPTION 说明
-skipDateCheck 跳过日期检查并强制执行计划。

查询

查询命令从数据节点获取 diskbalancer 的当前状态。

hdfs diskbalancer -query nodename.mycluster.com

COMMAND_OPTION 说明
-v 详细模式,打印出各个移动的状态

取消

取消命令取消正在运行的计划。重新启动数据节点与取消命令具有相同的效果,因为数据节点上的计划信息是临时的。

hdfs diskbalancer -cancel /system/diskbalancer/nodename.plan.json

hdfs diskbalancer -cancel planID -node nodename

计划 ID 可以使用查询命令从数据节点读取。

报告

报告命令提供指定节点或将受益于运行磁盘平衡器的顶级节点的详细报告。节点可以通过主机文件或逗号分隔的节点列表指定。

hdfs diskbalancer -fs http://namenode.uri -report -node <file://> | [<DataNodeID|IP|Hostname>,...]

hdfs diskbalancer -fs http://namenode.uri -report -top topnum

设置

有一组 diskbalancer 设置可以通过 hdfs-site.xml 控制

设置 说明
dfs.disk.balancer.enabled 此参数控制是否为集群启用 diskbalancer。如果未启用,数据节点将拒绝任何执行命令。默认值为 true。
dfs.disk.balancer.max.disk.throughputInMBperSec 此参数控制 diskbalancer 在复制数据时消耗的最大磁盘带宽。如果指定了 10MB 之类值,则 diskbalancer 平均只会复制 10MB/S。默认值为 10MB/S。
dfs.disk.balancer.max.disk.errors 设置在放弃两个磁盘之间的特定移动之前我们可以忽略的最大错误数。例如,如果计划有 3 对磁盘需要在它们之间复制,并且第一个磁盘集遇到超过 5 个错误,那么我们将放弃第一个副本并在计划中启动第二个副本。最大错误的默认值设置为 5。
dfs.disk.balancer.block.tolerance.percent 容差百分比指定何时达到任何复制步骤的足够好值。例如,如果您指定 10%,那么接近目标值的 10% 就足够好了。
dfs.disk.balancer.plan.threshold.percent 计划中卷数据密度的百分比阈值。如果节点中卷数据密度的绝对值超出阈值,则表示对应于磁盘的卷应在计划中进行平衡。默认值为 10。
dfs.disk.balancer.plan.valid.interval 磁盘平衡器计划有效的最大时间。支持以下后缀(不区分大小写):ms(毫秒)、s(秒)、m(分钟)、h(小时)、d(天)以指定时间(例如 2s、2m、1h 等)。如果未指定后缀,则假定为毫秒。默认值为 1d

调试

磁盘平衡器生成两个输出文件。nodename.before.json 包含我们从名称节点读取的集群状态。此文件包含有关数据节点和卷的详细信息。

如果您计划将此文件发布到 Apache JIRA,您可能需要替换您的主机名和卷路径,因为它可能会泄露您的个人信息。

您还可以修剪此文件,仅关注您想要在 JIRA 中报告的节点。

nodename.plan.json 包含特定节点的计划。此计划文件包含一系列步骤。步骤在数据节点内作为一系列移动操作执行。

要比较节点之前和之后的差异,您可以重新运行计划命令,并将新的 nodename.before.json 与旧的 before.json 进行比较,或针对节点运行报告命令。

要查看正在运行的计划的进度,请使用 -v 选项运行查询命令。这将打印出一组步骤 - 每个步骤表示从一个磁盘到另一个磁盘的移动操作。

移动速度受指定带宽的限制。带宽的默认值设置为 10MB/秒。如果您使用 -v 选项进行查询,您将看到以下值。

  "sourcePath" : "/data/disk2/hdfs/dn",

  "destPath" : "/data/disk3/hdfs/dn",

  "workItem" :

    "startTime" : 1466575335493,

    "secondsElapsed" : 16486,

    "bytesToCopy" : 181242049353,

    "bytesCopied" : 172655116288,

    "errorCount" : 0,

    "errMsg" : null,

    "blocksCopied" : 1287,

    "maxDiskErrors" : 5,

    "tolerancePercent" : 10,

    "bandwidth" : 10

源路径 - 是我们从中复制的卷。

目标路径 - 是我们复制到的卷。

开始时间 - 是以毫秒为单位的当前时间。

已用秒数 - 是在我们更新统计信息时更新的。这可能比挂钟时间慢。

要复制的字节数 - 是我们应该复制的字节数。我们复制正负一定百分比。因此,您经常会看到 bytesCopied - 作为小于要复制的字节数的值。在默认情况下,达到要移动字节数的 10% 被认为足够好。

已复制的字节数 - 是我们从源磁盘移动到目标磁盘的实际字节数。

错误计数 - 每次遇到错误时,我们将增加错误计数。只要错误计数保持在最大错误计数以下(默认值为 5),我们将尝试完成此移动。如果达到最大错误计数,我们将放弃此当前步骤并执行计划中的下一步。

错误消息 - 当前为报告最后一条错误消息的单个字符串。较旧的消息应在数据节点日志中。

已复制的块 - 已复制的块数。

最大磁盘错误 - 用于此移动步骤的配置。当前它将报告默认配置值,因为用于控制每个步骤的这些值的界面尚未到位。这是未来的工作项目。此值使用计划命令中指定的默认值或命令行值。

容差百分比 - 这表示在移动数据时我们能偏离多少。在繁忙的集群中,这允许管理员说,计算一个计划,但我知道此节点正在使用,所以如果磁盘平衡器可以达到要复制的字节的 +/- 10%,那就可以了。

带宽 - 这是磁盘平衡器使用的最大聚合源磁盘带宽。在移动块后,磁盘平衡器计算出使用指定带宽移动该块应花费多少秒。如果实际移动所花费的时间少于预期,则磁盘平衡器将休眠该持续时间。请注意,当前所有移动都由单个线程按顺序执行。